1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/krb5/krb/padata.c - utility functions for krb5_pa_data lists */
3 /*
4 * Copyright (C) 2019 by the Massachusetts Institute of Technology.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30 * OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include "k5-int.h"
34
35 krb5_pa_data *
krb5int_find_pa_data(krb5_context context,krb5_pa_data * const * pa_list,krb5_preauthtype pa_type)36 krb5int_find_pa_data(krb5_context context, krb5_pa_data *const *pa_list,
37 krb5_preauthtype pa_type)
38 {
39 krb5_pa_data *const *pa;
40
41 for (pa = pa_list; pa != NULL && *pa != NULL; pa++) {
42 if ((*pa)->pa_type == pa_type)
43 return *pa;
44 }
45 return NULL;
46 }
47
48 krb5_error_code
k5_alloc_pa_data(krb5_preauthtype pa_type,size_t len,krb5_pa_data ** out)49 k5_alloc_pa_data(krb5_preauthtype pa_type, size_t len, krb5_pa_data **out)
50 {
51 krb5_pa_data *pa;
52 uint8_t *buf = NULL;
53
54 *out = NULL;
55 if (len > 0) {
56 buf = malloc(len);
57 if (buf == NULL)
58 return ENOMEM;
59 }
60 pa = malloc(sizeof(*pa));
61 if (pa == NULL) {
62 free(buf);
63 return ENOMEM;
64 }
65 pa->magic = KV5M_PA_DATA;
66 pa->pa_type = pa_type;
67 pa->length = len;
68 pa->contents = buf;
69 *out = pa;
70 return 0;
71 }
72
73 void
k5_free_pa_data_element(krb5_pa_data * pa)74 k5_free_pa_data_element(krb5_pa_data *pa)
75 {
76 if (pa != NULL) {
77 free(pa->contents);
78 free(pa);
79 }
80 }
81
82 krb5_error_code
k5_add_pa_data_element(krb5_pa_data *** list,krb5_pa_data ** pa)83 k5_add_pa_data_element(krb5_pa_data ***list, krb5_pa_data **pa)
84 {
85 size_t count;
86 krb5_pa_data **newlist;
87
88 for (count = 0; *list != NULL && (*list)[count] != NULL; count++);
89
90 newlist = realloc(*list, (count + 2) * sizeof(*newlist));
91 if (newlist == NULL)
92 return ENOMEM;
93 newlist[count] = *pa;
94 newlist[count + 1] = NULL;
95 *pa = NULL;
96 *list = newlist;
97 return 0;
98 }
99
100 krb5_error_code
k5_add_pa_data_from_data(krb5_pa_data *** list,krb5_preauthtype pa_type,krb5_data * data)101 k5_add_pa_data_from_data(krb5_pa_data ***list, krb5_preauthtype pa_type,
102 krb5_data *data)
103 {
104 krb5_error_code ret;
105 krb5_pa_data *pa;
106
107 ret = k5_alloc_pa_data(pa_type, 0, &pa);
108 if (ret)
109 return ret;
110 pa->contents = (uint8_t *)data->data;
111 pa->length = data->length;
112 ret = k5_add_pa_data_element(list, &pa);
113 if (ret) {
114 free(pa);
115 return ret;
116 }
117 *data = empty_data();
118 return 0;
119 }
120
121 krb5_error_code
k5_add_empty_pa_data(krb5_pa_data *** list,krb5_preauthtype pa_type)122 k5_add_empty_pa_data(krb5_pa_data ***list, krb5_preauthtype pa_type)
123 {
124 krb5_data empty = empty_data();
125
126 return k5_add_pa_data_from_data(list, pa_type, &empty);
127 }
128