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 struct pa_info_data * pa_etype_info2(krb5_context context, const krb5_principal client, const AS_REQ *asreq, struct pa_info_data *paid, heim_octet_string *data) { krb5_error_code ret; ETYPE_INFO2 e; size_t sz; int i, j; memset(&e, 0, sizeof(e)); ret = decode_ETYPE_INFO2(data->data, data->length, &e, &sz); if (ret) goto out; if (e.len == 0) goto out; for (j = 0; j < asreq->req_body.etype.len; j++) { for (i = 0; i < e.len; i++) { if (asreq->req_body.etype.val[j] == e.val[i].etype) { krb5_salt salt; if (e.val[i].salt == NULL) ret = krb5_get_pw_salt(context, client, &salt); else { salt.saltvalue.data = *e.val[i].salt; salt.saltvalue.length = strlen(*e.val[i].salt); ret = 0; } if (ret == 0) ret = set_paid(paid, context, e.val[i].etype, KRB5_PW_SALT, salt.saltvalue.data, salt.saltvalue.length, e.val[i].s2kparams); if (e.val[i].salt == NULL) krb5_free_salt(context, salt); if (ret == 0) { free_ETYPE_INFO2(&e); return paid; } } } } out: free_ETYPE_INFO2(&e); return NULL; }
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; }