Correct darwin shared library support.
[openssl.git] / ssl / kssl.c
index d9e1160550c7919dd778b7060465106a6b689841..d3c7be7581fb5bbd702fde5070434d47a7b9e223 100644 (file)
@@ -67,7 +67,7 @@
 */
 
 #include <openssl/opensslconf.h>
-#ifndef OPENSSL_NO_KRB5
+
 #define _XOPEN_SOURCE /* glibc2 needs this to declare strptime() */
 #include <time.h>
 #include <string.h>
@@ -77,6 +77,8 @@
 #include <openssl/objects.h>
 #include <openssl/krb5_asn.h>
 
+#ifndef OPENSSL_NO_KRB5
+
 /* 
  * When OpenSSL is built on Windows, we do not want to require that
  * the Kerberos DLLs be available in order for the OpenSSL DLLs to
 #define krb5_rd_req              kssl_krb5_rd_req               
 #define krb5_kt_default          kssl_krb5_kt_default           
 #define krb5_kt_resolve          kssl_krb5_kt_resolve           
+/* macros in mit 1.2.2 and earlier; functions in mit 1.2.3 and greater */
+#ifndef krb5_kt_close
+#define krb5_kt_close            kssl_krb5_kt_close
+#endif /* krb5_kt_close */
+#ifndef krb5_kt_get_entry
+#define krb5_kt_get_entry        kssl_krb5_kt_get_entry
+#endif /* krb5_kt_get_entry */
 #define krb5_auth_con_init       kssl_krb5_auth_con_init        
 
 #define krb5_principal_compare   kssl_krb5_principal_compare
-/* macro  #define krb5_kt_get_entry        kssl_krb5_kt_get_entry  */
 #define krb5_decrypt_tkt_part    kssl_krb5_decrypt_tkt_part
 #define krb5_timeofday           kssl_krb5_timeofday
 #define krb5_rc_default           kssl_krb5_rc_default
+
+#ifdef krb5_rc_initialize
+#undef krb5_rc_initialize
+#endif
 #define krb5_rc_initialize   kssl_krb5_rc_initialize
+
+#ifdef krb5_rc_get_lifespan
+#undef krb5_rc_get_lifespan
+#endif
 #define krb5_rc_get_lifespan kssl_krb5_rc_get_lifespan
+
+#ifdef krb5_rc_destroy
+#undef krb5_rc_destroy
+#endif
 #define krb5_rc_destroy      kssl_krb5_rc_destroy
+
 #define valid_cksumtype      kssl_valid_cksumtype
 #define krb5_checksum_size   kssl_krb5_checksum_size
 #define krb5_kt_free_entry   kssl_krb5_kt_free_entry
@@ -252,6 +273,12 @@ static krb5_error_code (_stdcall * p_krb5_get_server_rcache)(krb5_context,
 static krb5_error_code (* p_krb5_auth_con_getrcache)(krb5_context, 
                                                       krb5_auth_context,
                                                       krb5_rcache *)=NULL;
+static krb5_error_code (_stdcall * p_krb5_kt_close)(krb5_context context, 
+                                                    krb5_keytab keytab)=NULL;
+static krb5_error_code (_stdcall * p_krb5_kt_get_entry)(krb5_context context, 
+                                                        krb5_keytab keytab,
+                       krb5_const_principal principal, krb5_kvno vno,
+                       krb5_enctype enctype, krb5_keytab_entry *entry)=NULL;
 static int krb5_loaded = 0;     /* only attempt to initialize func ptrs once */
 
 /* Function to Load the Kerberos 5 DLL and initialize function pointers */
@@ -321,6 +348,10 @@ load_krb5_dll(void)
                 GetProcAddress( hKRB5_32, "krb5_get_server_rcache" );
         (FARPROC) p_krb5_auth_con_getrcache =
                 GetProcAddress( hKRB5_32, "krb5_auth_con_getrcache" );
+        (FARPROC) p_krb5_kt_close =
+                GetProcAddress( hKRB5_32, "krb5_kt_close" );
+        (FARPROC) p_krb5_kt_get_entry =
+                GetProcAddress( hKRB5_32, "krb5_kt_get_entry" );
        }
 
 /* Stubs for each function to be dynamicly loaded */
@@ -707,20 +738,40 @@ krb5_error_code
 kssl_krb5_get_server_rcache(krb5_context con, krb5_const krb5_data * data,
                             krb5_rcache * rcache) 
         {
-                 if ( p_krb5_get_server_rcache )
-                         return(p_krb5_get_server_rcache(con,data,rcache));
-                 else
-                         return KRB5KRB_ERR_GENERIC;
+       if ( p_krb5_get_server_rcache )
+               return(p_krb5_get_server_rcache(con,data,rcache));
+       else
+               return KRB5KRB_ERR_GENERIC;
         }
 
 krb5_error_code
 kssl_krb5_auth_con_getrcache(krb5_context con, krb5_auth_context acon,
                              krb5_rcache * prcache)
         {
-                 if ( p_krb5_auth_con_getrcache )
-                         return(p_krb5_auth_con_getrcache(con,acon, prcache));
-                 else
-                         return KRB5KRB_ERR_GENERIC;
+       if ( p_krb5_auth_con_getrcache )
+               return(p_krb5_auth_con_getrcache(con,acon, prcache));
+       else
+               return KRB5KRB_ERR_GENERIC;
+       }
+krb5_error_code
+kssl_krb5_kt_close(krb5_context context, krb5_keytab keytab)
+       {
+       if ( p_krb5_kt_close )
+               return(p_krb5_kt_close(context,keytab));
+       else 
+               return KRB5KRB_ERR_GENERIC;
+       }
+
+krb5_error_code
+kssl_krb5_kt_get_entry(krb5_context context, krb5_keytab keytab,
+                       krb5_const_principal principal, krb5_kvno vno,
+                       krb5_enctype enctype, krb5_keytab_entry *entry)
+       {
+       if ( p_krb5_kt_get_entry )
+               return(p_krb5_kt_get_entry(context,keytab,principal,vno,enctype,entry));
+       else
+               return KRB5KRB_ERR_GENERIC;
         }
 #endif  /* OPENSSL_SYS_WINDOWS || OPENSSL_SYS_WIN32 */
 
@@ -755,29 +806,24 @@ char
 **     Return NULL for unknown or problematic (krb5_dk_encrypt) enctypes.
 **     Assume ENCTYPE_*_RAW (krb5_raw_encrypt) are OK.
 */
-EVP_CIPHER *
+const EVP_CIPHER *
 kssl_map_enc(krb5_enctype enctype)
         {
        switch (enctype)
                {
-#if ! defined(KRB5_MIT_OLD11)
-                                       /*     cannot handle derived keys  */
-       case ENCTYPE_DES3_CBC_SHA1:             /*    EVP_des_ede3_cbc();  */
        case ENCTYPE_DES_HMAC_SHA1:             /*    EVP_des_cbc();       */
-                               return (EVP_CIPHER *) NULL;
-                               break;
-#endif
        case ENCTYPE_DES_CBC_CRC:
        case ENCTYPE_DES_CBC_MD4:
        case ENCTYPE_DES_CBC_MD5:
        case ENCTYPE_DES_CBC_RAW:
-                               return (EVP_CIPHER *) EVP_des_cbc();
+                               return EVP_des_cbc();
                                break;
+       case ENCTYPE_DES3_CBC_SHA1:             /*    EVP_des_ede3_cbc();  */
        case ENCTYPE_DES3_CBC_SHA:
        case ENCTYPE_DES3_CBC_RAW:
-                               return (EVP_CIPHER *) EVP_des_ede3_cbc();
+                               return EVP_des_ede3_cbc();
                                break;
-       default:                return (EVP_CIPHER *) NULL;
+       default:                return NULL;
                                break;
                }
        }
@@ -823,7 +869,7 @@ int         kssl_test_confound(unsigned char *p)
 **      what the highest assigned CKSUMTYPE_ constant is.  As of 1.2.2
 **      it is 0x000c (CKSUMTYPE_HMAC_SHA1_DES3).  So we will use 0x0010.
 */
-int    *populate_cksumlens(void)
+size_t  *populate_cksumlens(void)
        {
        int             i, j, n;
        static size_t   *cklens = NULL;
@@ -863,8 +909,9 @@ int         *populate_cksumlens(void)
 */
 unsigned char  *kssl_skip_confound(krb5_enctype etype, unsigned char *a)
        {
-       int             i, cklen, conlen;
-       static int      *cksumlens = NULL;
+       int             i, conlen;
+       size_t          cklen;
+       static size_t   *cksumlens = NULL;
        unsigned char   *test_auth;
 
        conlen = (etype)? 8: 0;
@@ -899,7 +946,7 @@ kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text)
 void
 print_krb5_data(char *label, krb5_data *kdata)
         {
-       unsigned int    i;
+       int i;
 
        printf("%s[%d] ", label, kdata->length);
        for (i=0; i < kdata->length; i++)
@@ -944,7 +991,7 @@ print_krb5_authdata(char *label, krb5_authdata **adata)
 void
 print_krb5_keyblock(char *label, krb5_keyblock *keyblk)
         {
-       unsigned int    i;
+       int i;
 
        if (keyblk == NULL)
                 {
@@ -976,8 +1023,7 @@ print_krb5_keyblock(char *label, krb5_keyblock *keyblk)
 void
 print_krb5_princ(char *label, krb5_principal_data *princ)
         {
-       unsigned int    ui, uj;
-        int i;
+       int i, ui, uj;
 
        printf("%s principal Realm: ", label);
        if (princ == NULL)  return;
@@ -1112,7 +1158,7 @@ kssl_cget_tkt(    /* UPDATE */    KSSL_CTX *kssl_ctx,
                        }
 
                arlen = krb5_app_req.length;
-               p = krb5_app_req.data;
+               p = (unsigned char *)krb5_app_req.data;
                ap_req = (KRB5_APREQBODY *) d2i_KRB5_APREQ(NULL, &p, arlen);
                if (ap_req)
                        {
@@ -1121,9 +1167,9 @@ kssl_cget_tkt(    /* UPDATE */    KSSL_CTX *kssl_ctx,
                        if (authenp->length  && 
                                (authenp->data = malloc(authenp->length)))
                                {
-                               unsigned char   *p = authenp->data;
+                               unsigned char   *adp = (unsigned char *)authenp->data;
                                authenp->length = i2d_KRB5_ENCDATA(
-                                               ap_req->authenticator, &p);
+                                               ap_req->authenticator, &adp);
                                }
                        }
 
@@ -1187,8 +1233,7 @@ kssl_TKT2tkt(     /* IN     */    krb5_context    krb5context,
 
        if (asn1ticket == NULL  ||  asn1ticket->realm == NULL  ||
                asn1ticket->sname == NULL  || 
-               asn1ticket->sname->namestring == NULL  ||
-               asn1ticket->sname->namestring->num < 2)
+               sk_ASN1_GENERALSTRING_num(asn1ticket->sname->namestring) < 2)
                {
                BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
                        "Null field in asn1ticket.\n");
@@ -1204,14 +1249,14 @@ kssl_TKT2tkt(   /* IN     */    krb5_context    krb5context,
                return ENOMEM;          /*  or  KRB5KRB_ERR_GENERIC;    */
                }
 
-       gstr_svc  = (ASN1_GENERALSTRING*)asn1ticket->sname->namestring->data[0];
-       gstr_host = (ASN1_GENERALSTRING*)asn1ticket->sname->namestring->data[1];
+       gstr_svc  = sk_ASN1_GENERALSTRING_value(asn1ticket->sname->namestring, 0);
+       gstr_host = sk_ASN1_GENERALSTRING_value(asn1ticket->sname->namestring, 1);
 
        if ((krb5rc = kssl_build_principal_2(krb5context,
                        &new5ticket->server,
-                       asn1ticket->realm->length, asn1ticket->realm->data,
-                       gstr_svc->length,  gstr_svc->data,
-                       gstr_host->length, gstr_host->data)) != 0)
+                       asn1ticket->realm->length, (char *)asn1ticket->realm->data,
+                       gstr_svc->length,  (char *)gstr_svc->data,
+                       gstr_host->length, (char *)gstr_host->data)) != 0)
                {
                free(new5ticket);
                BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
@@ -1382,7 +1427,7 @@ kssl_sget_tkt(    /* UPDATE */    KSSL_CTX                *kssl_ctx,
        **                      &ap_option, &krb5ticket)) != 0)  { Error }
        */
 
-       p = indata->data;
+       p = (unsigned char *)indata->data;
        if ((asn1ticket = (KRB5_TKTBODY *) d2i_KRB5_TICKET(NULL, &p,
                                                (long) indata->length)) == NULL)
                {
@@ -1563,10 +1608,12 @@ kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which,
        else
                 {
                strncpy(*princ, entity->data, entity->length);
+               (*princ)[entity->length]='\0';
                if (realm)
                         {
                        strcat (*princ, "@");
                        (void) strncat(*princ, realm->data, realm->length);
+                       (*princ)[entity->length+1+realm->length]='\0';
                        }
                }
 
@@ -1830,15 +1877,15 @@ void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data)
 **  Return pointer to the (partially) filled in struct tm on success,
 **  return NULL on failure.
 */
-struct tm      *k_gmtime(ASN1_GENERALIZEDTIME *ctime, struct tm *k_tm)
+struct tm      *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm)
        {
        char            c, *p;
 
        if (!k_tm)  return NULL;
-       if (ctime == NULL  ||  ctime->length < 14)  return NULL;
-       if (ctime->data == NULL)  return NULL;
+       if (gtime == NULL  ||  gtime->length < 14)  return NULL;
+       if (gtime->data == NULL)  return NULL;
 
-       p = &ctime->data[14];
+       p = (char *)&gtime->data[14];
 
        c = *p;  *p = '\0';  p -= 2;  k_tm->tm_sec  = atoi(p);      *(p+2) = c;
        c = *p;  *p = '\0';  p -= 2;  k_tm->tm_min  = atoi(p);      *(p+2) = c;
@@ -1929,13 +1976,14 @@ krb5_error_code  kssl_check_authent(
        KRB5_AUTHENTBODY        *auth = NULL;
        krb5_enctype            enctype;
        EVP_CIPHER_CTX          ciph_ctx;
-       EVP_CIPHER              *enc = NULL;
+       const EVP_CIPHER        *enc = NULL;
        unsigned char           iv[EVP_MAX_IV_LENGTH];
        unsigned char           *p, *unenc_authent;
        int                     padl, outl, unencbufsize;
        struct tm               tm_time, *tm_l, *tm_g;
        time_t                  now, tl, tg, tr, tz_offset;
 
+       EVP_CIPHER_CTX_init(&ciph_ctx);
        *atimep = 0;
        kssl_err_set(kssl_err, 0, "");
 
@@ -1968,7 +2016,7 @@ krb5_error_code  kssl_check_authent(
                goto err;
                }
 
-       p = authentp->data;
+       p = (unsigned char *)authentp->data;
        if ((dec_authent = d2i_KRB5_ENCDATA(NULL, &p,
                                        (long) authentp->length)) == NULL) 
                {
@@ -1979,6 +2027,15 @@ krb5_error_code  kssl_check_authent(
                }
 
        enctype = dec_authent->etype->data[0];  /* should = kssl_ctx->enctype */
+#if !defined(KRB5_MIT_OLD11)
+            switch ( enctype ) {
+            case ENCTYPE_DES3_CBC_SHA1:                /*    EVP_des_ede3_cbc();  */
+            case ENCTYPE_DES3_CBC_SHA:
+            case ENCTYPE_DES3_CBC_RAW:
+                krb5rc = 0;                     /* Skip, can't handle derived keys */
+                goto err;
+            }
+#endif
        enc = kssl_map_enc(enctype);
        memset(iv, 0, EVP_MAX_IV_LENGTH);       /* per RFC 1510 */
 
@@ -1990,10 +2047,10 @@ krb5_error_code  kssl_check_authent(
                */
                goto err;
                }
-       if (!EVP_DecryptInit(&ciph_ctx, enc, kssl_ctx->key, iv))
+       if (!EVP_DecryptInit_ex(&ciph_ctx, enc, NULL, kssl_ctx->key, iv))
                {
                kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
-                       "EVP_DecryptInit error decrypting authenticator.\n");
+                       "EVP_DecryptInit_ex error decrypting authenticator.\n");
                krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY;
                goto err;
                }
@@ -2012,10 +2069,10 @@ krb5_error_code  kssl_check_authent(
                krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY;
                goto err;
                }
-       if (!EVP_DecryptFinal(&ciph_ctx, &(unenc_authent[outl]), &padl))
+       if (!EVP_DecryptFinal_ex(&ciph_ctx, &(unenc_authent[outl]), &padl))
                {
                kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
-                       "EVP_DecryptFinal error decrypting authenticator.\n");
+                       "EVP_DecryptFinal_ex error decrypting authenticator.\n");
                krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY;
                goto err;
                }