X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=ssl%2Fkssl.c;h=a80f5b2f74dad0019f31da33d79da7885911e1a0;hb=03eeb07152ce9413c017cdef83bd8b5b82bef31d;hp=cd9144f2be041aeecdde61edb68dfe60894ec553;hpb=882e891284c81c7a49b2bce28f44df3e8d6f7ffc;p=openssl.git diff --git a/ssl/kssl.c b/ssl/kssl.c index cd9144f2be..a80f5b2f74 100644 --- a/ssl/kssl.c +++ b/ssl/kssl.c @@ -67,9 +67,10 @@ */ #include -#ifndef OPENSSL_NO_KRB5 + #define _XOPEN_SOURCE /* glibc2 needs this to declare strptime() */ #include +#undef _XOPEN_SOURCE /* To avoid clashes with anything else... */ #include #include @@ -77,6 +78,8 @@ #include #include +#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 @@ -113,16 +116,35 @@ #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 +274,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 +349,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 +739,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 */ @@ -732,30 +784,12 @@ char return ((string == NULL)? null: string); } -#define MAXKNUM 255 -char -*knumber(int len, krb5_octet *contents) - { - static char buf[MAXKNUM+1]; - int i; - - BIO_snprintf(buf, MAXKNUM, "[%d] ", len); - - for (i=0; i < len && MAXKNUM > strlen(buf)+3; i++) - { - BIO_snprintf(&buf[strlen(buf)], 3, "%02x", contents[i]); - } - - return (buf); - } - - /* Given KRB5 enctype (basically DES or 3DES), ** return closest match openssl EVP_ encryption algorithm. ** 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) @@ -765,14 +799,14 @@ kssl_map_enc(krb5_enctype enctype) 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; } } @@ -818,7 +852,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; @@ -858,8 +892,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; @@ -894,7 +929,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++) @@ -939,7 +974,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) { @@ -971,8 +1006,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; @@ -1107,7 +1141,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) { @@ -1116,9 +1150,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); } } @@ -1182,8 +1216,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"); @@ -1199,14 +1232,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, @@ -1377,7 +1410,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) { @@ -1518,7 +1551,7 @@ kssl_ctx_free(KSSL_CTX *kssl_ctx) { if (kssl_ctx == NULL) return kssl_ctx; - if (kssl_ctx->key) memset(kssl_ctx->key, 0, + if (kssl_ctx->key) OPENSSL_cleanse(kssl_ctx->key, kssl_ctx->length); if (kssl_ctx->key) free(kssl_ctx->key); if (kssl_ctx->client_princ) free(kssl_ctx->client_princ); @@ -1558,10 +1591,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'; } } @@ -1620,7 +1655,7 @@ kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session) if (kssl_ctx->key) { - memset(kssl_ctx->key, 0, kssl_ctx->length); + OPENSSL_cleanse(kssl_ctx->key, kssl_ctx->length); free(kssl_ctx->key); } @@ -1825,15 +1860,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 *)>ime->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; @@ -1924,13 +1959,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; + int 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, ""); @@ -1963,7 +1999,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) { @@ -1984,7 +2020,7 @@ krb5_error_code kssl_check_authent( } #endif enc = kssl_map_enc(enctype); - memset(iv, 0, EVP_MAX_IV_LENGTH); /* per RFC 1510 */ + memset(iv, 0, sizeof iv); /* per RFC 1510 */ if (enc == NULL) { @@ -1994,44 +2030,23 @@ krb5_error_code kssl_check_authent( */ goto err; } - if (!EVP_DecryptInit(&ciph_ctx, enc, kssl_ctx->key, iv)) - { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "EVP_DecryptInit error decrypting authenticator.\n"); - krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; - goto err; - } - if (!EVP_DecryptUpdate(&ciph_ctx, unenc_authent, &outl, - dec_authent->cipher->data, dec_authent->cipher->length)) - { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "EVP_DecryptUpdate error decrypting authenticator.\n"); - krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; - goto err; - } - if (outl > unencbufsize) - { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "Buffer overflow decrypting authenticator.\n"); - krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; - goto err; - } - if (!EVP_DecryptFinal(&ciph_ctx, &(unenc_authent[outl]), &padl)) - { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "EVP_DecryptFinal error decrypting authenticator.\n"); - krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; - goto err; - } - outl += padl; - if (outl > unencbufsize) - { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "Buffer overflow decrypting authenticator.\n"); - krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; - goto err; - } - EVP_CIPHER_CTX_cleanup(&ciph_ctx); + + if (!EVP_CipherInit(&ciph_ctx,enc,kssl_ctx->key,iv,0)) + { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "EVP_CipherInit error decrypting authenticator.\n"); + krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; + goto err; + } + outl = dec_authent->cipher->length; + if (!EVP_Cipher(&ciph_ctx,unenc_authent,dec_authent->cipher->data,outl)) + { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "EVP_Cipher error decrypting authenticator.\n"); + krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; + goto err; + } + EVP_CIPHER_CTX_cleanup(&ciph_ctx); #ifdef KSSL_DEBUG printf("kssl_check_authent: decrypted authenticator[%d] =\n", outl); @@ -2080,6 +2095,7 @@ krb5_error_code kssl_check_authent( if (auth) KRB5_AUTHENT_free((KRB5_AUTHENT *) auth); if (dec_authent) KRB5_ENCDATA_free(dec_authent); if (unenc_authent) free(unenc_authent); + EVP_CIPHER_CTX_cleanup(&ciph_ctx); return krb5rc; }