xref: /freebsd/crypto/krb5/src/plugins/preauth/pkinit/pkinit_lib.c (revision f1c4c3daccbaf3820f0e2224de53df12fc952fcc)
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 "k5-int.h"
33 #include "pkinit.h"
34 
35 #define FAKECERT
36 
37 krb5_error_code
pkinit_init_req_opts(pkinit_req_opts ** reqopts)38 pkinit_init_req_opts(pkinit_req_opts **reqopts)
39 {
40     krb5_error_code retval = ENOMEM;
41     pkinit_req_opts *opts = NULL;
42 
43     *reqopts = NULL;
44     opts = calloc(1, sizeof(*opts));
45     if (opts == NULL)
46         return retval;
47 
48     opts->require_eku = 1;
49     opts->accept_secondary_eku = 0;
50     opts->allow_upn = 0;
51     opts->require_crl_checking = 0;
52     opts->dh_size = PKINIT_DEFAULT_DH_MIN_BITS;
53 
54     *reqopts = opts;
55 
56     return 0;
57 }
58 
59 void
pkinit_fini_req_opts(pkinit_req_opts * opts)60 pkinit_fini_req_opts(pkinit_req_opts *opts)
61 {
62     free(opts);
63     return;
64 }
65 
66 krb5_error_code
pkinit_init_plg_opts(pkinit_plg_opts ** plgopts)67 pkinit_init_plg_opts(pkinit_plg_opts **plgopts)
68 {
69     krb5_error_code retval = ENOMEM;
70     pkinit_plg_opts *opts = NULL;
71 
72     *plgopts = NULL;
73     opts = calloc(1, sizeof(pkinit_plg_opts));
74     if (opts == NULL)
75         return retval;
76 
77     opts->require_eku = 1;
78     opts->accept_secondary_eku = 0;
79     opts->allow_upn = 0;
80     opts->require_crl_checking = 0;
81     opts->require_freshness = 0;
82     opts->disable_freshness = 0;
83 
84     opts->dh_min_bits = PKINIT_DEFAULT_DH_MIN_BITS;
85 
86     *plgopts = opts;
87 
88     return 0;
89 }
90 
91 void
pkinit_fini_plg_opts(pkinit_plg_opts * opts)92 pkinit_fini_plg_opts(pkinit_plg_opts *opts)
93 {
94     free(opts);
95     return;
96 }
97 
98 void
free_krb5_pa_pk_as_req(krb5_pa_pk_as_req ** in)99 free_krb5_pa_pk_as_req(krb5_pa_pk_as_req **in)
100 {
101     if (*in == NULL) return;
102     free((*in)->signedAuthPack.data);
103     if ((*in)->trustedCertifiers != NULL)
104         free_krb5_external_principal_identifier(&(*in)->trustedCertifiers);
105     free((*in)->kdcPkId.data);
106     free(*in);
107 }
108 
109 void
free_krb5_reply_key_pack(krb5_reply_key_pack ** in)110 free_krb5_reply_key_pack(krb5_reply_key_pack **in)
111 {
112     if (*in == NULL) return;
113     free((*in)->replyKey.contents);
114     free((*in)->asChecksum.contents);
115     free(*in);
116 }
117 
118 void
free_krb5_auth_pack(krb5_auth_pack ** in)119 free_krb5_auth_pack(krb5_auth_pack **in)
120 {
121     if ((*in) == NULL) return;
122     krb5_free_data_contents(NULL, &(*in)->clientPublicValue);
123     free((*in)->pkAuthenticator.paChecksum.data);
124     krb5_free_data(NULL, (*in)->pkAuthenticator.freshnessToken);
125     free_pachecksum2(NULL, &(*in)->pkAuthenticator.paChecksum2);
126     if ((*in)->supportedCMSTypes != NULL)
127         free_krb5_algorithm_identifiers(&((*in)->supportedCMSTypes));
128     if ((*in)->supportedKDFs) {
129         krb5_data **supportedKDFs = (*in)->supportedKDFs;
130         unsigned i;
131         for (i = 0; supportedKDFs[i]; i++)
132             krb5_free_data(NULL, supportedKDFs[i]);
133         free(supportedKDFs);
134     }
135     free(*in);
136 }
137 
138 void
free_krb5_pa_pk_as_rep(krb5_pa_pk_as_rep ** in)139 free_krb5_pa_pk_as_rep(krb5_pa_pk_as_rep **in)
140 {
141     if (*in == NULL) return;
142     switch ((*in)->choice) {
143     case choice_pa_pk_as_rep_dhInfo:
144         krb5_free_data(NULL, (*in)->u.dh_Info.kdfID);
145         free((*in)->u.dh_Info.dhSignedData.data);
146         break;
147     case choice_pa_pk_as_rep_encKeyPack:
148         free((*in)->u.encKeyPack.data);
149         break;
150     default:
151         break;
152     }
153     free(*in);
154 }
155 
156 void
free_krb5_external_principal_identifier(krb5_external_principal_identifier *** in)157 free_krb5_external_principal_identifier(krb5_external_principal_identifier ***in)
158 {
159     int i = 0;
160     if (*in == NULL) return;
161     while ((*in)[i] != NULL) {
162         free((*in)[i]->subjectName.data);
163         free((*in)[i]->issuerAndSerialNumber.data);
164         free((*in)[i]->subjectKeyIdentifier.data);
165         free((*in)[i]);
166         i++;
167     }
168     free(*in);
169 }
170 
171 void
free_krb5_algorithm_identifier(krb5_algorithm_identifier * in)172 free_krb5_algorithm_identifier(krb5_algorithm_identifier *in)
173 {
174     if (in == NULL)
175         return;
176     free(in->algorithm.data);
177     free(in->parameters.data);
178     free(in);
179 }
180 
181 void
free_krb5_algorithm_identifiers(krb5_algorithm_identifier *** in)182 free_krb5_algorithm_identifiers(krb5_algorithm_identifier ***in)
183 {
184     int i;
185     if (in == NULL || *in == NULL)
186         return;
187     for (i = 0; (*in)[i] != NULL; i++) {
188         free_krb5_algorithm_identifier((*in)[i]);
189     }
190     free(*in);
191 }
192 
193 void
free_krb5_kdc_dh_key_info(krb5_kdc_dh_key_info ** in)194 free_krb5_kdc_dh_key_info(krb5_kdc_dh_key_info **in)
195 {
196     if (*in == NULL) return;
197     free((*in)->subjectPublicKey.data);
198     free(*in);
199 }
200 
201 void
free_pachecksum2(krb5_context context,krb5_pachecksum2 ** in)202 free_pachecksum2(krb5_context context, krb5_pachecksum2 **in)
203 {
204     if (*in == NULL)
205         return;
206     krb5_free_data_contents(context, &(*in)->checksum);
207     krb5_free_data_contents(context, &(*in)->algorithmIdentifier.algorithm);
208     krb5_free_data_contents(context, &(*in)->algorithmIdentifier.parameters);
209     free(*in);
210     *in = NULL;
211 }
212 
213 void
init_krb5_pa_pk_as_req(krb5_pa_pk_as_req ** in)214 init_krb5_pa_pk_as_req(krb5_pa_pk_as_req **in)
215 {
216     (*in) = malloc(sizeof(krb5_pa_pk_as_req));
217     if ((*in) == NULL) return;
218     (*in)->signedAuthPack.data = NULL;
219     (*in)->signedAuthPack.length = 0;
220     (*in)->trustedCertifiers = NULL;
221     (*in)->kdcPkId.data = NULL;
222     (*in)->kdcPkId.length = 0;
223 }
224 
225 void
init_krb5_reply_key_pack(krb5_reply_key_pack ** in)226 init_krb5_reply_key_pack(krb5_reply_key_pack **in)
227 {
228     (*in) = malloc(sizeof(krb5_reply_key_pack));
229     if ((*in) == NULL) return;
230     (*in)->replyKey.contents = NULL;
231     (*in)->replyKey.length = 0;
232     (*in)->asChecksum.contents = NULL;
233     (*in)->asChecksum.length = 0;
234 }
235 
236 void
init_krb5_pa_pk_as_rep(krb5_pa_pk_as_rep ** in)237 init_krb5_pa_pk_as_rep(krb5_pa_pk_as_rep **in)
238 {
239     (*in) = malloc(sizeof(krb5_pa_pk_as_rep));
240     if ((*in) == NULL) return;
241     (*in)->u.dh_Info.serverDHNonce.length = 0;
242     (*in)->u.dh_Info.serverDHNonce.data = NULL;
243     (*in)->u.dh_Info.dhSignedData.length = 0;
244     (*in)->u.dh_Info.dhSignedData.data = NULL;
245     (*in)->u.encKeyPack.length = 0;
246     (*in)->u.encKeyPack.data = NULL;
247     (*in)->u.dh_Info.kdfID = NULL;
248 }
249 
250 krb5_error_code
pkinit_copy_krb5_data(krb5_data * dst,const krb5_data * src)251 pkinit_copy_krb5_data(krb5_data *dst, const krb5_data *src)
252 {
253     if (dst == NULL || src == NULL)
254         return EINVAL;
255     if (src->data == NULL) {
256         dst->data = NULL;
257         dst->length = 0;
258         return 0;
259     }
260     dst->data = malloc(src->length);
261     if (dst->data == NULL)
262         return ENOMEM;
263     memcpy(dst->data, src->data, src->length);
264     dst->length = src->length;
265     return 0;
266 }
267 
268 /* debugging functions */
269 void
print_buffer(const unsigned char * buf,unsigned int len)270 print_buffer(const unsigned char *buf, unsigned int len)
271 {
272     unsigned  i = 0;
273     if (len <= 0)
274         return;
275 
276     for (i = 0; i < len; i++)
277         pkiDebug("%02x ", buf[i]);
278     pkiDebug("\n");
279 }
280 
281 void
print_buffer_bin(unsigned char * buf,unsigned int len,char * filename)282 print_buffer_bin(unsigned char *buf, unsigned int len, char *filename)
283 {
284     FILE *f = NULL;
285     unsigned int i = 0;
286 
287     if (len <= 0 || filename == NULL)
288         return;
289 
290     if ((f = fopen(filename, "w")) == NULL)
291         return;
292 
293     set_cloexec_file(f);
294 
295     for (i = 0; i < len; i++)
296         fputc(buf[i], f);
297 
298     fclose(f);
299 }
300