static krb5_error_code get_pa_etype_info2(krb5_context context, krb5_kdc_configuration *config, METHOD_DATA *md, Key *ckey) { krb5_error_code ret = 0; ETYPE_INFO2 pa; unsigned char *buf; size_t len; pa.len = 1; pa.val = calloc(1, sizeof(pa.val[0])); if(pa.val == NULL) return ENOMEM; ret = make_etype_info2_entry(&pa.val[0], ckey); if (ret) { free_ETYPE_INFO2(&pa); return ret; } ASN1_MALLOC_ENCODE(ETYPE_INFO2, buf, len, &pa, &len, ret); free_ETYPE_INFO2(&pa); if(ret) return ret; ret = realloc_method_data(md); if(ret) { free(buf); return ret; } md->val[md->len - 1].padata_type = KRB5_PADATA_ETYPE_INFO2; md->val[md->len - 1].padata_value.length = len; md->val[md->len - 1].padata_value.data = buf; return 0; }
static krb5_error_code get_pa_etype_info2(krb5_context context, krb5_kdc_configuration *config, METHOD_DATA *md, hdb_entry *client, ENCTYPE *etypes, unsigned int etypes_len) { krb5_error_code ret = 0; int i, j; unsigned int n = 0; ETYPE_INFO2 pa; unsigned char *buf; size_t len; pa.len = client->keys.len; if(pa.len > UINT_MAX/sizeof(*pa.val)) return ERANGE; pa.val = malloc(pa.len * sizeof(*pa.val)); if(pa.val == NULL) return ENOMEM; memset(pa.val, 0, pa.len * sizeof(*pa.val)); for(i = 0; i < client->keys.len; i++) { for (j = 0; j < n; j++) if (pa.val[j].etype == client->keys.val[i].key.keytype) goto skip1; for(j = 0; j < etypes_len; j++) { if(client->keys.val[i].key.keytype == etypes[j]) { if (krb5_enctype_valid(context, etypes[j]) != 0) continue; if (n >= pa.len) krb5_abortx(context, "internal error: n >= p.len"); if((ret = make_etype_info2_entry(&pa.val[n++], &client->keys.val[i])) != 0) { free_ETYPE_INFO2(&pa); return ret; } break; } } skip1:; } /* send enctypes that the client doesn't know about too */ for(i = 0; i < client->keys.len; i++) { /* already added? */ for(j = 0; j < etypes_len; j++) { if(client->keys.val[i].key.keytype == etypes[j]) goto skip2; } if (krb5_enctype_valid(context, client->keys.val[i].key.keytype) != 0) continue; if (n >= pa.len) krb5_abortx(context, "internal error: n >= p.len"); if((ret = make_etype_info2_entry(&pa.val[n++], &client->keys.val[i])) != 0) { free_ETYPE_INFO2(&pa); return ret; } skip2:; } if(n < pa.len) { /* stripped out dups, and not valid enctypes */ pa.len = n; } ASN1_MALLOC_ENCODE(ETYPE_INFO2, buf, len, &pa, &len, ret); free_ETYPE_INFO2(&pa); if(ret) return ret; ret = realloc_method_data(md); if(ret) { free(buf); return ret; } md->val[md->len - 1].padata_type = KRB5_PADATA_ETYPE_INFO2; md->val[md->len - 1].padata_value.length = len; md->val[md->len - 1].padata_value.data = buf; return 0; }