xref: /freebsd/crypto/krb5/src/lib/krb5/krb/padata.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
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