xref: /freebsd/crypto/krb5/src/plugins/preauth/pkinit/pkinit_lib.c (revision ee3960cba1068e12fb032a68c46d74841d9edab3)
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  * COPYRIGHT (C) 2006,2007
4  * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
5  * ALL RIGHTS RESERVED
6  *
7  * Permission is granted to use, copy, create derivative works
8  * and redistribute this software and such derivative works
9  * for any purpose, so long as the name of The University of
10  * Michigan is not used in any advertising or publicity
11  * pertaining to the use of distribution of this software
12  * without specific, written prior authorization.  If the
13  * above copyright notice or any other identification of the
14  * University of Michigan is included in any copy of any
15  * portion of this software, then the disclaimer below must
16  * also be included.
17  *
18  * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
19  * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
20  * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
21  * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
22  * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
23  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
24  * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
25  * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
26  * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
27  * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
28  * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGES.
30  */
31 
32 #include "pkinit.h"
33 
34 #define FAKECERT
35 
36 const krb5_data dh_oid = { 0, 7, "\x2A\x86\x48\xce\x3e\x02\x01" };
37 
38 
39 krb5_error_code
40 pkinit_init_req_opts(pkinit_req_opts **reqopts)
41 {
42     krb5_error_code retval = ENOMEM;
43     pkinit_req_opts *opts = NULL;
44 
45     *reqopts = NULL;
46     opts = calloc(1, sizeof(*opts));
47     if (opts == NULL)
48         return retval;
49 
50     opts->require_eku = 1;
51     opts->accept_secondary_eku = 0;
52     opts->allow_upn = 0;
53     opts->dh_or_rsa = DH_PROTOCOL;
54     opts->require_crl_checking = 0;
55     opts->dh_size = PKINIT_DEFAULT_DH_MIN_BITS;
56 
57     *reqopts = opts;
58 
59     return 0;
60 }
61 
62 void
63 pkinit_fini_req_opts(pkinit_req_opts *opts)
64 {
65     free(opts);
66     return;
67 }
68 
69 krb5_error_code
70 pkinit_init_plg_opts(pkinit_plg_opts **plgopts)
71 {
72     krb5_error_code retval = ENOMEM;
73     pkinit_plg_opts *opts = NULL;
74 
75     *plgopts = NULL;
76     opts = calloc(1, sizeof(pkinit_plg_opts));
77     if (opts == NULL)
78         return retval;
79 
80     opts->require_eku = 1;
81     opts->accept_secondary_eku = 0;
82     opts->dh_or_rsa = DH_PROTOCOL;
83     opts->allow_upn = 0;
84     opts->require_crl_checking = 0;
85     opts->require_freshness = 0;
86     opts->disable_freshness = 0;
87 
88     opts->dh_min_bits = PKINIT_DEFAULT_DH_MIN_BITS;
89 
90     *plgopts = opts;
91 
92     return 0;
93 }
94 
95 void
96 pkinit_fini_plg_opts(pkinit_plg_opts *opts)
97 {
98     free(opts);
99     return;
100 }
101 
102 void
103 free_krb5_pa_pk_as_req(krb5_pa_pk_as_req **in)
104 {
105     if (*in == NULL) return;
106     free((*in)->signedAuthPack.data);
107     if ((*in)->trustedCertifiers != NULL)
108         free_krb5_external_principal_identifier(&(*in)->trustedCertifiers);
109     free((*in)->kdcPkId.data);
110     free(*in);
111 }
112 
113 void
114 free_krb5_reply_key_pack(krb5_reply_key_pack **in)
115 {
116     if (*in == NULL) return;
117     free((*in)->replyKey.contents);
118     free((*in)->asChecksum.contents);
119     free(*in);
120 }
121 
122 void
123 free_krb5_auth_pack(krb5_auth_pack **in)
124 {
125     if ((*in) == NULL) return;
126     krb5_free_data_contents(NULL, &(*in)->clientPublicValue);
127     free((*in)->pkAuthenticator.paChecksum.contents);
128     krb5_free_data(NULL, (*in)->pkAuthenticator.freshnessToken);
129     if ((*in)->supportedCMSTypes != NULL)
130         free_krb5_algorithm_identifiers(&((*in)->supportedCMSTypes));
131     if ((*in)->supportedKDFs) {
132         krb5_data **supportedKDFs = (*in)->supportedKDFs;
133         unsigned i;
134         for (i = 0; supportedKDFs[i]; i++)
135             krb5_free_data(NULL, supportedKDFs[i]);
136         free(supportedKDFs);
137     }
138     free(*in);
139 }
140 
141 void
142 free_krb5_pa_pk_as_rep(krb5_pa_pk_as_rep **in)
143 {
144     if (*in == NULL) return;
145     switch ((*in)->choice) {
146     case choice_pa_pk_as_rep_dhInfo:
147         krb5_free_data(NULL, (*in)->u.dh_Info.kdfID);
148         free((*in)->u.dh_Info.dhSignedData.data);
149         break;
150     case choice_pa_pk_as_rep_encKeyPack:
151         free((*in)->u.encKeyPack.data);
152         break;
153     default:
154         break;
155     }
156     free(*in);
157 }
158 
159 void
160 free_krb5_external_principal_identifier(krb5_external_principal_identifier ***in)
161 {
162     int i = 0;
163     if (*in == NULL) return;
164     while ((*in)[i] != NULL) {
165         free((*in)[i]->subjectName.data);
166         free((*in)[i]->issuerAndSerialNumber.data);
167         free((*in)[i]->subjectKeyIdentifier.data);
168         free((*in)[i]);
169         i++;
170     }
171     free(*in);
172 }
173 
174 void
175 free_krb5_algorithm_identifier(krb5_algorithm_identifier *in)
176 {
177     if (in == NULL)
178         return;
179     free(in->algorithm.data);
180     free(in->parameters.data);
181     free(in);
182 }
183 
184 void
185 free_krb5_algorithm_identifiers(krb5_algorithm_identifier ***in)
186 {
187     int i;
188     if (in == NULL || *in == NULL)
189         return;
190     for (i = 0; (*in)[i] != NULL; i++) {
191         free_krb5_algorithm_identifier((*in)[i]);
192     }
193     free(*in);
194 }
195 
196 void
197 free_krb5_kdc_dh_key_info(krb5_kdc_dh_key_info **in)
198 {
199     if (*in == NULL) return;
200     free((*in)->subjectPublicKey.data);
201     free(*in);
202 }
203 
204 void
205 init_krb5_pa_pk_as_req(krb5_pa_pk_as_req **in)
206 {
207     (*in) = malloc(sizeof(krb5_pa_pk_as_req));
208     if ((*in) == NULL) return;
209     (*in)->signedAuthPack.data = NULL;
210     (*in)->signedAuthPack.length = 0;
211     (*in)->trustedCertifiers = NULL;
212     (*in)->kdcPkId.data = NULL;
213     (*in)->kdcPkId.length = 0;
214 }
215 
216 void
217 init_krb5_reply_key_pack(krb5_reply_key_pack **in)
218 {
219     (*in) = malloc(sizeof(krb5_reply_key_pack));
220     if ((*in) == NULL) return;
221     (*in)->replyKey.contents = NULL;
222     (*in)->replyKey.length = 0;
223     (*in)->asChecksum.contents = NULL;
224     (*in)->asChecksum.length = 0;
225 }
226 
227 void
228 init_krb5_pa_pk_as_rep(krb5_pa_pk_as_rep **in)
229 {
230     (*in) = malloc(sizeof(krb5_pa_pk_as_rep));
231     if ((*in) == NULL) return;
232     (*in)->u.dh_Info.serverDHNonce.length = 0;
233     (*in)->u.dh_Info.serverDHNonce.data = NULL;
234     (*in)->u.dh_Info.dhSignedData.length = 0;
235     (*in)->u.dh_Info.dhSignedData.data = NULL;
236     (*in)->u.encKeyPack.length = 0;
237     (*in)->u.encKeyPack.data = NULL;
238     (*in)->u.dh_Info.kdfID = NULL;
239 }
240 
241 krb5_error_code
242 pkinit_copy_krb5_data(krb5_data *dst, const krb5_data *src)
243 {
244     if (dst == NULL || src == NULL)
245         return EINVAL;
246     if (src->data == NULL) {
247         dst->data = NULL;
248         dst->length = 0;
249         return 0;
250     }
251     dst->data = malloc(src->length);
252     if (dst->data == NULL)
253         return ENOMEM;
254     memcpy(dst->data, src->data, src->length);
255     dst->length = src->length;
256     return 0;
257 }
258 
259 /* debugging functions */
260 void
261 print_buffer(const unsigned char *buf, unsigned int len)
262 {
263     unsigned  i = 0;
264     if (len <= 0)
265         return;
266 
267     for (i = 0; i < len; i++)
268         pkiDebug("%02x ", buf[i]);
269     pkiDebug("\n");
270 }
271 
272 void
273 print_buffer_bin(unsigned char *buf, unsigned int len, char *filename)
274 {
275     FILE *f = NULL;
276     unsigned int i = 0;
277 
278     if (len <= 0 || filename == NULL)
279         return;
280 
281     if ((f = fopen(filename, "w")) == NULL)
282         return;
283 
284     set_cloexec_file(f);
285 
286     for (i = 0; i < len; i++)
287         fputc(buf[i], f);
288 
289     fclose(f);
290 }
291