Print this page
8982 Support building with OpenSSL 1.1
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ new/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.c
1 1 /*
2 2 * COPYRIGHT (C) 2006,2007
3 3 * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
4 4 * ALL RIGHTS RESERVED
5 5 *
6 6 * Permission is granted to use, copy, create derivative works
7 7 * and redistribute this software and such derivative works
8 8 * for any purpose, so long as the name of The University of
9 9 * Michigan is not used in any advertising or publicity
10 10 * pertaining to the use of distribution of this software
11 11 * without specific, written prior authorization. If the
12 12 * above copyright notice or any other identification of the
13 13 * University of Michigan is included in any copy of any
14 14 * portion of this software, then the disclaimer below must
15 15 * also be included.
16 16 *
17 17 * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
18 18 * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
19 19 * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
20 20 * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
21 21 * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
22 22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
23 23 * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
|
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
24 24 * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
25 25 * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
26 26 * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
27 27 * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
28 28 * SUCH DAMAGES.
29 29 */
30 30
31 31 /*
32 32 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
33 33 * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved.
34 + * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
34 35 */
35 36
36 37 #include <errno.h>
37 38 #include <string.h>
38 39 #include <stdio.h>
39 40 #include <stdlib.h>
40 41 #include <dlfcn.h>
41 42 #include <unistd.h>
42 43 #include <dirent.h>
43 44
44 45
45 46 /* Solaris Kerberos */
46 47 #include <libintl.h>
47 48 #include <assert.h>
48 49 #include <security/pam_appl.h>
49 50 #include <ctype.h>
50 51 #include "k5-int.h"
51 52 #include <ctype.h>
52 53
53 54 /*
54 55 * Q: What is this SILLYDECRYPT stuff about?
55 56 * A: When using the ActivCard Linux pkcs11 library (v2.0.1),
56 57 * the decrypt function fails. By inserting an extra
57 58 * function call, which serves nothing but to change the
58 59 * stack, we were able to work around the issue. If the
59 60 * ActivCard library is fixed in the future, this
60 61 * definition and related code can be removed.
61 62 */
62 63 #define SILLYDECRYPT
63 64
64 65 #include "pkinit_crypto_openssl.h"
65 66
66 67 /*
67 68 * Solaris Kerberos:
68 69 * Changed to a switch statement so gettext() can be used
69 70 * for internationization.
70 71 * Use defined constants rather than raw numbers for error codes.
71 72 */
72 73 static char *
73 74 pkcs11_error_table(short code) {
74 75 switch (code) {
75 76 case CKR_OK:
76 77 return (gettext("ok"));
77 78 case CKR_CANCEL:
78 79 return (gettext("cancel"));
79 80 case CKR_HOST_MEMORY:
80 81 return (gettext("host memory"));
81 82 case CKR_SLOT_ID_INVALID:
82 83 return (gettext("slot id invalid"));
83 84 case CKR_GENERAL_ERROR:
84 85 return (gettext("general error"));
85 86 case CKR_FUNCTION_FAILED:
86 87 return (gettext("function failed"));
87 88 case CKR_ARGUMENTS_BAD:
88 89 return (gettext("arguments bad"));
89 90 case CKR_NO_EVENT:
90 91 return (gettext("no event"));
91 92 case CKR_NEED_TO_CREATE_THREADS:
92 93 return (gettext("need to create threads"));
93 94 case CKR_CANT_LOCK:
94 95 return (gettext("cant lock"));
95 96 case CKR_ATTRIBUTE_READ_ONLY:
96 97 return (gettext("attribute read only"));
97 98 case CKR_ATTRIBUTE_SENSITIVE:
98 99 return (gettext("attribute sensitive"));
99 100 case CKR_ATTRIBUTE_TYPE_INVALID:
100 101 return (gettext("attribute type invalid"));
101 102 case CKR_ATTRIBUTE_VALUE_INVALID:
102 103 return (gettext("attribute value invalid"));
103 104 case CKR_DATA_INVALID:
104 105 return (gettext("data invalid"));
105 106 case CKR_DATA_LEN_RANGE:
106 107 return (gettext("data len range"));
107 108 case CKR_DEVICE_ERROR:
108 109 return (gettext("device error"));
109 110 case CKR_DEVICE_MEMORY:
110 111 return (gettext("device memory"));
111 112 case CKR_DEVICE_REMOVED:
112 113 return (gettext("device removed"));
113 114 case CKR_ENCRYPTED_DATA_INVALID:
114 115 return (gettext("encrypted data invalid"));
115 116 case CKR_ENCRYPTED_DATA_LEN_RANGE:
116 117 return (gettext("encrypted data len range"));
117 118 case CKR_FUNCTION_CANCELED:
118 119 return (gettext("function canceled"));
119 120 case CKR_FUNCTION_NOT_PARALLEL:
120 121 return (gettext("function not parallel"));
121 122 case CKR_FUNCTION_NOT_SUPPORTED:
122 123 return (gettext("function not supported"));
123 124 case CKR_KEY_HANDLE_INVALID:
124 125 return (gettext("key handle invalid"));
125 126 case CKR_KEY_SIZE_RANGE:
126 127 return (gettext("key size range"));
127 128 case CKR_KEY_TYPE_INCONSISTENT:
128 129 return (gettext("key type inconsistent"));
129 130 case CKR_KEY_NOT_NEEDED:
130 131 return (gettext("key not needed"));
131 132 case CKR_KEY_CHANGED:
132 133 return (gettext("key changed"));
133 134 case CKR_KEY_NEEDED:
134 135 return (gettext("key needed"));
135 136 case CKR_KEY_INDIGESTIBLE:
136 137 return (gettext("key indigestible"));
137 138 case CKR_KEY_FUNCTION_NOT_PERMITTED:
138 139 return (gettext("key function not permitted"));
139 140 case CKR_KEY_NOT_WRAPPABLE:
140 141 return (gettext("key not wrappable"));
141 142 case CKR_KEY_UNEXTRACTABLE:
142 143 return (gettext("key unextractable"));
143 144 case CKR_MECHANISM_INVALID:
144 145 return (gettext("mechanism invalid"));
145 146 case CKR_MECHANISM_PARAM_INVALID:
146 147 return (gettext("mechanism param invalid"));
147 148 case CKR_OBJECT_HANDLE_INVALID:
148 149 return (gettext("object handle invalid"));
149 150 case CKR_OPERATION_ACTIVE:
150 151 return (gettext("operation active"));
151 152 case CKR_OPERATION_NOT_INITIALIZED:
152 153 return (gettext("operation not initialized"));
153 154 case CKR_PIN_INCORRECT:
154 155 return (gettext("pin incorrect"));
155 156 case CKR_PIN_INVALID:
156 157 return (gettext("pin invalid"));
157 158 case CKR_PIN_LEN_RANGE:
158 159 return (gettext("pin len range"));
159 160 case CKR_PIN_EXPIRED:
160 161 return (gettext("pin expired"));
161 162 case CKR_PIN_LOCKED:
162 163 return (gettext("pin locked"));
163 164 case CKR_SESSION_CLOSED:
164 165 return (gettext("session closed"));
165 166 case CKR_SESSION_COUNT:
166 167 return (gettext("session count"));
167 168 case CKR_SESSION_HANDLE_INVALID:
168 169 return (gettext("session handle invalid"));
169 170 case CKR_SESSION_PARALLEL_NOT_SUPPORTED:
170 171 return (gettext("session parallel not supported"));
171 172 case CKR_SESSION_READ_ONLY:
172 173 return (gettext("session read only"));
173 174 case CKR_SESSION_EXISTS:
174 175 return (gettext("session exists"));
175 176 case CKR_SESSION_READ_ONLY_EXISTS:
176 177 return (gettext("session read only exists"));
177 178 case CKR_SESSION_READ_WRITE_SO_EXISTS:
178 179 return (gettext("session read write so exists"));
179 180 case CKR_SIGNATURE_INVALID:
180 181 return (gettext("signature invalid"));
181 182 case CKR_SIGNATURE_LEN_RANGE:
182 183 return (gettext("signature len range"));
183 184 case CKR_TEMPLATE_INCOMPLETE:
184 185 return (gettext("template incomplete"));
185 186 case CKR_TEMPLATE_INCONSISTENT:
186 187 return (gettext("template inconsistent"));
187 188 case CKR_TOKEN_NOT_PRESENT:
188 189 return (gettext("token not present"));
189 190 case CKR_TOKEN_NOT_RECOGNIZED:
190 191 return (gettext("token not recognized"));
191 192 case CKR_TOKEN_WRITE_PROTECTED:
192 193 return (gettext("token write protected"));
193 194 case CKR_UNWRAPPING_KEY_HANDLE_INVALID:
194 195 return (gettext("unwrapping key handle invalid"));
195 196 case CKR_UNWRAPPING_KEY_SIZE_RANGE:
196 197 return (gettext("unwrapping key size range"));
197 198 case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT:
198 199 return (gettext("unwrapping key type inconsistent"));
199 200 case CKR_USER_ALREADY_LOGGED_IN:
200 201 return (gettext("user already logged in"));
201 202 case CKR_USER_NOT_LOGGED_IN:
202 203 return (gettext("user not logged in"));
203 204 case CKR_USER_PIN_NOT_INITIALIZED:
204 205 return (gettext("user pin not initialized"));
205 206 case CKR_USER_TYPE_INVALID:
206 207 return (gettext("user type invalid"));
207 208 case CKR_USER_ANOTHER_ALREADY_LOGGED_IN:
208 209 return (gettext("user another already logged in"));
209 210 case CKR_USER_TOO_MANY_TYPES:
210 211 return (gettext("user too many types"));
211 212 case CKR_WRAPPED_KEY_INVALID:
212 213 return (gettext("wrapped key invalid"));
213 214 case CKR_WRAPPED_KEY_LEN_RANGE:
214 215 return (gettext("wrapped key len range"));
215 216 case CKR_WRAPPING_KEY_HANDLE_INVALID:
216 217 return (gettext("wrapping key handle invalid"));
217 218 case CKR_WRAPPING_KEY_SIZE_RANGE:
218 219 return (gettext("wrapping key size range"));
219 220 case CKR_WRAPPING_KEY_TYPE_INCONSISTENT:
220 221 return (gettext("wrapping key type inconsistent"));
221 222 case CKR_RANDOM_SEED_NOT_SUPPORTED:
222 223 return (gettext("random seed not supported"));
223 224 case CKR_RANDOM_NO_RNG:
224 225 return (gettext("random no rng"));
225 226 case CKR_DOMAIN_PARAMS_INVALID:
226 227 return (gettext("domain params invalid"));
227 228 case CKR_BUFFER_TOO_SMALL:
228 229 return (gettext("buffer too small"));
229 230 case CKR_SAVED_STATE_INVALID:
230 231 return (gettext("saved state invalid"));
231 232 case CKR_INFORMATION_SENSITIVE:
232 233 return (gettext("information sensitive"));
233 234 case CKR_STATE_UNSAVEABLE:
234 235 return (gettext("state unsaveable"));
235 236 case CKR_CRYPTOKI_NOT_INITIALIZED:
236 237 return (gettext("cryptoki not initialized"));
237 238 case CKR_CRYPTOKI_ALREADY_INITIALIZED:
238 239 return (gettext("cryptoki already initialized"));
239 240 case CKR_MUTEX_BAD:
240 241 return (gettext("mutex bad"));
241 242 case CKR_MUTEX_NOT_LOCKED:
242 243 return (gettext("mutex not locked"));
243 244 case CKR_FUNCTION_REJECTED:
244 245 return (gettext("function rejected"));
245 246 default:
246 247 return (gettext("unknown error"));
247 248 }
248 249 }
249 250
250 251 /* DH parameters */
251 252 unsigned char pkinit_1024_dhprime[128] = {
252 253 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
253 254 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
254 255 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
255 256 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
256 257 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
257 258 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
258 259 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
259 260 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
260 261 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
261 262 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
262 263 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
263 264 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
264 265 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
265 266 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
266 267 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
267 268 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
268 269 };
269 270
270 271 unsigned char pkinit_2048_dhprime[2048/8] = {
271 272 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
272 273 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
273 274 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
274 275 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
275 276 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
276 277 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
277 278 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
278 279 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
279 280 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
280 281 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
281 282 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
282 283 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
283 284 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
284 285 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
285 286 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
286 287 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
287 288 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
288 289 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
289 290 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
290 291 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
291 292 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
292 293 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
293 294 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
294 295 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
295 296 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
296 297 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
297 298 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
298 299 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
299 300 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
300 301 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
301 302 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68,
302 303 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
303 304 };
304 305
305 306 unsigned char pkinit_4096_dhprime[4096/8] = {
306 307 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
307 308 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
308 309 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
309 310 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
310 311 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
311 312 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
312 313 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
313 314 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
314 315 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
315 316 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
316 317 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
317 318 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
318 319 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
319 320 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
320 321 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
321 322 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
322 323 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
323 324 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
324 325 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
325 326 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
326 327 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
327 328 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
328 329 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
329 330 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
330 331 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
331 332 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
332 333 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
333 334 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
334 335 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
335 336 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
336 337 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
337 338 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
338 339 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
339 340 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
340 341 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
341 342 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
342 343 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
343 344 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
344 345 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
345 346 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
346 347 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
347 348 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
348 349 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
349 350 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
350 351 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
351 352 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
352 353 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,
353 354 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
354 355 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,
355 356 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
356 357 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
357 358 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
358 359 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,
359 360 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
360 361 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,
361 362 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
|
↓ open down ↓ |
318 lines elided |
↑ open up ↑ |
362 363 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
363 364 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
364 365 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
365 366 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
366 367 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
367 368 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
368 369 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
369 370 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
370 371 };
371 372
373 +#if OPENSSL_VERSION_NUMBER < 0x10100000L
374 +/*
375 + * Many things have changed in OpenSSL 1.1. The code in this file has been
376 + * updated to use the v1.1 APIs but some are new and require emulation
377 + * for older OpenSSL versions.
378 + */
379 +
380 +/* EVP_MD_CTX construct and destructor names have changed */
381 +
382 +#define EVP_MD_CTX_new EVP_MD_CTX_create
383 +#define EVP_MD_CTX_free EVP_MD_CTX_destroy
384 +
385 +/* ASN1_STRING_data is deprecated */
386 +#define ASN1_STRING_get0_data ASN1_STRING_data
387 +
388 +/* X509_STORE_CTX_trusted_stack is deprecated */
389 +#define X509_STORE_CTX_set0_trusted_stack X509_STORE_CTX_trusted_stack
390 +
391 +/* get_rfc2409_prime_1024() has been renamed. */
392 +#define BN_get_rfc2409_prime_1024 get_rfc2409_prime_1024
393 +
394 +#define OBJ_get0_data(o) ((o)->data)
395 +#define OBJ_length(o) ((o)->length)
396 +
397 +/* Some new DH functions that aren't in OpenSSL 1.0.x */
398 +#define DH_bits(dh) BN_num_bits((dh)->p);
399 +
400 +#define DH_set0_pqg(dh, p, q, g) __DH_set0_pqg(dh, p, q, g)
401 +static int
402 +__DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
403 +{
404 + if ((dh->p == NULL && p == NULL) || (dh->g == NULL && g == NULL))
405 + return 0;
406 +
407 + if (p != NULL) {
408 + BN_free(dh->p);
409 + dh->p = p;
410 + }
411 + if (q != NULL) {
412 + BN_free(dh->q);
413 + dh->q = q;
414 + }
415 + if (g != NULL) {
416 + BN_free(dh->g);
417 + dh->g = g;
418 + }
419 +
420 + if (q != NULL) {
421 + dh->length = BN_num_bits(q);
422 + }
423 +
424 + return 1;
425 +}
426 +
427 +#define DH_get0_pqg(dh, p, q, g) __DH_get0_pqg(dh, p, q, g)
428 +static void
429 +__DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q,
430 + const BIGNUM **g)
431 +{
432 + if (p != NULL)
433 + *p = dh->p;
434 + if (q != NULL)
435 + *q = dh->q;
436 + if (g != NULL)
437 + *g = dh->g;
438 +}
439 +
440 +#define DH_set0_key(dh, pub, priv) __DH_set0_key(dh, pub, priv)
441 +static int
442 +__DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
443 +{
444 + if (pub_key != NULL) {
445 + BN_free(dh->pub_key);
446 + dh->pub_key = pub_key;
447 + }
448 + if (priv_key != NULL) {
449 + BN_free(dh->priv_key);
450 + dh->priv_key = priv_key;
451 + }
452 +
453 + return 1;
454 +}
455 +
456 +#define DH_get0_key(dh, pub, priv) __DH_get0_key(dh, pub, priv)
457 +static void
458 +__DH_get0_key(const DH *dh, const BIGNUM **pub, const BIGNUM **priv)
459 +{
460 + if (pub != NULL)
461 + *pub = dh->pub_key;
462 + if (priv != NULL)
463 + *priv = dh->priv_key;
464 +}
465 +
466 +#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
467 +
372 468 /* Solaris Kerberos */
373 469 static k5_mutex_t oids_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
374 470 static int pkinit_oids_refs = 0;
375 471
376 472 krb5_error_code
377 473 pkinit_init_plg_crypto(pkinit_plg_crypto_context *cryptoctx) {
378 474
379 475 krb5_error_code retval = ENOMEM;
380 476 pkinit_plg_crypto_context ctx = NULL;
381 477
382 478 /* initialize openssl routines */
383 479 /* Solaris Kerberos */
384 480 retval = openssl_init();
385 481 if (retval != 0)
386 482 goto out;
387 483
388 484 ctx = (pkinit_plg_crypto_context)malloc(sizeof(*ctx));
389 485 if (ctx == NULL)
390 486 goto out;
391 487 (void) memset(ctx, 0, sizeof(*ctx));
392 488
393 489 pkiDebug("%s: initializing openssl crypto context at %p\n",
394 490 __FUNCTION__, ctx);
395 491 retval = pkinit_init_pkinit_oids(ctx);
396 492 if (retval)
397 493 goto out;
398 494
399 495 retval = pkinit_init_dh_params(ctx);
400 496 if (retval)
401 497 goto out;
402 498
403 499 *cryptoctx = ctx;
404 500
405 501 out:
406 502 if (retval && ctx != NULL)
407 503 pkinit_fini_plg_crypto(ctx);
408 504
409 505 return retval;
410 506 }
411 507
412 508 void
413 509 pkinit_fini_plg_crypto(pkinit_plg_crypto_context cryptoctx)
414 510 {
415 511 pkiDebug("%s: freeing context at %p\n", __FUNCTION__, cryptoctx);
416 512
417 513 if (cryptoctx == NULL)
418 514 return;
419 515 pkinit_fini_pkinit_oids(cryptoctx);
420 516 pkinit_fini_dh_params(cryptoctx);
421 517 free(cryptoctx);
422 518 }
423 519
424 520 krb5_error_code
425 521 pkinit_init_identity_crypto(pkinit_identity_crypto_context *idctx)
426 522 {
427 523 krb5_error_code retval = ENOMEM;
428 524 pkinit_identity_crypto_context ctx = NULL;
429 525
430 526 ctx = (pkinit_identity_crypto_context)malloc(sizeof(*ctx));
431 527 if (ctx == NULL)
432 528 goto out;
433 529 (void) memset(ctx, 0, sizeof(*ctx));
434 530
435 531 retval = pkinit_init_certs(ctx);
436 532 if (retval)
437 533 goto out;
438 534
439 535 retval = pkinit_init_pkcs11(ctx);
440 536 if (retval)
441 537 goto out;
442 538
443 539 pkiDebug("%s: returning ctx at %p\n", __FUNCTION__, ctx);
444 540 *idctx = ctx;
445 541
446 542 out:
447 543 if (retval) {
448 544 if (ctx)
449 545 pkinit_fini_identity_crypto(ctx);
450 546 }
451 547
452 548 return retval;
453 549 }
454 550
455 551 void
456 552 pkinit_fini_identity_crypto(pkinit_identity_crypto_context idctx)
457 553 {
458 554 if (idctx == NULL)
459 555 return;
460 556
461 557 pkiDebug("%s: freeing ctx at %p\n", __FUNCTION__, idctx);
462 558 pkinit_fini_certs(idctx);
463 559 pkinit_fini_pkcs11(idctx);
464 560 free(idctx);
465 561 }
466 562
467 563 krb5_error_code
468 564 pkinit_init_req_crypto(pkinit_req_crypto_context *cryptoctx)
469 565 {
470 566
471 567 pkinit_req_crypto_context ctx = NULL;
472 568
473 569 /* Solaris Kerberos */
474 570 if (cryptoctx == NULL)
475 571 return EINVAL;
476 572
477 573 ctx = (pkinit_req_crypto_context)malloc(sizeof(*ctx));
478 574 if (ctx == NULL)
479 575 return ENOMEM;
480 576 (void) memset(ctx, 0, sizeof(*ctx));
481 577
482 578 ctx->dh = NULL;
483 579 ctx->received_cert = NULL;
484 580
485 581 *cryptoctx = ctx;
486 582
487 583 pkiDebug("%s: returning ctx at %p\n", __FUNCTION__, ctx);
488 584
489 585 return 0;
490 586 }
491 587
492 588 void
493 589 pkinit_fini_req_crypto(pkinit_req_crypto_context req_cryptoctx)
494 590 {
495 591 if (req_cryptoctx == NULL)
496 592 return;
497 593
498 594 pkiDebug("%s: freeing ctx at %p\n", __FUNCTION__, req_cryptoctx);
499 595 if (req_cryptoctx->dh != NULL)
500 596 DH_free(req_cryptoctx->dh);
501 597 if (req_cryptoctx->received_cert != NULL)
502 598 X509_free(req_cryptoctx->received_cert);
503 599
504 600 free(req_cryptoctx);
505 601 }
506 602
507 603 static krb5_error_code
508 604 pkinit_init_pkinit_oids(pkinit_plg_crypto_context ctx)
509 605 {
510 606 krb5_error_code retval = ENOMEM;
511 607 int nid = 0;
512 608
513 609 /*
514 610 * If OpenSSL already knows about the OID, use the
515 611 * existing definition. Otherwise, create an OID object.
516 612 */
|
↓ open down ↓ |
135 lines elided |
↑ open up ↑ |
517 613 #define CREATE_OBJ_IF_NEEDED(oid, vn, sn, ln) \
518 614 nid = OBJ_txt2nid(oid); \
519 615 if (nid == NID_undef) { \
520 616 nid = OBJ_create(oid, sn, ln); \
521 617 if (nid == NID_undef) { \
522 618 pkiDebug("Error creating oid object for '%s'\n", oid); \
523 619 goto out; \
524 620 } \
525 621 } \
526 622 ctx->vn = OBJ_nid2obj(nid);
527 -
623 +
528 624 /* Solaris Kerberos */
529 625 retval = k5_mutex_lock(&oids_mutex);
530 626 if (retval != 0)
531 627 goto out;
532 628
533 629 CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.2", id_pkinit_san,
534 630 "id-pkinit-san", "KRB5PrincipalName");
535 631
536 632 CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.1", id_pkinit_authData,
537 633 "id-pkinit-authdata", "PKINIT signedAuthPack");
538 634
539 635 CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.2", id_pkinit_DHKeyData,
540 636 "id-pkinit-DHKeyData", "PKINIT dhSignedData");
541 637
542 638 CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.3", id_pkinit_rkeyData,
543 639 "id-pkinit-rkeyData", "PKINIT encKeyPack");
544 640
545 641 CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.4", id_pkinit_KPClientAuth,
546 642 "id-pkinit-KPClientAuth", "PKINIT Client EKU");
547 643
548 644 CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.5", id_pkinit_KPKdc,
549 645 "id-pkinit-KPKdc", "KDC EKU");
550 646
551 647 #if 0
552 648 CREATE_OBJ_IF_NEEDED("1.2.840.113549.1.7.1", id_pkinit_authData9,
553 649 "id-pkcs7-data", "PKCS7 data");
554 650 #else
555 651 /* See note in pkinit_pkcs7type2oid() */
556 652 ctx->id_pkinit_authData9 = NULL;
557 653 #endif
558 654
559 655 CREATE_OBJ_IF_NEEDED("1.3.6.1.4.1.311.20.2.2", id_ms_kp_sc_logon,
|
↓ open down ↓ |
22 lines elided |
↑ open up ↑ |
560 656 "id-ms-kp-sc-logon EKU", "Microsoft SmartCard Login EKU");
561 657
562 658 CREATE_OBJ_IF_NEEDED("1.3.6.1.4.1.311.20.2.3", id_ms_san_upn,
563 659 "id-ms-san-upn", "Microsoft Universal Principal Name");
564 660
565 661 CREATE_OBJ_IF_NEEDED("1.3.6.1.5.5.7.3.1", id_kp_serverAuth,
566 662 "id-kp-serverAuth EKU", "Server Authentication EKU");
567 663
568 664 /* Success */
569 665 retval = 0;
570 -
666 +
571 667 pkinit_oids_refs++;
572 668 /* Solaris Kerberos */
573 669 k5_mutex_unlock(&oids_mutex);
574 670
575 671 out:
576 672 return retval;
577 673 }
578 674
579 675 static krb5_error_code
580 676 get_cert(char *filename, X509 **retcert)
581 677 {
582 678 X509 *cert = NULL;
583 679 BIO *tmp = NULL;
584 680 int code;
585 681 krb5_error_code retval;
586 682
587 683 if (filename == NULL || retcert == NULL)
588 684 return EINVAL;
589 685
590 686 *retcert = NULL;
591 687
592 688 tmp = BIO_new(BIO_s_file());
593 689 if (tmp == NULL)
594 690 return ENOMEM;
595 691
596 692 code = BIO_read_filename(tmp, filename);
597 693 if (code == 0) {
598 694 retval = errno;
599 695 goto cleanup;
600 696 }
601 697
602 698 cert = (X509 *) PEM_read_bio_X509(tmp, NULL, NULL, NULL);
603 699 if (cert == NULL) {
604 700 retval = EIO;
605 701 pkiDebug("failed to read certificate from %s\n", filename);
606 702 goto cleanup;
607 703 }
608 704 *retcert = cert;
609 705 retval = 0;
610 706 cleanup:
611 707 if (tmp != NULL)
612 708 BIO_free(tmp);
613 709 return retval;
614 710 }
615 711
616 712 static krb5_error_code
617 713 get_key(char *filename, EVP_PKEY **retkey)
618 714 {
619 715 EVP_PKEY *pkey = NULL;
620 716 BIO *tmp = NULL;
621 717 int code;
622 718 krb5_error_code retval;
623 719
624 720 if (filename == NULL || retkey == NULL)
625 721 return EINVAL;
626 722
627 723 tmp = BIO_new(BIO_s_file());
628 724 if (tmp == NULL)
629 725 return ENOMEM;
630 726
631 727 code = BIO_read_filename(tmp, filename);
632 728 if (code == 0) {
633 729 retval = errno;
634 730 goto cleanup;
635 731 }
636 732 pkey = (EVP_PKEY *) PEM_read_bio_PrivateKey(tmp, NULL, NULL, NULL);
637 733 if (pkey == NULL) {
638 734 retval = EIO;
639 735 pkiDebug("failed to read private key from %s\n", filename);
640 736 goto cleanup;
641 737 }
642 738 *retkey = pkey;
643 739 retval = 0;
644 740 cleanup:
645 741 if (tmp != NULL)
646 742 BIO_free(tmp);
647 743 return retval;
648 744 }
|
↓ open down ↓ |
68 lines elided |
↑ open up ↑ |
649 745
650 746 static void
651 747 pkinit_fini_pkinit_oids(pkinit_plg_crypto_context ctx)
652 748 {
653 749 if (ctx == NULL)
654 750 return;
655 751
656 752 /* Only call OBJ_cleanup once! */
657 753 /* Solaris Kerberos: locking */
658 754 k5_mutex_lock(&oids_mutex);
755 +#if OPENSSL_VERSION_NUMBER < 0x10100000L
756 + /*
757 + * In OpenSSL versions prior to 1.1.0, OBJ_cleanup() cleaned up OpenSSL's
758 + * internal object table. This function is deprecated in version 1.1.0.
759 + * No explicit de-initialisation is now required.
760 + */
659 761 if (--pkinit_oids_refs == 0)
660 762 OBJ_cleanup();
763 +#else
764 + pkinit_oids_refs--;
765 +#endif
661 766 k5_mutex_unlock(&oids_mutex);
662 767 }
663 768
769 +/* Construct an OpenSSL DH object for an Oakley group. */
770 +static DH *
771 +make_dhprime(uint8_t *prime, size_t len)
772 +{
773 + DH *dh = NULL;
774 + BIGNUM *p = NULL, *q = NULL, *g = NULL;
775 +
776 + if ((p = BN_bin2bn(prime, len, NULL)) == NULL)
777 + goto cleanup;
778 + if ((q = BN_new()) == NULL)
779 + goto cleanup;
780 + if (!BN_rshift1(q, p))
781 + goto cleanup;
782 + if ((g = BN_new()) == NULL)
783 + goto cleanup;
784 + if (!BN_set_word(g, DH_GENERATOR_2))
785 + goto cleanup;
786 +
787 + dh = DH_new();
788 + if (dh == NULL)
789 + goto cleanup;
790 + DH_set0_pqg(dh, p, q, g);
791 + p = g = q = NULL;
792 +
793 +cleanup:
794 + BN_free(p);
795 + BN_free(q);
796 + BN_free(g);
797 + return dh;
798 +}
799 +
664 800 static krb5_error_code
665 801 pkinit_init_dh_params(pkinit_plg_crypto_context plgctx)
666 802 {
667 803 krb5_error_code retval = ENOMEM;
668 804
669 - plgctx->dh_1024 = DH_new();
805 + plgctx->dh_1024 = make_dhprime(pkinit_1024_dhprime,
806 + sizeof(pkinit_1024_dhprime));
670 807 if (plgctx->dh_1024 == NULL)
671 808 goto cleanup;
672 - plgctx->dh_1024->p = BN_bin2bn(pkinit_1024_dhprime,
673 - sizeof(pkinit_1024_dhprime), NULL);
674 - if ((plgctx->dh_1024->g = BN_new()) == NULL ||
675 - (plgctx->dh_1024->q = BN_new()) == NULL)
676 - goto cleanup;
677 - BN_set_word(plgctx->dh_1024->g, DH_GENERATOR_2);
678 - BN_rshift1(plgctx->dh_1024->q, plgctx->dh_1024->p);
679 809
680 - plgctx->dh_2048 = DH_new();
810 + plgctx->dh_2048 = make_dhprime(pkinit_2048_dhprime,
811 + sizeof(pkinit_2048_dhprime));
681 812 if (plgctx->dh_2048 == NULL)
682 813 goto cleanup;
683 - plgctx->dh_2048->p = BN_bin2bn(pkinit_2048_dhprime,
684 - sizeof(pkinit_2048_dhprime), NULL);
685 - if ((plgctx->dh_2048->g = BN_new()) == NULL ||
686 - (plgctx->dh_2048->q = BN_new()) == NULL)
687 - goto cleanup;
688 - BN_set_word(plgctx->dh_2048->g, DH_GENERATOR_2);
689 - BN_rshift1(plgctx->dh_2048->q, plgctx->dh_2048->p);
690 814
691 - plgctx->dh_4096 = DH_new();
815 + plgctx->dh_4096 = make_dhprime(pkinit_4096_dhprime,
816 + sizeof(pkinit_4096_dhprime));
692 817 if (plgctx->dh_4096 == NULL)
693 818 goto cleanup;
694 - plgctx->dh_4096->p = BN_bin2bn(pkinit_4096_dhprime,
695 - sizeof(pkinit_4096_dhprime), NULL);
696 - if ((plgctx->dh_4096->g = BN_new()) == NULL ||
697 - (plgctx->dh_4096->q = BN_new()) == NULL)
698 - goto cleanup;
699 - BN_set_word(plgctx->dh_4096->g, DH_GENERATOR_2);
700 - BN_rshift1(plgctx->dh_4096->q, plgctx->dh_4096->p);
701 819
702 820 retval = 0;
703 821
704 822 cleanup:
705 823 if (retval)
706 824 pkinit_fini_dh_params(plgctx);
707 825
708 826 return retval;
709 827 }
710 828
711 829 static void
712 830 pkinit_fini_dh_params(pkinit_plg_crypto_context plgctx)
713 831 {
714 832 if (plgctx->dh_1024 != NULL)
715 833 DH_free(plgctx->dh_1024);
716 834 if (plgctx->dh_2048 != NULL)
717 835 DH_free(plgctx->dh_2048);
718 836 if (plgctx->dh_4096 != NULL)
719 837 DH_free(plgctx->dh_4096);
720 838
721 839 plgctx->dh_1024 = plgctx->dh_2048 = plgctx->dh_4096 = NULL;
722 840 }
723 841
724 842 static krb5_error_code
725 843 pkinit_init_certs(pkinit_identity_crypto_context ctx)
726 844 {
727 845 /* Solaris Kerberos */
728 846 int i;
729 847
730 848 for (i = 0; i < MAX_CREDS_ALLOWED; i++)
731 849 ctx->creds[i] = NULL;
732 850 ctx->my_certs = NULL;
733 851 ctx->cert_index = 0;
734 852 ctx->my_key = NULL;
735 853 ctx->trustedCAs = NULL;
736 854 ctx->intermediateCAs = NULL;
737 855 ctx->revoked = NULL;
738 856
739 857 return 0;
740 858 }
741 859
742 860 static void
743 861 pkinit_fini_certs(pkinit_identity_crypto_context ctx)
744 862 {
745 863 if (ctx == NULL)
746 864 return;
747 865
748 866 if (ctx->my_certs != NULL)
749 867 sk_X509_pop_free(ctx->my_certs, X509_free);
750 868
751 869 if (ctx->my_key != NULL)
752 870 EVP_PKEY_free(ctx->my_key);
753 871
754 872 if (ctx->trustedCAs != NULL)
755 873 sk_X509_pop_free(ctx->trustedCAs, X509_free);
756 874
757 875 if (ctx->intermediateCAs != NULL)
758 876 sk_X509_pop_free(ctx->intermediateCAs, X509_free);
759 877
760 878 if (ctx->revoked != NULL)
761 879 sk_X509_CRL_pop_free(ctx->revoked, X509_CRL_free);
762 880 }
763 881
764 882 static krb5_error_code
765 883 pkinit_init_pkcs11(pkinit_identity_crypto_context ctx)
766 884 {
767 885 /* Solaris Kerberos */
768 886
769 887 #ifndef WITHOUT_PKCS11
770 888 ctx->p11_module_name = strdup(PKCS11_MODNAME);
771 889 if (ctx->p11_module_name == NULL)
772 890 return ENOMEM;
773 891 ctx->p11_module = NULL;
774 892 ctx->slotid = PK_NOSLOT;
775 893 ctx->token_label = NULL;
776 894 ctx->cert_label = NULL;
777 895 ctx->PIN = NULL;
778 896 ctx->session = CK_INVALID_HANDLE;
779 897 ctx->p11 = NULL;
780 898 ctx->p11flags = 0; /* Solaris Kerberos */
781 899 #endif
782 900 ctx->pkcs11_method = 0;
783 901 (void) memset(ctx->creds, 0, sizeof(ctx->creds));
784 902
785 903 return 0;
786 904 }
787 905
788 906 static void
789 907 pkinit_fini_pkcs11(pkinit_identity_crypto_context ctx)
790 908 {
791 909 #ifndef WITHOUT_PKCS11
792 910 if (ctx == NULL)
793 911 return;
794 912
795 913 if (ctx->p11 != NULL) {
796 914 if (ctx->session != CK_INVALID_HANDLE) {
797 915 ctx->p11->C_CloseSession(ctx->session);
798 916 ctx->session = CK_INVALID_HANDLE;
799 917 }
800 918 /*
801 919 * Solaris Kerberos:
802 920 * Only call C_Finalize if the process was not already using pkcs11.
803 921 */
804 922 if (ctx->finalize_pkcs11 == TRUE)
805 923 ctx->p11->C_Finalize(NULL_PTR);
806 924
807 925 ctx->p11 = NULL;
808 926 }
809 927 if (ctx->p11_module != NULL) {
810 928 pkinit_C_UnloadModule(ctx->p11_module);
811 929 ctx->p11_module = NULL;
812 930 }
813 931 if (ctx->p11_module_name != NULL)
814 932 free(ctx->p11_module_name);
815 933 if (ctx->token_label != NULL)
816 934 free(ctx->token_label);
817 935 if (ctx->cert_id != NULL)
818 936 free(ctx->cert_id);
819 937 if (ctx->cert_label != NULL)
820 938 free(ctx->cert_label);
821 939 if (ctx->PIN != NULL) {
822 940 (void) memset(ctx->PIN, 0, strlen(ctx->PIN));
823 941 free(ctx->PIN);
824 942 }
825 943 #endif
826 944 }
827 945
828 946 krb5_error_code
829 947 pkinit_identity_set_prompter(pkinit_identity_crypto_context id_cryptoctx,
830 948 krb5_prompter_fct prompter,
831 949 void *prompter_data)
832 950 {
833 951 id_cryptoctx->prompter = prompter;
834 952 id_cryptoctx->prompter_data = prompter_data;
835 953
836 954 return 0;
837 955 }
838 956
839 957 /* ARGSUSED */
840 958 krb5_error_code
841 959 cms_signeddata_create(krb5_context context,
842 960 pkinit_plg_crypto_context plg_cryptoctx,
843 961 pkinit_req_crypto_context req_cryptoctx,
844 962 pkinit_identity_crypto_context id_cryptoctx,
845 963 int cms_msg_type,
846 964 int include_certchain,
847 965 unsigned char *data,
848 966 unsigned int data_len,
849 967 unsigned char **signed_data,
850 968 unsigned int *signed_data_len)
|
↓ open down ↓ |
140 lines elided |
↑ open up ↑ |
851 969 {
852 970 /* Solaris Kerberos */
853 971 krb5_error_code retval = KRB5KRB_ERR_GENERIC;
854 972 PKCS7 *p7 = NULL, *inner_p7 = NULL;
855 973 PKCS7_SIGNED *p7s = NULL;
856 974 PKCS7_SIGNER_INFO *p7si = NULL;
857 975 unsigned char *p;
858 976 ASN1_TYPE *pkinit_data = NULL;
859 977 STACK_OF(X509) * cert_stack = NULL;
860 978 ASN1_OCTET_STRING *digest_attr = NULL;
861 - EVP_MD_CTX ctx, ctx2;
979 + EVP_MD_CTX *ctx = NULL, *ctx2 = NULL;
862 980 const EVP_MD *md_tmp = NULL;
863 981 unsigned char md_data[EVP_MAX_MD_SIZE], md_data2[EVP_MAX_MD_SIZE];
864 982 unsigned char *digestInfo_buf = NULL, *abuf = NULL;
865 983 unsigned int md_len, md_len2, alen, digestInfo_len;
866 984 STACK_OF(X509_ATTRIBUTE) * sk;
867 985 unsigned char *sig = NULL;
868 986 unsigned int sig_len = 0;
869 987 X509_ALGOR *alg = NULL;
870 988 ASN1_OCTET_STRING *digest = NULL;
871 989 unsigned int alg_len = 0, digest_len = 0;
872 990 unsigned char *y = NULL, *alg_buf = NULL, *digest_buf = NULL;
873 991 X509 *cert = NULL;
874 992 ASN1_OBJECT *oid = NULL;
875 993
876 994 /* Solaris Kerberos */
877 995 if (signed_data == NULL)
878 996 return EINVAL;
879 997
880 998 if (signed_data_len == NULL)
881 999 return EINVAL;
882 1000
883 1001 /* start creating PKCS7 data */
884 1002 if ((p7 = PKCS7_new()) == NULL)
885 1003 goto cleanup;
886 1004 p7->type = OBJ_nid2obj(NID_pkcs7_signed);
887 1005
888 1006 if ((p7s = PKCS7_SIGNED_new()) == NULL)
889 1007 goto cleanup;
890 1008 p7->d.sign = p7s;
891 1009 if (!ASN1_INTEGER_set(p7s->version, 3))
892 1010 goto cleanup;
893 1011
894 1012 /* create a cert chain that has at least the signer's certificate */
|
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
895 1013 if ((cert_stack = sk_X509_new_null()) == NULL)
896 1014 goto cleanup;
897 1015
898 1016 cert = sk_X509_value(id_cryptoctx->my_certs, id_cryptoctx->cert_index);
899 1017 if (!include_certchain) {
900 1018 pkiDebug("only including signer's certificate\n");
901 1019 sk_X509_push(cert_stack, X509_dup(cert));
902 1020 } else {
903 1021 /* create a cert chain */
904 1022 X509_STORE *certstore = NULL;
905 - X509_STORE_CTX certctx;
1023 + X509_STORE_CTX *certctx;
906 1024 STACK_OF(X509) *certstack = NULL;
907 1025 char buf[DN_BUF_LEN];
908 1026 int i = 0, size = 0;
909 1027
910 1028 if ((certstore = X509_STORE_new()) == NULL)
911 1029 goto cleanup;
1030 + if ((certctx = X509_STORE_CTX_new()) == NULL)
1031 + goto cleanup;
912 1032 pkiDebug("building certificate chain\n");
913 - X509_STORE_set_verify_cb_func(certstore, openssl_callback);
914 - X509_STORE_CTX_init(&certctx, certstore, cert,
1033 + X509_STORE_set_verify_cb(certstore, openssl_callback);
1034 + X509_STORE_CTX_init(certctx, certstore, cert,
915 1035 id_cryptoctx->intermediateCAs);
916 - X509_STORE_CTX_trusted_stack(&certctx, id_cryptoctx->trustedCAs);
1036 + X509_STORE_CTX_set0_trusted_stack(certctx, id_cryptoctx->trustedCAs);
917 1037 /* Solaris Kerberos */
918 - if (X509_verify_cert(&certctx) <= 0) {
919 - pkiDebug("failed to create a certificate chain: %s\n",
920 - X509_verify_cert_error_string(X509_STORE_CTX_get_error(&certctx)));
921 - if (!sk_X509_num(id_cryptoctx->trustedCAs))
1038 + if (X509_verify_cert(certctx) <= 0) {
1039 + pkiDebug("failed to create a certificate chain: %s\n",
1040 + X509_verify_cert_error_string(X509_STORE_CTX_get_error(certctx)));
1041 + if (!sk_X509_num(id_cryptoctx->trustedCAs))
922 1042 pkiDebug("No trusted CAs found. Check your X509_anchors\n");
923 1043 goto cleanup;
924 1044 }
925 - certstack = X509_STORE_CTX_get1_chain(&certctx);
1045 + certstack = X509_STORE_CTX_get1_chain(certctx);
926 1046 size = sk_X509_num(certstack);
927 1047 pkiDebug("size of certificate chain = %d\n", size);
928 1048 for(i = 0; i < size - 1; i++) {
929 1049 X509 *x = sk_X509_value(certstack, i);
930 1050 X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf));
931 1051 pkiDebug("cert #%d: %s\n", i, buf);
932 1052 sk_X509_push(cert_stack, X509_dup(x));
933 1053 }
934 - X509_STORE_CTX_cleanup(&certctx);
1054 + X509_STORE_CTX_free(certctx);
935 1055 X509_STORE_free(certstore);
936 1056 sk_X509_pop_free(certstack, X509_free);
937 1057 }
938 1058 p7s->cert = cert_stack;
939 1059
940 1060 /* fill-in PKCS7_SIGNER_INFO */
941 1061 if ((p7si = PKCS7_SIGNER_INFO_new()) == NULL)
942 1062 goto cleanup;
943 1063 if (!ASN1_INTEGER_set(p7si->version, 1))
944 1064 goto cleanup;
945 1065 if (!X509_NAME_set(&p7si->issuer_and_serial->issuer,
946 1066 X509_get_issuer_name(cert)))
947 1067 goto cleanup;
948 1068 /* because ASN1_INTEGER_set is used to set a 'long' we will do
949 1069 * things the ugly way. */
950 - M_ASN1_INTEGER_free(p7si->issuer_and_serial->serial);
1070 + ASN1_INTEGER_free(p7si->issuer_and_serial->serial);
951 1071 if (!(p7si->issuer_and_serial->serial =
952 - M_ASN1_INTEGER_dup(X509_get_serialNumber(cert))))
1072 + ASN1_INTEGER_dup(X509_get_serialNumber(cert))))
953 1073 goto cleanup;
954 1074
955 1075 /* will not fill-out EVP_PKEY because it's on the smartcard */
956 1076
957 1077 /* Set digest algs */
958 1078 p7si->digest_alg->algorithm = OBJ_nid2obj(NID_sha1);
959 1079
960 1080 if (p7si->digest_alg->parameter != NULL)
961 1081 ASN1_TYPE_free(p7si->digest_alg->parameter);
962 1082 if ((p7si->digest_alg->parameter = ASN1_TYPE_new()) == NULL)
963 1083 goto cleanup;
964 1084 p7si->digest_alg->parameter->type = V_ASN1_NULL;
965 1085
966 1086 /* Set sig algs */
967 1087 if (p7si->digest_enc_alg->parameter != NULL)
968 1088 ASN1_TYPE_free(p7si->digest_enc_alg->parameter);
969 1089 p7si->digest_enc_alg->algorithm = OBJ_nid2obj(NID_sha1WithRSAEncryption);
970 1090 if (!(p7si->digest_enc_alg->parameter = ASN1_TYPE_new()))
971 1091 goto cleanup;
972 1092 p7si->digest_enc_alg->parameter->type = V_ASN1_NULL;
973 1093
974 1094 /* pick the correct oid for the eContentInfo */
975 1095 oid = pkinit_pkcs7type2oid(plg_cryptoctx, cms_msg_type);
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
976 1096 if (oid == NULL)
977 1097 goto cleanup;
978 1098
979 1099 if (cms_msg_type == CMS_SIGN_DRAFT9) {
980 1100 /* don't include signed attributes for pa-type 15 request */
981 1101 abuf = data;
982 1102 alen = data_len;
983 1103 } else {
984 1104 /* add signed attributes */
985 1105 /* compute sha1 digest over the EncapsulatedContentInfo */
986 - EVP_MD_CTX_init(&ctx);
987 - EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL);
988 - EVP_DigestUpdate(&ctx, data, data_len);
989 - md_tmp = EVP_MD_CTX_md(&ctx);
990 - EVP_DigestFinal_ex(&ctx, md_data, &md_len);
1106 + ctx = EVP_MD_CTX_new();
1107 + if (ctx == NULL)
1108 + goto cleanup2;
1109 + EVP_MD_CTX_init(ctx);
1110 + EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
1111 + EVP_DigestUpdate(ctx, data, data_len);
1112 + md_tmp = EVP_MD_CTX_md(ctx);
1113 + EVP_DigestFinal_ex(ctx, md_data, &md_len);
1114 + EVP_MD_CTX_free(ctx);
1115 + ctx = NULL;
991 1116
992 1117 /* create a message digest attr */
993 1118 digest_attr = ASN1_OCTET_STRING_new();
994 1119 ASN1_OCTET_STRING_set(digest_attr, md_data, (int)md_len);
995 1120 PKCS7_add_signed_attribute(p7si, NID_pkcs9_messageDigest,
996 1121 V_ASN1_OCTET_STRING, (char *) digest_attr);
997 1122
998 1123 /* create a content-type attr */
999 - PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType,
1124 + PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType,
1000 1125 V_ASN1_OBJECT, oid);
1001 1126
1002 1127 /* create the signature over signed attributes. get DER encoded value */
1003 1128 /* This is the place where smartcard signature needs to be calculated */
1004 1129 sk = p7si->auth_attr;
1005 1130 alen = ASN1_item_i2d((ASN1_VALUE *) sk, &abuf,
1006 1131 ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
1007 1132 if (abuf == NULL)
1008 1133 goto cleanup2;
1009 1134 }
1010 1135
1011 1136 #ifndef WITHOUT_PKCS11
1012 1137 /* Some tokens can only do RSAEncryption without sha1 hash */
1013 1138 /* to compute sha1WithRSAEncryption, encode the algorithm ID for the hash
1014 1139 * function and the hash value into an ASN.1 value of type DigestInfo
1015 1140 * DigestInfo::=SEQUENCE {
1016 1141 * digestAlgorithm AlgorithmIdentifier,
1017 1142 * digest OCTET STRING }
1018 1143 */
1019 - if (id_cryptoctx->pkcs11_method == 1 &&
1144 + if (id_cryptoctx->pkcs11_method == 1 &&
1020 1145 id_cryptoctx->mech == CKM_RSA_PKCS) {
1021 1146 pkiDebug("mech = CKM_RSA_PKCS\n");
1022 - EVP_MD_CTX_init(&ctx2);
1147 + ctx2 = EVP_MD_CTX_new();
1148 + if (ctx2 == NULL)
1149 + goto cleanup2;
1150 + EVP_MD_CTX_init(ctx2);
1023 1151 /* if this is not draft9 request, include digest signed attribute */
1024 - if (cms_msg_type != CMS_SIGN_DRAFT9)
1025 - EVP_DigestInit_ex(&ctx2, md_tmp, NULL);
1152 + if (cms_msg_type != CMS_SIGN_DRAFT9)
1153 + EVP_DigestInit_ex(ctx2, md_tmp, NULL);
1026 1154 else
1027 - EVP_DigestInit_ex(&ctx2, EVP_sha1(), NULL);
1028 - EVP_DigestUpdate(&ctx2, abuf, alen);
1029 - EVP_DigestFinal_ex(&ctx2, md_data2, &md_len2);
1155 + EVP_DigestInit_ex(ctx2, EVP_sha1(), NULL);
1156 + EVP_DigestUpdate(ctx2, abuf, alen);
1157 + EVP_DigestFinal_ex(ctx2, md_data2, &md_len2);
1158 + EVP_MD_CTX_free(ctx2);
1159 + ctx2 = NULL;
1030 1160
1031 1161 alg = X509_ALGOR_new();
1032 1162 if (alg == NULL)
1033 1163 goto cleanup2;
1034 1164 alg->algorithm = OBJ_nid2obj(NID_sha1);
1035 1165 alg->parameter = NULL;
1036 1166 alg_len = i2d_X509_ALGOR(alg, NULL);
1037 1167 alg_buf = (unsigned char *)malloc(alg_len);
1038 1168 if (alg_buf == NULL)
1039 1169 goto cleanup2;
1040 1170
1041 1171 digest = ASN1_OCTET_STRING_new();
1042 1172 if (digest == NULL)
1043 1173 goto cleanup2;
1044 1174 ASN1_OCTET_STRING_set(digest, md_data2, (int)md_len2);
1045 1175 digest_len = i2d_ASN1_OCTET_STRING(digest, NULL);
1046 1176 digest_buf = (unsigned char *)malloc(digest_len);
1047 1177 if (digest_buf == NULL)
1048 1178 goto cleanup2;
1049 1179
1050 1180 digestInfo_len = ASN1_object_size(1, (int)(alg_len + digest_len),
1051 1181 V_ASN1_SEQUENCE);
1052 1182 y = digestInfo_buf = (unsigned char *)malloc(digestInfo_len);
1053 1183 if (digestInfo_buf == NULL)
1054 1184 goto cleanup2;
1055 1185 ASN1_put_object(&y, 1, (int)(alg_len + digest_len), V_ASN1_SEQUENCE,
1056 1186 V_ASN1_UNIVERSAL);
1057 1187 i2d_X509_ALGOR(alg, &y);
1058 1188 i2d_ASN1_OCTET_STRING(digest, &y);
1059 1189 #ifdef DEBUG_SIG
1060 1190 pkiDebug("signing buffer\n");
1061 1191 print_buffer(digestInfo_buf, digestInfo_len);
1062 1192 print_buffer_bin(digestInfo_buf, digestInfo_len, "/tmp/pkcs7_tosign");
1063 1193 #endif
1064 1194 retval = pkinit_sign_data(context, id_cryptoctx, digestInfo_buf,
1065 1195 digestInfo_len, &sig, &sig_len);
1066 1196 } else
|
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
1067 1197 #endif
1068 1198 {
1069 1199 pkiDebug("mech = %s\n",
1070 1200 id_cryptoctx->pkcs11_method == 1 ? "CKM_SHA1_RSA_PKCS" : "FS");
1071 1201 retval = pkinit_sign_data(context, id_cryptoctx, abuf, alen,
1072 1202 &sig, &sig_len);
1073 1203 }
1074 1204 #ifdef DEBUG_SIG
1075 1205 print_buffer(sig, sig_len);
1076 1206 #endif
1077 - if (cms_msg_type != CMS_SIGN_DRAFT9)
1207 + if (cms_msg_type != CMS_SIGN_DRAFT9)
1078 1208 free(abuf);
1079 1209 if (retval)
1080 1210 goto cleanup2;
1081 1211
1082 1212 /* Add signature */
1083 1213 if (!ASN1_STRING_set(p7si->enc_digest, (unsigned char *) sig,
1084 1214 (int)sig_len)) {
1085 1215 unsigned long err = ERR_peek_error();
1086 1216 retval = KRB5KDC_ERR_PREAUTH_FAILED;
1087 1217 krb5_set_error_message(context, retval, "%s\n",
1088 1218 ERR_error_string(err, NULL));
1089 1219 pkiDebug("failed to add a signed digest attribute\n");
1090 1220 goto cleanup2;
1091 1221 }
1092 1222 /* adder signer_info to pkcs7 signed */
1093 1223 if (!PKCS7_add_signer(p7, p7si))
1094 1224 goto cleanup2;
1095 1225
1096 1226 /* start on adding data to the pkcs7 signed */
1097 1227 if ((inner_p7 = PKCS7_new()) == NULL)
1098 1228 goto cleanup2;
1099 1229 if ((pkinit_data = ASN1_TYPE_new()) == NULL)
1100 1230 goto cleanup2;
1101 1231 pkinit_data->type = V_ASN1_OCTET_STRING;
1102 1232 if ((pkinit_data->value.octet_string = ASN1_OCTET_STRING_new()) == NULL)
1103 1233 goto cleanup2;
1104 1234 if (!ASN1_OCTET_STRING_set(pkinit_data->value.octet_string, data,
1105 1235 (int)data_len)) {
1106 1236 unsigned long err = ERR_peek_error();
1107 1237 retval = KRB5KDC_ERR_PREAUTH_FAILED;
1108 1238 krb5_set_error_message(context, retval, "%s\n",
1109 1239 ERR_error_string(err, NULL));
1110 1240 pkiDebug("failed to add pkcs7 data\n");
1111 1241 goto cleanup2;
1112 1242 }
1113 1243
1114 1244 if (!PKCS7_set0_type_other(inner_p7, OBJ_obj2nid(oid), pkinit_data))
1115 1245 goto cleanup2;
1116 1246
1117 1247 if (p7s->contents != NULL)
1118 1248 PKCS7_free(p7s->contents);
1119 1249 p7s->contents = inner_p7;
1120 1250
1121 1251 *signed_data_len = i2d_PKCS7(p7, NULL);
1122 1252 if (!(*signed_data_len)) {
1123 1253 unsigned long err = ERR_peek_error();
1124 1254 retval = KRB5KDC_ERR_PREAUTH_FAILED;
1125 1255 krb5_set_error_message(context, retval, "%s\n",
1126 1256 ERR_error_string(err, NULL));
1127 1257 pkiDebug("failed to der encode pkcs7\n");
1128 1258 goto cleanup2;
1129 1259 }
1130 1260 if ((p = *signed_data =
1131 1261 (unsigned char *) malloc((size_t)*signed_data_len)) == NULL)
1132 1262 goto cleanup2;
1133 1263
1134 1264 /* DER encode PKCS7 data */
1135 1265 retval = i2d_PKCS7(p7, &p);
1136 1266 if (!retval) {
1137 1267 unsigned long err = ERR_peek_error();
1138 1268 retval = KRB5KDC_ERR_PREAUTH_FAILED;
1139 1269 krb5_set_error_message(context, retval, "%s\n",
1140 1270 ERR_error_string(err, NULL));
1141 1271 pkiDebug("failed to der encode pkcs7\n");
1142 1272 goto cleanup2;
1143 1273 }
1144 1274 retval = 0;
1145 1275
1146 1276 #ifdef DEBUG_ASN1
1147 1277 if (cms_msg_type == CMS_SIGN_CLIENT) {
1148 1278 print_buffer_bin(*signed_data, *signed_data_len,
1149 1279 "/tmp/client_pkcs7_signeddata");
1150 1280 } else {
1151 1281 if (cms_msg_type == CMS_SIGN_SERVER) {
|
↓ open down ↓ |
64 lines elided |
↑ open up ↑ |
1152 1282 print_buffer_bin(*signed_data, *signed_data_len,
1153 1283 "/tmp/kdc_pkcs7_signeddata");
1154 1284 } else {
1155 1285 print_buffer_bin(*signed_data, *signed_data_len,
1156 1286 "/tmp/draft9_pkcs7_signeddata");
1157 1287 }
1158 1288 }
1159 1289 #endif
1160 1290
1161 1291 cleanup2:
1162 - if (cms_msg_type != CMS_SIGN_DRAFT9)
1163 - EVP_MD_CTX_cleanup(&ctx);
1292 + if (cms_msg_type != CMS_SIGN_DRAFT9)
1293 + if (ctx != NULL)
1294 + EVP_MD_CTX_free(ctx);
1164 1295 #ifndef WITHOUT_PKCS11
1165 - if (id_cryptoctx->pkcs11_method == 1 &&
1296 + if (id_cryptoctx->pkcs11_method == 1 &&
1166 1297 id_cryptoctx->mech == CKM_RSA_PKCS) {
1167 - EVP_MD_CTX_cleanup(&ctx2);
1298 + if (ctx2 != NULL)
1299 + EVP_MD_CTX_free(ctx2);
1168 1300 if (digest_buf != NULL)
1169 1301 free(digest_buf);
1170 1302 if (digestInfo_buf != NULL)
1171 1303 free(digestInfo_buf);
1172 1304 if (alg_buf != NULL)
1173 1305 free(alg_buf);
1174 1306 if (digest != NULL)
1175 1307 ASN1_OCTET_STRING_free(digest);
1176 1308 }
1177 1309 #endif
1178 1310 if (alg != NULL)
1179 1311 X509_ALGOR_free(alg);
1180 1312 cleanup:
1181 - if (p7 != NULL)
1313 + if (p7 != NULL)
1182 1314 PKCS7_free(p7);
1183 1315 if (sig != NULL)
1184 1316 free(sig);
1185 1317
1186 1318 return retval;
1187 1319 }
1188 1320
1189 1321 krb5_error_code
1190 1322 cms_signeddata_verify(krb5_context context,
1191 1323 pkinit_plg_crypto_context plgctx,
1192 1324 pkinit_req_crypto_context reqctx,
1193 1325 pkinit_identity_crypto_context idctx,
1194 1326 int cms_msg_type,
1195 1327 int require_crl_checking,
1196 1328 unsigned char *signed_data,
1197 1329 unsigned int signed_data_len,
1198 1330 unsigned char **data,
1199 1331 unsigned int *data_len,
1200 1332 unsigned char **authz_data,
1201 1333 unsigned int *authz_data_len)
1202 1334 {
|
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
1203 1335 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
1204 1336 PKCS7 *p7 = NULL;
1205 1337 BIO *out = NULL;
1206 1338 int flags = PKCS7_NOVERIFY, i = 0;
1207 1339 unsigned int vflags = 0, size = 0;
1208 1340 const unsigned char *p = signed_data;
1209 1341 STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
1210 1342 PKCS7_SIGNER_INFO *si = NULL;
1211 1343 X509 *x = NULL;
1212 1344 X509_STORE *store = NULL;
1213 - X509_STORE_CTX cert_ctx;
1345 + X509_STORE_CTX *cert_ctx;
1214 1346 STACK_OF(X509) *intermediateCAs = NULL;
1215 1347 STACK_OF(X509_CRL) *revoked = NULL;
1216 1348 STACK_OF(X509) *verified_chain = NULL;
1217 1349 ASN1_OBJECT *oid = NULL;
1218 1350 krb5_external_principal_identifier **krb5_verified_chain = NULL;
1219 1351 krb5_data *authz = NULL;
1220 1352 char buf[DN_BUF_LEN];
1221 1353
1222 1354 #ifdef DEBUG_ASN1
1223 1355 print_buffer_bin(signed_data, signed_data_len,
1224 1356 "/tmp/client_received_pkcs7_signeddata");
1225 1357 #endif
1226 1358
1227 1359 /* Do this early enough to create the shadow OID for pkcs7-data if needed */
1228 1360 oid = pkinit_pkcs7type2oid(plgctx, cms_msg_type);
1229 1361 if (oid == NULL)
1230 1362 goto cleanup;
1231 1363
1232 1364 /* decode received PKCS7 message */
1233 1365 if ((p7 = d2i_PKCS7(NULL, &p, (int)signed_data_len)) == NULL) {
1234 1366 unsigned long err = ERR_peek_error();
1235 1367 krb5_set_error_message(context, retval, "%s\n",
1236 1368 ERR_error_string(err, NULL));
1237 1369 pkiDebug("%s: failed to decode message: %s\n",
1238 1370 __FUNCTION__, ERR_error_string(err, NULL));
1239 1371 goto cleanup;
1240 1372 }
1241 1373
1242 1374 /* verify that the received message is PKCS7 SignedData message */
1243 1375 if (OBJ_obj2nid(p7->type) != NID_pkcs7_signed) {
1244 1376 pkiDebug("Expected id-signedData PKCS7 msg (received type = %d)\n",
1245 1377 OBJ_obj2nid(p7->type));
1246 1378 krb5_set_error_message(context, retval, "wrong oid\n");
|
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
1247 1379 goto cleanup;
1248 1380 }
1249 1381
1250 1382 /* setup to verify X509 certificate used to sign PKCS7 message */
1251 1383 if (!(store = X509_STORE_new()))
1252 1384 goto cleanup;
1253 1385
1254 1386 /* check if we are inforcing CRL checking */
1255 1387 vflags = X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
1256 1388 if (require_crl_checking)
1257 - X509_STORE_set_verify_cb_func(store, openssl_callback);
1389 + X509_STORE_set_verify_cb(store, openssl_callback);
1258 1390 else
1259 - X509_STORE_set_verify_cb_func(store, openssl_callback_ignore_crls);
1391 + X509_STORE_set_verify_cb(store, openssl_callback_ignore_crls);
1260 1392 X509_STORE_set_flags(store, vflags);
1261 1393
1262 1394 /* get the signer's information from the PKCS7 message */
1263 1395 if ((si_sk = PKCS7_get_signer_info(p7)) == NULL)
1264 1396 goto cleanup;
1265 1397 if ((si = sk_PKCS7_SIGNER_INFO_value(si_sk, 0)) == NULL)
1266 1398 goto cleanup;
1267 1399 if ((x = PKCS7_cert_from_signer_info(p7, si)) == NULL)
1268 1400 goto cleanup;
1269 1401
1270 1402 /* create available CRL information (get local CRLs and include CRLs
1271 1403 * received in the PKCS7 message
1272 1404 */
1273 1405 if (idctx->revoked == NULL)
1274 1406 revoked = p7->d.sign->crl;
1275 1407 else if (p7->d.sign->crl == NULL)
1276 1408 revoked = idctx->revoked;
1277 1409 else {
1278 1410 size = sk_X509_CRL_num(idctx->revoked);
1279 1411 revoked = sk_X509_CRL_new_null();
1280 1412 for (i = 0; i < size; i++)
1281 1413 sk_X509_CRL_push(revoked, sk_X509_CRL_value(idctx->revoked, i));
1282 1414 size = sk_X509_CRL_num(p7->d.sign->crl);
1283 1415 for (i = 0; i < size; i++)
1284 1416 sk_X509_CRL_push(revoked, sk_X509_CRL_value(p7->d.sign->crl, i));
1285 1417 }
1286 1418
1287 1419 /* create available intermediate CAs chains (get local intermediateCAs and
1288 1420 * include the CA chain received in the PKCS7 message
1289 1421 */
1290 1422 if (idctx->intermediateCAs == NULL)
1291 1423 intermediateCAs = p7->d.sign->cert;
1292 1424 else if (p7->d.sign->cert == NULL)
1293 1425 intermediateCAs = idctx->intermediateCAs;
1294 1426 else {
1295 1427 size = sk_X509_num(idctx->intermediateCAs);
1296 1428 intermediateCAs = sk_X509_new_null();
1297 1429 for (i = 0; i < size; i++) {
1298 1430 sk_X509_push(intermediateCAs,
1299 1431 sk_X509_value(idctx->intermediateCAs, i));
|
↓ open down ↓ |
30 lines elided |
↑ open up ↑ |
1300 1432 }
1301 1433 size = sk_X509_num(p7->d.sign->cert);
1302 1434 for (i = 0; i < size; i++) {
1303 1435 sk_X509_push(intermediateCAs, sk_X509_value(p7->d.sign->cert, i));
1304 1436 }
1305 1437 }
1306 1438
1307 1439 /* initialize x509 context with the received certificate and
1308 1440 * trusted and intermediate CA chains and CRLs
1309 1441 */
1310 - if (!X509_STORE_CTX_init(&cert_ctx, store, x, intermediateCAs))
1442 + if ((cert_ctx = X509_STORE_CTX_new()) == NULL)
1311 1443 goto cleanup;
1444 + if (!X509_STORE_CTX_init(cert_ctx, store, x, intermediateCAs))
1445 + goto cleanup;
1312 1446
1313 - X509_STORE_CTX_set0_crls(&cert_ctx, revoked);
1447 + X509_STORE_CTX_set0_crls(cert_ctx, revoked);
1314 1448
1315 1449 /* add trusted CAs certificates for cert verification */
1316 1450 if (idctx->trustedCAs != NULL)
1317 - X509_STORE_CTX_trusted_stack(&cert_ctx, idctx->trustedCAs);
1451 + X509_STORE_CTX_set0_trusted_stack(cert_ctx, idctx->trustedCAs);
1318 1452 else {
1319 1453 pkiDebug("unable to find any trusted CAs\n");
1320 1454 goto cleanup;
1321 1455 }
1322 1456 #ifdef DEBUG_CERTCHAIN
1323 1457 if (intermediateCAs != NULL) {
1324 1458 size = sk_X509_num(intermediateCAs);
1325 1459 pkiDebug("untrusted cert chain of size %d\n", size);
1326 1460 for (i = 0; i < size; i++) {
1327 1461 X509_NAME_oneline(X509_get_subject_name(
1328 1462 sk_X509_value(intermediateCAs, i)), buf, sizeof(buf));
1329 1463 pkiDebug("cert #%d: %s\n", i, buf);
1330 1464 }
1331 1465 }
1332 1466 if (idctx->trustedCAs != NULL) {
1333 1467 size = sk_X509_num(idctx->trustedCAs);
1334 1468 pkiDebug("trusted cert chain of size %d\n", size);
1335 1469 for (i = 0; i < size; i++) {
1336 1470 X509_NAME_oneline(X509_get_subject_name(
1337 1471 sk_X509_value(idctx->trustedCAs, i)), buf, sizeof(buf));
1338 1472 pkiDebug("cert #%d: %s\n", i, buf);
1339 1473 }
1340 1474 }
1341 1475 if (revoked != NULL) {
|
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
1342 1476 size = sk_X509_CRL_num(revoked);
1343 1477 pkiDebug("CRL chain of size %d\n", size);
1344 1478 for (i = 0; i < size; i++) {
1345 1479 X509_CRL *crl = sk_X509_CRL_value(revoked, i);
1346 1480 X509_NAME_oneline(X509_CRL_get_issuer(crl), buf, sizeof(buf));
1347 1481 pkiDebug("crls by CA #%d: %s\n", i , buf);
1348 1482 }
1349 1483 }
1350 1484 #endif
1351 1485
1352 - i = X509_verify_cert(&cert_ctx);
1486 + i = X509_verify_cert(cert_ctx);
1353 1487 if (i <= 0) {
1354 - int j = X509_STORE_CTX_get_error(&cert_ctx);
1488 + int j = X509_STORE_CTX_get_error(cert_ctx);
1355 1489
1356 - reqctx->received_cert = X509_dup(cert_ctx.current_cert);
1490 + reqctx->received_cert = X509_dup(
1491 + X509_STORE_CTX_get_current_cert(cert_ctx));
1357 1492 switch(j) {
1358 1493 case X509_V_ERR_CERT_REVOKED:
1359 1494 retval = KRB5KDC_ERR_REVOKED_CERTIFICATE;
1360 1495 break;
1361 1496 case X509_V_ERR_UNABLE_TO_GET_CRL:
1362 1497 retval = KRB5KDC_ERR_REVOCATION_STATUS_UNKNOWN;
1363 1498 break;
1364 1499 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
1365 1500 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1366 1501 retval = KRB5KDC_ERR_CANT_VERIFY_CERTIFICATE;
1367 1502 break;
1368 1503 default:
1369 1504 retval = KRB5KDC_ERR_INVALID_CERTIFICATE;
1370 1505 }
1371 1506 X509_NAME_oneline(X509_get_subject_name(
1372 1507 reqctx->received_cert), buf, sizeof(buf));
1373 1508 pkiDebug("problem with cert DN = %s (error=%d) %s\n", buf, j,
1374 1509 X509_verify_cert_error_string(j));
1375 1510 krb5_set_error_message(context, retval, "%s\n",
1376 1511 X509_verify_cert_error_string(j));
1377 1512 #ifdef DEBUG_CERTCHAIN
|
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
1378 1513 size = sk_X509_num(p7->d.sign->cert);
1379 1514 pkiDebug("received cert chain of size %d\n", size);
1380 1515 for (j = 0; j < size; j++) {
1381 1516 X509 *tmp_cert = sk_X509_value(p7->d.sign->cert, j);
1382 1517 X509_NAME_oneline(X509_get_subject_name(tmp_cert), buf, sizeof(buf));
1383 1518 pkiDebug("cert #%d: %s\n", j, buf);
1384 1519 }
1385 1520 #endif
1386 1521 } else {
1387 1522 /* retrieve verified certificate chain */
1388 - if (cms_msg_type == CMS_SIGN_CLIENT || cms_msg_type == CMS_SIGN_DRAFT9)
1389 - verified_chain = X509_STORE_CTX_get1_chain(&cert_ctx);
1523 + if (cms_msg_type == CMS_SIGN_CLIENT || cms_msg_type == CMS_SIGN_DRAFT9)
1524 + verified_chain = X509_STORE_CTX_get1_chain(cert_ctx);
1390 1525 }
1391 - X509_STORE_CTX_cleanup(&cert_ctx);
1526 + X509_STORE_CTX_free(cert_ctx);
1392 1527 if (i <= 0)
1393 1528 goto cleanup;
1394 1529
1395 1530 out = BIO_new(BIO_s_mem());
1396 1531 if (cms_msg_type == CMS_SIGN_DRAFT9)
1397 1532 flags |= PKCS7_NOATTR;
1398 1533 if (PKCS7_verify(p7, NULL, store, NULL, out, flags)) {
1399 1534 int valid_oid = 0;
1400 1535
1401 - if (!OBJ_cmp(p7->d.sign->contents->type, oid))
1536 + if (!OBJ_cmp(p7->d.sign->contents->type, oid))
1402 1537 valid_oid = 1;
1403 1538 else if (cms_msg_type == CMS_SIGN_DRAFT9) {
1404 1539 /*
1405 1540 * Various implementations of the pa-type 15 request use
1406 1541 * different OIDS. We check that the returned object
1407 1542 * has any of the acceptable OIDs
1408 1543 */
1409 1544 ASN1_OBJECT *client_oid = NULL, *server_oid = NULL, *rsa_oid = NULL;
1410 1545 client_oid = pkinit_pkcs7type2oid(plgctx, CMS_SIGN_CLIENT);
1411 1546 server_oid = pkinit_pkcs7type2oid(plgctx, CMS_SIGN_SERVER);
1412 1547 rsa_oid = pkinit_pkcs7type2oid(plgctx, CMS_ENVEL_SERVER);
1413 1548 if (!OBJ_cmp(p7->d.sign->contents->type, client_oid) ||
1414 1549 !OBJ_cmp(p7->d.sign->contents->type, server_oid) ||
1415 1550 !OBJ_cmp(p7->d.sign->contents->type, rsa_oid))
1416 1551 valid_oid = 1;
1417 1552 }
1418 1553
1419 - if (valid_oid)
1554 + if (valid_oid)
1420 1555 pkiDebug("PKCS7 Verification successful\n");
1421 1556 else {
1557 + const ASN1_OBJECT *etype = p7->d.sign->contents->type;
1422 1558 pkiDebug("wrong oid in eContentType\n");
1423 - print_buffer((unsigned char *)p7->d.sign->contents->type->data,
1424 - (unsigned int)p7->d.sign->contents->type->length);
1559 + print_buffer((unsigned char *)OBJ_get0_data(etype),
1560 + OBJ_length(etype));
1425 1561 retval = KRB5KDC_ERR_PREAUTH_FAILED;
1426 1562 krb5_set_error_message(context, retval, "wrong oid\n");
1427 1563 goto cleanup;
1428 1564 }
1429 1565 }
1430 1566 else {
1431 1567 unsigned long err = ERR_peek_error();
1432 1568 switch(ERR_GET_REASON(err)) {
1433 1569 case PKCS7_R_DIGEST_FAILURE:
1434 1570 retval = KRB5KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED;
1435 1571 break;
1436 1572 case PKCS7_R_SIGNATURE_FAILURE:
1437 1573 default:
1438 1574 retval = KRB5KDC_ERR_INVALID_SIG;
1439 1575 }
1440 1576 pkiDebug("PKCS7 Verification failure\n");
1441 1577 krb5_set_error_message(context, retval, "%s\n",
1442 1578 ERR_error_string(err, NULL));
1443 1579 goto cleanup;
1444 1580 }
1445 1581
1446 1582 /* transfer the data from PKCS7 message into return buffer */
1447 1583 for (size = 0;;) {
1448 1584 if ((*data = realloc(*data, size + 1024 * 10)) == NULL)
1449 1585 goto cleanup;
1450 1586 i = BIO_read(out, &((*data)[size]), 1024 * 10);
1451 1587 if (i <= 0)
1452 1588 break;
|
↓ open down ↓ |
18 lines elided |
↑ open up ↑ |
1453 1589 else
1454 1590 size += i;
1455 1591 }
1456 1592 *data_len = size;
1457 1593
1458 1594 reqctx->received_cert = X509_dup(x);
1459 1595
1460 1596 /* generate authorization data */
1461 1597 if (cms_msg_type == CMS_SIGN_CLIENT || cms_msg_type == CMS_SIGN_DRAFT9) {
1462 1598
1463 - if (authz_data == NULL || authz_data_len == NULL)
1599 + if (authz_data == NULL || authz_data_len == NULL)
1464 1600 goto out;
1465 1601
1466 1602 *authz_data = NULL;
1467 - retval = create_identifiers_from_stack(verified_chain,
1603 + retval = create_identifiers_from_stack(verified_chain,
1468 1604 &krb5_verified_chain);
1469 1605 if (retval) {
1470 1606 pkiDebug("create_identifiers_from_stack failed\n");
1471 1607 goto cleanup;
1472 1608 }
1473 1609
1474 1610 retval = k5int_encode_krb5_td_trusted_certifiers((const krb5_external_principal_identifier **)krb5_verified_chain, &authz);
1475 1611 if (retval) {
1476 1612 pkiDebug("encode_krb5_td_trusted_certifiers failed\n");
1477 1613 goto cleanup;
1478 1614 }
1479 1615 #ifdef DEBUG_ASN1
1480 1616 print_buffer_bin((unsigned char *)authz->data, authz->length,
1481 1617 "/tmp/kdc_ad_initial_verified_cas");
1482 1618 #endif
1483 1619 *authz_data = (unsigned char *)malloc(authz->length);
1484 1620 if (*authz_data == NULL) {
1485 1621 retval = ENOMEM;
1486 1622 goto cleanup;
1487 1623 }
1488 1624 (void) memcpy(*authz_data, authz->data, authz->length);
1489 1625 *authz_data_len = authz->length;
1490 1626 }
1491 1627 out:
1492 1628 retval = 0;
1493 1629
1494 1630 cleanup:
1495 1631 if (out != NULL)
1496 1632 BIO_free(out);
1497 1633 if (store != NULL)
1498 1634 X509_STORE_free(store);
1499 1635 if (p7 != NULL) {
1500 1636 if (idctx->intermediateCAs != NULL && p7->d.sign->cert)
1501 1637 sk_X509_free(intermediateCAs);
1502 1638 if (idctx->revoked != NULL && p7->d.sign->crl)
1503 1639 sk_X509_CRL_free(revoked);
1504 1640 PKCS7_free(p7);
1505 1641 }
1506 1642 if (verified_chain != NULL)
1507 1643 sk_X509_pop_free(verified_chain, X509_free);
1508 1644 if (krb5_verified_chain != NULL)
1509 1645 free_krb5_external_principal_identifier(&krb5_verified_chain);
1510 1646 if (authz != NULL)
1511 1647 krb5_free_data(context, authz);
1512 1648
1513 1649 return retval;
1514 1650 }
1515 1651
1516 1652 krb5_error_code
1517 1653 cms_envelopeddata_create(krb5_context context,
1518 1654 pkinit_plg_crypto_context plgctx,
1519 1655 pkinit_req_crypto_context reqctx,
1520 1656 pkinit_identity_crypto_context idctx,
1521 1657 krb5_preauthtype pa_type,
1522 1658 int include_certchain,
1523 1659 unsigned char *key_pack,
1524 1660 unsigned int key_pack_len,
1525 1661 unsigned char **out,
1526 1662 unsigned int *out_len)
1527 1663 {
1528 1664
1529 1665 /* Solaris Kerberos */
1530 1666 krb5_error_code retval = KRB5KRB_ERR_GENERIC;
1531 1667 PKCS7 *p7 = NULL;
1532 1668 BIO *in = NULL;
1533 1669 unsigned char *p = NULL, *signed_data = NULL, *enc_data = NULL;
1534 1670 int signed_data_len = 0, enc_data_len = 0, flags = PKCS7_BINARY;
1535 1671 STACK_OF(X509) *encerts = NULL;
1536 1672 const EVP_CIPHER *cipher = NULL;
1537 1673 int cms_msg_type;
1538 1674
1539 1675 /* create the PKCS7 SignedData portion of the PKCS7 EnvelopedData */
1540 1676 switch ((int)pa_type) {
1541 1677 case KRB5_PADATA_PK_AS_REQ_OLD:
1542 1678 case KRB5_PADATA_PK_AS_REP_OLD:
1543 1679 cms_msg_type = CMS_SIGN_DRAFT9;
1544 1680 break;
1545 1681 case KRB5_PADATA_PK_AS_REQ:
1546 1682 cms_msg_type = CMS_ENVEL_SERVER;
1547 1683 break;
1548 1684 default:
1549 1685 /* Solaris Kerberos */
1550 1686 retval = EINVAL;
1551 1687 goto cleanup;
1552 1688 }
1553 1689
1554 1690 retval = cms_signeddata_create(context, plgctx, reqctx, idctx,
1555 1691 cms_msg_type, include_certchain, key_pack, key_pack_len,
1556 1692 &signed_data, (unsigned int *)&signed_data_len);
1557 1693 if (retval) {
1558 1694 pkiDebug("failed to create pkcs7 signed data\n");
1559 1695 goto cleanup;
1560 1696 }
1561 1697
1562 1698 /* check we have client's certificate */
1563 1699 if (reqctx->received_cert == NULL) {
1564 1700 retval = KRB5KDC_ERR_PREAUTH_FAILED;
1565 1701 goto cleanup;
1566 1702 }
1567 1703 encerts = sk_X509_new_null();
1568 1704 sk_X509_push(encerts, reqctx->received_cert);
1569 1705
1570 1706 cipher = EVP_des_ede3_cbc();
1571 1707 in = BIO_new(BIO_s_mem());
1572 1708 switch (pa_type) {
1573 1709 case KRB5_PADATA_PK_AS_REQ:
1574 1710 prepare_enc_data(signed_data, signed_data_len, &enc_data,
1575 1711 &enc_data_len);
1576 1712 retval = BIO_write(in, enc_data, enc_data_len);
1577 1713 if (retval != enc_data_len) {
1578 1714 pkiDebug("BIO_write only wrote %d\n", retval);
1579 1715 goto cleanup;
1580 1716 }
1581 1717 break;
1582 1718 case KRB5_PADATA_PK_AS_REP_OLD:
1583 1719 case KRB5_PADATA_PK_AS_REQ_OLD:
1584 1720 retval = BIO_write(in, signed_data, signed_data_len);
1585 1721 if (retval != signed_data_len) {
1586 1722 pkiDebug("BIO_write only wrote %d\n", retval);
1587 1723 /* Solaris Kerberos */
1588 1724 retval = KRB5KRB_ERR_GENERIC;
1589 1725 goto cleanup;
1590 1726 }
1591 1727 break;
1592 1728 default:
1593 1729 retval = -1;
1594 1730 goto cleanup;
|
↓ open down ↓ |
117 lines elided |
↑ open up ↑ |
1595 1731 }
1596 1732
1597 1733 p7 = PKCS7_encrypt(encerts, in, cipher, flags);
1598 1734 if (p7 == NULL) {
1599 1735 pkiDebug("failed to encrypt PKCS7 object\n");
1600 1736 retval = -1;
1601 1737 goto cleanup;
1602 1738 }
1603 1739 switch (pa_type) {
1604 1740 case KRB5_PADATA_PK_AS_REQ:
1605 - p7->d.enveloped->enc_data->content_type =
1741 + p7->d.enveloped->enc_data->content_type =
1606 1742 OBJ_nid2obj(NID_pkcs7_signed);
1607 1743 break;
1608 1744 case KRB5_PADATA_PK_AS_REP_OLD:
1609 1745 case KRB5_PADATA_PK_AS_REQ_OLD:
1610 - p7->d.enveloped->enc_data->content_type =
1746 + p7->d.enveloped->enc_data->content_type =
1611 1747 OBJ_nid2obj(NID_pkcs7_data);
1612 1748 break;
1613 - }
1749 + }
1614 1750
1615 1751 *out_len = i2d_PKCS7(p7, NULL);
1616 1752 if (!*out_len || (p = *out = (unsigned char *)malloc(*out_len)) == NULL) {
1617 1753 retval = ENOMEM;
1618 1754 goto cleanup;
1619 1755 }
1620 1756 retval = i2d_PKCS7(p7, &p);
1621 1757 if (!retval) {
1622 1758 pkiDebug("unable to write pkcs7 object\n");
1623 1759 goto cleanup;
1624 1760 }
1625 1761 retval = 0;
1626 1762
1627 1763 #ifdef DEBUG_ASN1
1628 1764 print_buffer_bin(*out, *out_len, "/tmp/kdc_enveloped_data");
1629 1765 #endif
1630 1766
1631 1767 cleanup:
1632 1768 if (p7 != NULL)
1633 1769 PKCS7_free(p7);
1634 1770 if (in != NULL)
1635 1771 BIO_free(in);
1636 1772 if (signed_data != NULL)
1637 1773 free(signed_data);
1638 1774 if (enc_data != NULL)
1639 1775 free(enc_data);
1640 1776 if (encerts != NULL)
1641 1777 sk_X509_free(encerts);
1642 1778
1643 1779 return retval;
1644 1780 }
1645 1781
1646 1782 krb5_error_code
1647 1783 cms_envelopeddata_verify(krb5_context context,
1648 1784 pkinit_plg_crypto_context plg_cryptoctx,
1649 1785 pkinit_req_crypto_context req_cryptoctx,
1650 1786 pkinit_identity_crypto_context id_cryptoctx,
1651 1787 krb5_preauthtype pa_type,
1652 1788 int require_crl_checking,
1653 1789 unsigned char *enveloped_data,
1654 1790 unsigned int enveloped_data_len,
1655 1791 unsigned char **data,
1656 1792 unsigned int *data_len)
1657 1793 {
1658 1794 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
1659 1795 PKCS7 *p7 = NULL;
1660 1796 BIO *out = NULL;
1661 1797 int i = 0;
1662 1798 unsigned int size = 0;
1663 1799 const unsigned char *p = enveloped_data;
1664 1800 unsigned int tmp_buf_len = 0, tmp_buf2_len = 0, vfy_buf_len = 0;
1665 1801 unsigned char *tmp_buf = NULL, *tmp_buf2 = NULL, *vfy_buf = NULL;
1666 1802 int msg_type = 0;
1667 1803
1668 1804 #ifdef DEBUG_ASN1
1669 1805 print_buffer_bin(enveloped_data, enveloped_data_len,
1670 1806 "/tmp/client_envelopeddata");
1671 1807 #endif
1672 1808 /* decode received PKCS7 message */
1673 1809 if ((p7 = d2i_PKCS7(NULL, &p, (int)enveloped_data_len)) == NULL) {
1674 1810 unsigned long err = ERR_peek_error();
1675 1811 pkiDebug("failed to decode pkcs7\n");
1676 1812 krb5_set_error_message(context, retval, "%s\n",
1677 1813 ERR_error_string(err, NULL));
1678 1814 goto cleanup;
1679 1815 }
1680 1816
1681 1817 /* verify that the received message is PKCS7 EnvelopedData message */
1682 1818 if (OBJ_obj2nid(p7->type) != NID_pkcs7_enveloped) {
1683 1819 pkiDebug("Expected id-enveloped PKCS7 msg (received type = %d)\n",
1684 1820 OBJ_obj2nid(p7->type));
1685 1821 krb5_set_error_message(context, retval, "wrong oid\n");
1686 1822 goto cleanup;
1687 1823 }
1688 1824
1689 1825 /* decrypt received PKCS7 message */
1690 1826 out = BIO_new(BIO_s_mem());
1691 1827 if (pkcs7_decrypt(context, id_cryptoctx, p7, out)) {
1692 1828 pkiDebug("PKCS7 decryption successful\n");
1693 1829 } else {
1694 1830 unsigned long err = ERR_peek_error();
1695 1831 if (err != 0)
1696 1832 krb5_set_error_message(context, retval, "%s\n",
1697 1833 ERR_error_string(err, NULL));
1698 1834 pkiDebug("PKCS7 decryption failed\n");
1699 1835 goto cleanup;
1700 1836 }
1701 1837
1702 1838 /* transfer the decoded PKCS7 SignedData message into a separate buffer */
1703 1839 for (;;) {
1704 1840 if ((tmp_buf = realloc(tmp_buf, size + 1024 * 10)) == NULL)
1705 1841 goto cleanup;
1706 1842 i = BIO_read(out, &(tmp_buf[size]), 1024 * 10);
1707 1843 if (i <= 0)
1708 1844 break;
1709 1845 else
1710 1846 size += i;
1711 1847 }
1712 1848 tmp_buf_len = size;
1713 1849
1714 1850 #ifdef DEBUG_ASN1
1715 1851 print_buffer_bin(tmp_buf, tmp_buf_len, "/tmp/client_enc_keypack");
1716 1852 #endif
1717 1853 /* verify PKCS7 SignedData message */
1718 1854 switch (pa_type) {
1719 1855 case KRB5_PADATA_PK_AS_REP:
1720 1856 msg_type = CMS_ENVEL_SERVER;
1721 1857
1722 1858 break;
1723 1859 case KRB5_PADATA_PK_AS_REP_OLD:
1724 1860 msg_type = CMS_SIGN_DRAFT9;
1725 1861 break;
1726 1862 default:
1727 1863 pkiDebug("%s: unrecognized pa_type = %d\n", __FUNCTION__, pa_type);
1728 1864 retval = KRB5KDC_ERR_PREAUTH_FAILED;
1729 1865 goto cleanup;
1730 1866 }
1731 1867 /*
1732 1868 * If this is the RFC style, wrap the signed data to make
1733 1869 * decoding easier in the verify routine.
1734 1870 * For draft9-compatible, we don't do anything because it
1735 1871 * is already wrapped.
1736 1872 */
1737 1873 #ifdef LONGHORN_BETA_COMPAT
1738 1874 /*
1739 1875 * The Longhorn server returns the expected RFC-style data, but
1740 1876 * it is missing the sequence tag and length, so it requires
1741 1877 * special processing when wrapping.
1742 1878 * This will hopefully be fixed before the final release and
1743 1879 * this can all be removed.
1744 1880 */
1745 1881 if (msg_type == CMS_ENVEL_SERVER || longhorn == 1) {
1746 1882 retval = wrap_signeddata(tmp_buf, tmp_buf_len,
1747 1883 &tmp_buf2, &tmp_buf2_len, longhorn);
1748 1884 if (retval) {
1749 1885 pkiDebug("failed to encode signeddata\n");
1750 1886 goto cleanup;
1751 1887 }
1752 1888 vfy_buf = tmp_buf2;
1753 1889 vfy_buf_len = tmp_buf2_len;
1754 1890
1755 1891 } else {
1756 1892 vfy_buf = tmp_buf;
1757 1893 vfy_buf_len = tmp_buf_len;
1758 1894 }
1759 1895 #else
1760 1896 if (msg_type == CMS_ENVEL_SERVER) {
1761 1897 retval = wrap_signeddata(tmp_buf, tmp_buf_len,
1762 1898 &tmp_buf2, &tmp_buf2_len);
1763 1899 if (retval) {
1764 1900 pkiDebug("failed to encode signeddata\n");
1765 1901 goto cleanup;
1766 1902 }
1767 1903 vfy_buf = tmp_buf2;
1768 1904 vfy_buf_len = tmp_buf2_len;
1769 1905
1770 1906 } else {
1771 1907 vfy_buf = tmp_buf;
1772 1908 vfy_buf_len = tmp_buf_len;
1773 1909 }
1774 1910 #endif
1775 1911
1776 1912 #ifdef DEBUG_ASN1
1777 1913 print_buffer_bin(vfy_buf, vfy_buf_len, "/tmp/client_enc_keypack2");
1778 1914 #endif
1779 1915
1780 1916 retval = cms_signeddata_verify(context, plg_cryptoctx, req_cryptoctx,
1781 1917 id_cryptoctx, msg_type,
1782 1918 require_crl_checking,
1783 1919 vfy_buf, vfy_buf_len,
1784 1920 data, data_len, NULL, NULL);
1785 1921
1786 1922 if (!retval)
1787 1923 pkiDebug("PKCS7 Verification Success\n");
1788 1924 else {
1789 1925 pkiDebug("PKCS7 Verification Failure\n");
1790 1926 goto cleanup;
1791 1927 }
1792 1928
1793 1929 retval = 0;
1794 1930
1795 1931 cleanup:
1796 1932
1797 1933 if (p7 != NULL)
1798 1934 PKCS7_free(p7);
1799 1935 if (out != NULL)
1800 1936 BIO_free(out);
1801 1937 if (tmp_buf != NULL)
1802 1938 free(tmp_buf);
1803 1939 if (tmp_buf2 != NULL)
1804 1940 free(tmp_buf2);
1805 1941
1806 1942 return retval;
1807 1943 }
1808 1944
1809 1945 /* ARGSUSED */
1810 1946 static krb5_error_code
1811 1947 crypto_retrieve_X509_sans(krb5_context context,
1812 1948 pkinit_plg_crypto_context plgctx,
1813 1949 pkinit_req_crypto_context reqctx,
1814 1950 X509 *cert,
1815 1951 krb5_principal **princs_ret,
1816 1952 krb5_principal **upn_ret,
1817 1953 unsigned char ***dns_ret)
1818 1954 {
1819 1955 krb5_error_code retval = EINVAL;
1820 1956 char buf[DN_BUF_LEN];
1821 1957 int p = 0, u = 0, d = 0;
1822 1958 krb5_principal *princs = NULL;
1823 1959 krb5_principal *upns = NULL;
1824 1960 unsigned char **dnss = NULL;
1825 1961 int i, num_found = 0;
1826 1962
1827 1963 if (princs_ret == NULL && upn_ret == NULL && dns_ret == NULL) {
1828 1964 pkiDebug("%s: nowhere to return any values!\n", __FUNCTION__);
1829 1965 return retval;
1830 1966 }
1831 1967
1832 1968 if (cert == NULL) {
1833 1969 pkiDebug("%s: no certificate!\n", __FUNCTION__);
1834 1970 return retval;
1835 1971 }
1836 1972
1837 1973 X509_NAME_oneline(X509_get_subject_name(cert),
1838 1974 buf, sizeof(buf));
1839 1975 pkiDebug("%s: looking for SANs in cert = %s\n", __FUNCTION__, buf);
1840 1976
1841 1977 if ((i = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1)) >= 0) {
1842 1978 X509_EXTENSION *ext = NULL;
1843 1979 GENERAL_NAMES *ialt = NULL;
1844 1980 GENERAL_NAME *gen = NULL;
1845 1981 int ret = 0;
1846 1982 unsigned int num_sans = 0;
1847 1983
1848 1984 if (!(ext = X509_get_ext(cert, i)) || !(ialt = X509V3_EXT_d2i(ext))) {
1849 1985 pkiDebug("%s: found no subject alt name extensions\n",
1850 1986 __FUNCTION__);
1851 1987 goto cleanup;
1852 1988 }
1853 1989 num_sans = sk_GENERAL_NAME_num(ialt);
1854 1990
1855 1991 pkiDebug("%s: found %d subject alt name extension(s)\n",
1856 1992 __FUNCTION__, num_sans);
1857 1993
1858 1994 /* OK, we're likely returning something. Allocate return values */
1859 1995 if (princs_ret != NULL) {
1860 1996 princs = calloc(num_sans + 1, sizeof(krb5_principal));
1861 1997 if (princs == NULL) {
1862 1998 retval = ENOMEM;
1863 1999 goto cleanup;
1864 2000 }
1865 2001 }
1866 2002 if (upn_ret != NULL) {
1867 2003 upns = calloc(num_sans + 1, sizeof(krb5_principal));
1868 2004 if (upns == NULL) {
1869 2005 retval = ENOMEM;
1870 2006 goto cleanup;
1871 2007 }
1872 2008 }
1873 2009 if (dns_ret != NULL) {
1874 2010 dnss = calloc(num_sans + 1, sizeof(*dnss));
1875 2011 if (dnss == NULL) {
1876 2012 retval = ENOMEM;
1877 2013 goto cleanup;
1878 2014 }
1879 2015 }
1880 2016
1881 2017 for (i = 0; i < num_sans; i++) {
1882 2018 krb5_data name = { 0, 0, NULL };
1883 2019
1884 2020 gen = sk_GENERAL_NAME_value(ialt, i);
1885 2021 switch (gen->type) {
1886 2022 case GEN_OTHERNAME:
1887 2023 name.length = gen->d.otherName->value->value.sequence->length;
1888 2024 name.data = (char *)gen->d.otherName->value->value.sequence->data;
1889 2025 if (princs != NULL
1890 2026 && OBJ_cmp(plgctx->id_pkinit_san,
1891 2027 gen->d.otherName->type_id) == 0) {
1892 2028 #ifdef DEBUG_ASN1
1893 2029 print_buffer_bin((unsigned char *)name.data, name.length,
1894 2030 "/tmp/pkinit_san");
1895 2031 #endif
1896 2032 ret = k5int_decode_krb5_principal_name(&name, &princs[p]);
1897 2033 if (ret) {
1898 2034 pkiDebug("%s: failed decoding pkinit san value\n",
1899 2035 __FUNCTION__);
1900 2036 } else {
1901 2037 p++;
1902 2038 num_found++;
1903 2039 }
1904 2040 } else if (upns != NULL
1905 2041 && OBJ_cmp(plgctx->id_ms_san_upn,
1906 2042 gen->d.otherName->type_id) == 0) {
1907 2043 ret = krb5_parse_name(context, name.data, &upns[u]);
1908 2044 if (ret) {
1909 2045 pkiDebug("%s: failed parsing ms-upn san value\n",
1910 2046 __FUNCTION__);
1911 2047 } else {
1912 2048 u++;
1913 2049 num_found++;
1914 2050 }
1915 2051 } else {
1916 2052 pkiDebug("%s: unrecognized othername oid in SAN\n",
|
↓ open down ↓ |
293 lines elided |
↑ open up ↑ |
1917 2053 __FUNCTION__);
1918 2054 continue;
1919 2055 }
1920 2056
1921 2057 break;
1922 2058 case GEN_DNS:
1923 2059 if (dnss != NULL) {
1924 2060 pkiDebug("%s: found dns name = %s\n",
1925 2061 __FUNCTION__, gen->d.dNSName->data);
1926 2062 dnss[d] = (unsigned char *)
1927 - strdup((char *)gen->d.dNSName->data);
2063 + strdup((char *)gen->d.dNSName->data);
1928 2064 if (dnss[d] == NULL) {
1929 2065 pkiDebug("%s: failed to duplicate dns name\n",
1930 2066 __FUNCTION__);
1931 2067 } else {
1932 2068 d++;
1933 2069 num_found++;
1934 2070 }
1935 2071 }
1936 2072 break;
1937 2073 default:
1938 2074 pkiDebug("%s: SAN type = %d expecting %d\n",
1939 2075 __FUNCTION__, gen->type, GEN_OTHERNAME);
1940 2076 }
1941 2077 }
1942 2078 sk_GENERAL_NAME_pop_free(ialt, GENERAL_NAME_free);
1943 2079 }
1944 2080
1945 2081 retval = 0;
1946 2082 if (princs)
1947 2083 *princs_ret = princs;
1948 2084 if (upns)
1949 2085 *upn_ret = upns;
1950 2086 if (dnss)
1951 2087 *dns_ret = dnss;
1952 2088
1953 2089 cleanup:
1954 2090 if (retval) {
1955 2091 if (princs != NULL) {
1956 2092 for (i = 0; princs[i] != NULL; i++)
1957 2093 krb5_free_principal(context, princs[i]);
1958 2094 free(princs);
1959 2095 }
1960 2096 if (upns != NULL) {
1961 2097 for (i = 0; upns[i] != NULL; i++)
1962 2098 krb5_free_principal(context, upns[i]);
1963 2099 free(upns);
1964 2100 }
1965 2101 if (dnss != NULL) {
1966 2102 for (i = 0; dnss[i] != NULL; i++)
1967 2103 free(dnss[i]);
1968 2104 free(dnss);
1969 2105 }
1970 2106 }
1971 2107 return retval;
1972 2108 }
1973 2109
1974 2110 /* ARGSUSED */
1975 2111 krb5_error_code
1976 2112 crypto_retrieve_cert_sans(krb5_context context,
1977 2113 pkinit_plg_crypto_context plgctx,
1978 2114 pkinit_req_crypto_context reqctx,
1979 2115 pkinit_identity_crypto_context idctx,
1980 2116 krb5_principal **princs_ret,
1981 2117 krb5_principal **upn_ret,
1982 2118 unsigned char ***dns_ret)
1983 2119 {
1984 2120 krb5_error_code retval = EINVAL;
1985 2121
1986 2122 if (reqctx->received_cert == NULL) {
1987 2123 pkiDebug("%s: No certificate!\n", __FUNCTION__);
1988 2124 return retval;
1989 2125 }
1990 2126
1991 2127 return crypto_retrieve_X509_sans(context, plgctx, reqctx,
1992 2128 reqctx->received_cert, princs_ret,
1993 2129 upn_ret, dns_ret);
1994 2130 }
1995 2131
1996 2132 /* ARGSUSED */
1997 2133 krb5_error_code
1998 2134 crypto_check_cert_eku(krb5_context context,
1999 2135 pkinit_plg_crypto_context plgctx,
2000 2136 pkinit_req_crypto_context reqctx,
2001 2137 pkinit_identity_crypto_context idctx,
2002 2138 int checking_kdc_cert,
2003 2139 int allow_secondary_usage,
2004 2140 int *valid_eku)
2005 2141 {
2006 2142 char buf[DN_BUF_LEN];
2007 2143 int found_eku = 0;
2008 2144 krb5_error_code retval = EINVAL;
2009 2145 int i;
2010 2146
2011 2147 /* Solaris Kerberos */
2012 2148 if (valid_eku == NULL)
2013 2149 return retval;
2014 2150
2015 2151 *valid_eku = 0;
2016 2152 if (reqctx->received_cert == NULL)
2017 2153 goto cleanup;
2018 2154
2019 2155 X509_NAME_oneline(X509_get_subject_name(reqctx->received_cert),
2020 2156 buf, sizeof(buf));
2021 2157 pkiDebug("%s: looking for EKUs in cert = %s\n", __FUNCTION__, buf);
2022 2158
2023 2159 if ((i = X509_get_ext_by_NID(reqctx->received_cert,
2024 2160 NID_ext_key_usage, -1)) >= 0) {
2025 2161 EXTENDED_KEY_USAGE *extusage;
2026 2162
2027 2163 extusage = X509_get_ext_d2i(reqctx->received_cert, NID_ext_key_usage,
2028 2164 NULL, NULL);
2029 2165 if (extusage) {
2030 2166 pkiDebug("%s: found eku info in the cert\n", __FUNCTION__);
2031 2167 for (i = 0; found_eku == 0 && i < sk_ASN1_OBJECT_num(extusage); i++) {
2032 2168 ASN1_OBJECT *tmp_oid;
2033 2169
2034 2170 tmp_oid = sk_ASN1_OBJECT_value(extusage, i);
2035 2171 pkiDebug("%s: checking eku %d of %d, allow_secondary = %d\n",
2036 2172 __FUNCTION__, i+1, sk_ASN1_OBJECT_num(extusage),
2037 2173 allow_secondary_usage);
2038 2174 if (checking_kdc_cert) {
2039 2175 if ((OBJ_cmp(tmp_oid, plgctx->id_pkinit_KPKdc) == 0)
2040 2176 || (allow_secondary_usage
2041 2177 && OBJ_cmp(tmp_oid, plgctx->id_kp_serverAuth) == 0))
2042 2178 found_eku = 1;
2043 2179 } else {
2044 2180 if ((OBJ_cmp(tmp_oid, plgctx->id_pkinit_KPClientAuth) == 0)
2045 2181 || (allow_secondary_usage
2046 2182 && OBJ_cmp(tmp_oid, plgctx->id_ms_kp_sc_logon) == 0))
2047 2183 found_eku = 1;
2048 2184 }
2049 2185 }
2050 2186 }
2051 2187 EXTENDED_KEY_USAGE_free(extusage);
2052 2188
2053 2189 if (found_eku) {
2054 2190 ASN1_BIT_STRING *usage = NULL;
2055 2191 pkiDebug("%s: found acceptable EKU, checking for digitalSignature\n", __FUNCTION__);
2056 2192
2057 2193 /* check that digitalSignature KeyUsage is present */
2058 2194 if ((usage = X509_get_ext_d2i(reqctx->received_cert,
2059 2195 NID_key_usage, NULL, NULL))) {
2060 2196
2061 2197 if (!ku_reject(reqctx->received_cert,
2062 2198 X509v3_KU_DIGITAL_SIGNATURE)) {
2063 2199 pkiDebug("%s: found digitalSignature KU\n",
2064 2200 __FUNCTION__);
2065 2201 *valid_eku = 1;
2066 2202 } else
2067 2203 pkiDebug("%s: didn't find digitalSignature KU\n",
2068 2204 __FUNCTION__);
2069 2205 }
2070 2206 ASN1_BIT_STRING_free(usage);
2071 2207 }
2072 2208 }
2073 2209 retval = 0;
2074 2210 cleanup:
2075 2211 pkiDebug("%s: returning retval %d, valid_eku %d\n",
2076 2212 __FUNCTION__, retval, *valid_eku);
2077 2213 return retval;
2078 2214 }
2079 2215
2080 2216 krb5_error_code
2081 2217 pkinit_octetstring2key(krb5_context context,
2082 2218 krb5_enctype etype,
2083 2219 unsigned char *key,
2084 2220 unsigned int dh_key_len,
2085 2221 krb5_keyblock * key_block)
2086 2222 {
2087 2223 krb5_error_code retval;
2088 2224 unsigned char *buf = NULL;
2089 2225 unsigned char md[SHA_DIGEST_LENGTH];
2090 2226 unsigned char counter;
2091 2227 size_t keybytes, keylength, offset;
2092 2228 krb5_data random_data;
2093 2229
2094 2230
2095 2231 if ((buf = (unsigned char *) malloc(dh_key_len)) == NULL) {
2096 2232 retval = ENOMEM;
2097 2233 goto cleanup;
2098 2234 }
2099 2235 (void) memset(buf, 0, dh_key_len);
2100 2236
2101 2237 counter = 0;
2102 2238 offset = 0;
2103 2239 do {
2104 2240 SHA_CTX c;
2105 2241
2106 2242 SHA1_Init(&c);
2107 2243 SHA1_Update(&c, &counter, 1);
2108 2244 SHA1_Update(&c, key, dh_key_len);
2109 2245 SHA1_Final(md, &c);
2110 2246
2111 2247 if (dh_key_len - offset < sizeof(md))
2112 2248 (void) memcpy(buf + offset, md, dh_key_len - offset);
2113 2249 else
2114 2250 (void) memcpy(buf + offset, md, sizeof(md));
2115 2251
2116 2252 offset += sizeof(md);
2117 2253 counter++;
2118 2254 } while (offset < dh_key_len);
2119 2255
2120 2256 /* Solaris Kerberos */
2121 2257 key_block->magic = KV5M_KEYBLOCK;
2122 2258 key_block->enctype = etype;
2123 2259
2124 2260 retval = krb5_c_keylengths(context, etype, &keybytes, &keylength);
2125 2261 if (retval)
2126 2262 goto cleanup;
2127 2263
2128 2264 key_block->length = keylength;
2129 2265 key_block->contents = calloc(keylength, sizeof(unsigned char *));
2130 2266 if (key_block->contents == NULL) {
2131 2267 retval = ENOMEM;
2132 2268 goto cleanup;
2133 2269 }
2134 2270
2135 2271 random_data.length = keybytes;
2136 2272 random_data.data = (char *)buf;
2137 2273
2138 2274 retval = krb5_c_random_to_key(context, etype, &random_data, key_block);
2139 2275
2140 2276 cleanup:
2141 2277 if (buf != NULL)
2142 2278 free(buf);
2143 2279 if (retval && key_block->contents != NULL && key_block->length != 0) {
2144 2280 (void) memset(key_block->contents, 0, key_block->length);
2145 2281 key_block->length = 0;
2146 2282 }
2147 2283
2148 2284 return retval;
2149 2285 }
2150 2286
2151 2287 /* ARGSUSED */
2152 2288 krb5_error_code
2153 2289 client_create_dh(krb5_context context,
2154 2290 pkinit_plg_crypto_context plg_cryptoctx,
2155 2291 pkinit_req_crypto_context cryptoctx,
|
↓ open down ↓ |
218 lines elided |
↑ open up ↑ |
2156 2292 pkinit_identity_crypto_context id_cryptoctx,
2157 2293 int dh_size,
2158 2294 unsigned char **dh_params,
2159 2295 unsigned int *dh_params_len,
2160 2296 unsigned char **dh_pubkey,
2161 2297 unsigned int *dh_pubkey_len)
2162 2298 {
2163 2299 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
2164 2300 unsigned char *buf = NULL;
2165 2301 int dh_err = 0;
2166 - ASN1_INTEGER *pub_key = NULL;
2302 + ASN1_INTEGER *asn_pub_key = NULL;
2303 + BIGNUM *p, *g, *q;
2304 + const BIGNUM *pub_key;
2167 2305
2168 2306 if (cryptoctx->dh == NULL) {
2169 2307 if ((cryptoctx->dh = DH_new()) == NULL)
2170 2308 goto cleanup;
2171 - if ((cryptoctx->dh->g = BN_new()) == NULL ||
2172 - (cryptoctx->dh->q = BN_new()) == NULL)
2309 + if ((g = BN_new()) == NULL || (q = BN_new()) == NULL)
2173 2310 goto cleanup;
2174 2311
2175 2312 switch(dh_size) {
2176 2313 case 1024:
2177 2314 pkiDebug("client uses 1024 DH keys\n");
2178 - cryptoctx->dh->p = get_rfc2409_prime_1024(NULL);
2315 + cryptoctx->dh = make_dhprime(pkinit_1024_dhprime,
2316 + sizeof(pkinit_1024_dhprime));
2179 2317 break;
2180 2318 case 2048:
2181 2319 pkiDebug("client uses 2048 DH keys\n");
2182 - cryptoctx->dh->p = BN_bin2bn(pkinit_2048_dhprime,
2183 - sizeof(pkinit_2048_dhprime), NULL);
2320 + cryptoctx->dh = make_dhprime(pkinit_2048_dhprime,
2321 + sizeof(pkinit_2048_dhprime));
2184 2322 break;
2185 2323 case 4096:
2186 2324 pkiDebug("client uses 4096 DH keys\n");
2187 - cryptoctx->dh->p = BN_bin2bn(pkinit_4096_dhprime,
2188 - sizeof(pkinit_4096_dhprime), NULL);
2325 + cryptoctx->dh = make_dhprime(pkinit_4096_dhprime,
2326 + sizeof(pkinit_4096_dhprime));
2189 2327 break;
2190 - default:
2191 - goto cleanup;
2192 2328 }
2193 -
2194 - BN_set_word((cryptoctx->dh->g), DH_GENERATOR_2);
2195 - BN_rshift1(cryptoctx->dh->q, cryptoctx->dh->p);
2329 + if (cryptoctx->dh == NULL)
2330 + goto cleanup;
2196 2331 }
2197 2332
2198 2333 DH_generate_key(cryptoctx->dh);
2334 + DH_get0_key(cryptoctx->dh, &pub_key, NULL);
2335 +
2199 2336 /* Solaris Kerberos */
2200 2337 #ifdef DEBUG
2201 2338 DH_check(cryptoctx->dh, &dh_err);
2202 2339 if (dh_err != 0) {
2203 2340 pkiDebug("Warning: dh_check failed with %d\n", dh_err);
2204 2341 if (dh_err & DH_CHECK_P_NOT_PRIME)
2205 2342 pkiDebug("p value is not prime\n");
2206 2343 if (dh_err & DH_CHECK_P_NOT_SAFE_PRIME)
2207 2344 pkiDebug("p value is not a safe prime\n");
2208 2345 if (dh_err & DH_UNABLE_TO_CHECK_GENERATOR)
2209 2346 pkiDebug("unable to check the generator value\n");
2210 2347 if (dh_err & DH_NOT_SUITABLE_GENERATOR)
2211 2348 pkiDebug("the g value is not a generator\n");
2212 2349 }
2213 2350 #endif
2214 2351 #ifdef DEBUG_DH
2215 2352 print_dh(cryptoctx->dh, "client's DH params\n");
2216 - print_pubkey(cryptoctx->dh->pub_key, "client's pub_key=");
2353 + print_pubkey(pub_key, "client's pub_key=");
2217 2354 #endif
2218 2355
2219 - DH_check_pub_key(cryptoctx->dh, cryptoctx->dh->pub_key, &dh_err);
2356 + DH_check_pub_key(cryptoctx->dh, pub_key, &dh_err);
2220 2357 if (dh_err != 0) {
2221 2358 pkiDebug("dh_check_pub_key failed with %d\n", dh_err);
2222 2359 goto cleanup;
2223 2360 }
2224 2361
2225 2362 /* pack DHparams */
2226 2363 /* aglo: usually we could just call i2d_DHparams to encode DH params
2227 2364 * however, PKINIT requires RFC3279 encoding and openssl does pkcs#3.
2228 2365 */
2229 - retval = pkinit_encode_dh_params(cryptoctx->dh->p, cryptoctx->dh->g,
2230 - cryptoctx->dh->q, dh_params, dh_params_len);
2366 + DH_get0_pqg(cryptoctx->dh, (const BIGNUM **)&p, (const BIGNUM **)&q,
2367 + (const BIGNUM **)&g);
2368 + retval = pkinit_encode_dh_params(p, g, q, dh_params, dh_params_len);
2231 2369 if (retval)
2232 2370 goto cleanup;
2233 2371
2234 2372 /* pack DH public key */
2235 2373 /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this
2236 2374 * encoding shall be used as the contents (the value) of the
2237 2375 * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo
2238 2376 * data element
2239 2377 */
2240 - if ((pub_key = BN_to_ASN1_INTEGER(cryptoctx->dh->pub_key, NULL)) == NULL)
2378 + if ((asn_pub_key = BN_to_ASN1_INTEGER(pub_key, NULL)) == NULL)
2241 2379 goto cleanup;
2242 - *dh_pubkey_len = i2d_ASN1_INTEGER(pub_key, NULL);
2380 + *dh_pubkey_len = i2d_ASN1_INTEGER(asn_pub_key, NULL);
2243 2381 if ((buf = *dh_pubkey = (unsigned char *)
2244 - malloc((size_t) *dh_pubkey_len)) == NULL) {
2245 - retval = ENOMEM;
2246 - goto cleanup;
2382 + malloc((size_t) *dh_pubkey_len)) == NULL) {
2383 + retval = ENOMEM;
2384 + goto cleanup;
2247 2385 }
2248 - i2d_ASN1_INTEGER(pub_key, &buf);
2386 + i2d_ASN1_INTEGER(asn_pub_key, &buf);
2249 2387
2250 - if (pub_key != NULL)
2251 - ASN1_INTEGER_free(pub_key);
2388 + if (asn_pub_key != NULL)
2389 + ASN1_INTEGER_free(asn_pub_key);
2252 2390
2253 2391 retval = 0;
2254 2392 return retval;
2255 2393
2256 2394 cleanup:
2257 2395 if (cryptoctx->dh != NULL)
2258 2396 DH_free(cryptoctx->dh);
2259 2397 cryptoctx->dh = NULL;
2260 2398 if (*dh_params != NULL)
2261 2399 free(*dh_params);
2262 2400 *dh_params = NULL;
2263 2401 if (*dh_pubkey != NULL)
2264 2402 free(*dh_pubkey);
2265 2403 *dh_pubkey = NULL;
2266 - if (pub_key != NULL)
2267 - ASN1_INTEGER_free(pub_key);
2404 + if (asn_pub_key != NULL)
2405 + ASN1_INTEGER_free(asn_pub_key);
2268 2406
2269 2407 return retval;
2270 2408 }
2271 2409
2272 2410 /* ARGSUSED */
2273 2411 krb5_error_code
2274 2412 client_process_dh(krb5_context context,
2275 2413 pkinit_plg_crypto_context plg_cryptoctx,
2276 2414 pkinit_req_crypto_context cryptoctx,
2277 2415 pkinit_identity_crypto_context id_cryptoctx,
2278 2416 unsigned char *subjectPublicKey_data,
2279 2417 unsigned int subjectPublicKey_length,
2280 2418 unsigned char **client_key,
2281 2419 unsigned int *client_key_len)
2282 2420 {
2283 2421 /* Solaris Kerberos */
2284 2422 krb5_error_code retval = KRB5_PREAUTH_FAILED;
2285 2423 BIGNUM *server_pub_key = NULL;
2286 2424 ASN1_INTEGER *pub_key = NULL;
2287 2425 const unsigned char *p = NULL;
2288 2426 unsigned char *data = NULL;
2289 2427 long data_len;
2290 2428
2291 2429 /* decode subjectPublicKey (retrieve INTEGER from OCTET_STRING) */
2292 2430
2293 2431 if (der_decode_data(subjectPublicKey_data, (long)subjectPublicKey_length,
2294 2432 &data, &data_len) != 0) {
2295 2433 pkiDebug("failed to decode subjectPublicKey\n");
2296 2434 /* Solaris Kerberos */
2297 2435 retval = KRB5_PREAUTH_FAILED;
2298 2436 goto cleanup;
2299 2437 }
2300 2438
2301 2439 *client_key_len = DH_size(cryptoctx->dh);
2302 2440 if ((*client_key = (unsigned char *)
2303 2441 malloc((size_t) *client_key_len)) == NULL) {
2304 2442 retval = ENOMEM;
2305 2443 goto cleanup;
2306 2444 }
2307 2445 p = data;
2308 2446 if ((pub_key = d2i_ASN1_INTEGER(NULL, &p, data_len)) == NULL)
2309 2447 goto cleanup;
2310 2448 if ((server_pub_key = ASN1_INTEGER_to_BN(pub_key, NULL)) == NULL)
2311 2449 goto cleanup;
2312 2450
2313 2451 DH_compute_key(*client_key, server_pub_key, cryptoctx->dh);
2314 2452 #ifdef DEBUG_DH
2315 2453 print_pubkey(server_pub_key, "server's pub_key=");
2316 2454 pkiDebug("client secret key (%d)= ", *client_key_len);
2317 2455 print_buffer(*client_key, *client_key_len);
2318 2456 #endif
2319 2457
2320 2458 retval = 0;
2321 2459 if (server_pub_key != NULL)
2322 2460 BN_free(server_pub_key);
2323 2461 if (pub_key != NULL)
2324 2462 ASN1_INTEGER_free(pub_key);
2325 2463 if (data != NULL)
2326 2464 free (data);
2327 2465
2328 2466 return retval;
2329 2467
2330 2468 cleanup:
2331 2469 if (*client_key != NULL)
2332 2470 free(*client_key);
2333 2471 *client_key = NULL;
2334 2472 if (pub_key != NULL)
2335 2473 ASN1_INTEGER_free(pub_key);
2336 2474 if (data != NULL)
2337 2475 free (data);
2338 2476
2339 2477 return retval;
2340 2478 }
2341 2479
2342 2480 /* ARGSUSED */
2343 2481 krb5_error_code
2344 2482 server_check_dh(krb5_context context,
|
↓ open down ↓ |
67 lines elided |
↑ open up ↑ |
2345 2483 pkinit_plg_crypto_context cryptoctx,
2346 2484 pkinit_req_crypto_context req_cryptoctx,
2347 2485 pkinit_identity_crypto_context id_cryptoctx,
2348 2486 krb5_octet_data *dh_params,
2349 2487 int minbits)
2350 2488 {
2351 2489 DH *dh = NULL;
2352 2490 unsigned char *tmp = NULL;
2353 2491 int dh_prime_bits;
2354 2492 krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
2493 + const BIGNUM *p, *g, *q, *p2;
2355 2494
2356 2495 tmp = dh_params->data;
2357 2496 dh = DH_new();
2358 2497 dh = pkinit_decode_dh_params(&dh, &tmp, dh_params->length);
2359 2498 if (dh == NULL) {
2360 2499 pkiDebug("failed to decode dhparams\n");
2361 2500 goto cleanup;
2362 2501 }
2363 2502
2503 + DH_get0_pqg(dh, &p, &q, &g);
2504 +
2364 2505 /* KDC SHOULD check to see if the key parameters satisfy its policy */
2365 - dh_prime_bits = BN_num_bits(dh->p);
2506 + dh_prime_bits = BN_num_bits(p);
2366 2507 if (minbits && dh_prime_bits < minbits) {
2367 2508 pkiDebug("client sent dh params with %d bits, we require %d\n",
2368 2509 dh_prime_bits, minbits);
2369 2510 goto cleanup;
2370 2511 }
2371 2512
2372 2513 /* check dhparams is group 2 */
2373 - if (pkinit_check_dh_params(cryptoctx->dh_1024->p,
2374 - dh->p, dh->g, dh->q) == 0) {
2514 + DH_get0_pqg(cryptoctx->dh_1024, &p2, NULL, NULL);
2515 + if (pkinit_check_dh_params(p2, p, g, q) == 0) {
2375 2516 retval = 0;
2376 2517 goto cleanup;
2377 2518 }
2378 2519
2379 2520 /* check dhparams is group 14 */
2380 - if (pkinit_check_dh_params(cryptoctx->dh_2048->p,
2381 - dh->p, dh->g, dh->q) == 0) {
2521 + DH_get0_pqg(cryptoctx->dh_2048, &p2, NULL, NULL);
2522 + if (pkinit_check_dh_params(p2, p, g, q) == 0) {
2382 2523 retval = 0;
2383 2524 goto cleanup;
2384 2525 }
2385 2526
2386 2527 /* check dhparams is group 16 */
2387 - if (pkinit_check_dh_params(cryptoctx->dh_4096->p,
2388 - dh->p, dh->g, dh->q) == 0) {
2528 + DH_get0_pqg(cryptoctx->dh_4096, &p2, NULL, NULL);
2529 + if (pkinit_check_dh_params(p2, p, g, q) == 0) {
2389 2530 retval = 0;
2390 2531 goto cleanup;
2391 2532 }
2392 2533
2393 2534 cleanup:
2394 2535 if (retval == 0)
2395 2536 req_cryptoctx->dh = dh;
2396 2537 else
2397 2538 DH_free(dh);
2398 2539
2399 2540 return retval;
2400 2541 }
2401 2542
2402 2543 /* kdc's dh function */
2403 2544 /* ARGSUSED */
2404 2545 krb5_error_code
2405 2546 server_process_dh(krb5_context context,
2406 2547 pkinit_plg_crypto_context plg_cryptoctx,
2407 2548 pkinit_req_crypto_context cryptoctx,
2408 2549 pkinit_identity_crypto_context id_cryptoctx,
|
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
2409 2550 unsigned char *data,
2410 2551 unsigned int data_len,
2411 2552 unsigned char **dh_pubkey,
2412 2553 unsigned int *dh_pubkey_len,
2413 2554 unsigned char **server_key,
2414 2555 unsigned int *server_key_len)
2415 2556 {
2416 2557 /* Solaris Kerberos */
2417 2558 krb5_error_code retval = KRB5KRB_ERR_GENERIC;
2418 2559 DH *dh = NULL, *dh_server = NULL;
2419 - unsigned char *p = NULL;
2420 - ASN1_INTEGER *pub_key = NULL;
2560 + const BIGNUM *p, *g, *q, *s_pub_key;
2561 + BIGNUM *pub_key;
2562 + unsigned char *s = NULL;
2563 + ASN1_INTEGER *asn_pub_key = NULL;
2421 2564
2422 2565 /* get client's received DH parameters that we saved in server_check_dh */
2423 2566 dh = cryptoctx->dh;
2424 2567
2425 2568 dh_server = DH_new();
2426 2569 if (dh_server == NULL)
2427 2570 goto cleanup;
2428 - dh_server->p = BN_dup(dh->p);
2429 - dh_server->g = BN_dup(dh->g);
2430 - dh_server->q = BN_dup(dh->q);
2571 + DH_get0_pqg(dh, &p, &g, &q);
2572 + DH_set0_pqg(dh_server, BN_dup(p), BN_dup(g), BN_dup(q));
2431 2573
2432 2574 /* decode client's public key */
2433 - p = data;
2434 - pub_key = d2i_ASN1_INTEGER(NULL, (const unsigned char **)&p, (int)data_len);
2575 + s = data;
2576 + asn_pub_key = d2i_ASN1_INTEGER(NULL,
2577 + (const unsigned char **)&s, (int)data_len);
2578 + if (asn_pub_key == NULL)
2579 + goto cleanup;
2580 + pub_key = ASN1_INTEGER_to_BN(asn_pub_key, NULL);
2435 2581 if (pub_key == NULL)
2436 2582 goto cleanup;
2437 - dh->pub_key = ASN1_INTEGER_to_BN(pub_key, NULL);
2438 - if (dh->pub_key == NULL)
2439 - goto cleanup;
2440 - ASN1_INTEGER_free(pub_key);
2583 + DH_set0_key(dh, pub_key, NULL);
2584 + ASN1_INTEGER_free(asn_pub_key);
2441 2585
2442 2586 if (!DH_generate_key(dh_server))
2443 2587 goto cleanup;
2444 2588
2445 2589 /* generate DH session key */
2446 2590 *server_key_len = DH_size(dh_server);
2447 - if ((*server_key = (unsigned char *) malloc((size_t)*server_key_len)) == NULL)
2448 - goto cleanup;
2449 - DH_compute_key(*server_key, dh->pub_key, dh_server);
2591 + if ((*server_key = (unsigned char *) malloc((size_t)*server_key_len))
2592 + == NULL)
2593 + goto cleanup;
2594 + DH_compute_key(*server_key, pub_key, dh_server);
2595 + DH_get0_key(dh_server, &s_pub_key, NULL);
2450 2596
2451 2597 #ifdef DEBUG_DH
2452 2598 print_dh(dh_server, "client&server's DH params\n");
2453 - print_pubkey(dh->pub_key, "client's pub_key=");
2454 - print_pubkey(dh_server->pub_key, "server's pub_key=");
2599 + print_pubkey(pub_key, "client's pub_key=");
2600 + print_pubkey(s_pub_key, "server's pub_key=");
2455 2601 pkiDebug("server secret key=");
2456 2602 print_buffer(*server_key, *server_key_len);
2457 2603 #endif
2458 2604
2459 2605 /* KDC reply */
2460 2606 /* pack DH public key */
2461 2607 /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this
2462 2608 * encoding shall be used as the contents (the value) of the
2463 2609 * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo
2464 2610 * data element
2465 2611 */
2466 - if ((pub_key = BN_to_ASN1_INTEGER(dh_server->pub_key, NULL)) == NULL)
2612 + if ((asn_pub_key = BN_to_ASN1_INTEGER(s_pub_key, NULL)) == NULL)
2467 2613 goto cleanup;
2468 - *dh_pubkey_len = i2d_ASN1_INTEGER(pub_key, NULL);
2469 - if ((p = *dh_pubkey = (unsigned char *) malloc((size_t)*dh_pubkey_len)) == NULL)
2470 - goto cleanup;
2471 - i2d_ASN1_INTEGER(pub_key, &p);
2472 - if (pub_key != NULL)
2473 - ASN1_INTEGER_free(pub_key);
2614 + *dh_pubkey_len = i2d_ASN1_INTEGER(asn_pub_key, NULL);
2615 + if ((s = *dh_pubkey = (unsigned char *) malloc((size_t)*dh_pubkey_len))
2616 + == NULL)
2617 + goto cleanup;
2618 + i2d_ASN1_INTEGER(asn_pub_key, &s);
2619 + if (asn_pub_key != NULL)
2620 + ASN1_INTEGER_free(asn_pub_key);
2474 2621
2475 2622 retval = 0;
2476 2623
2477 2624 if (dh_server != NULL)
2478 2625 DH_free(dh_server);
2479 2626 return retval;
2480 2627
2481 2628 cleanup:
2482 2629 if (dh_server != NULL)
2483 2630 DH_free(dh_server);
2484 2631 if (*dh_pubkey != NULL)
2485 2632 free(*dh_pubkey);
2486 2633 if (*server_key != NULL)
2487 2634 free(*server_key);
2488 2635
2489 2636 return retval;
2490 2637 }
2491 2638
2492 2639 /*
2493 2640 * Solaris Kerberos:
2494 2641 * Add locking around did_init to make it MT-safe.
2495 2642 */
2496 2643 static krb5_error_code
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
2497 2644 openssl_init()
2498 2645 {
2499 2646 krb5_error_code ret = 0;
2500 2647 static int did_init = 0;
2501 2648 static k5_mutex_t init_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
2502 2649
2503 2650 ret = k5_mutex_lock(&init_mutex);
2504 2651 if (ret == 0) {
2505 2652 if (!did_init) {
2506 2653 /* initialize openssl routines */
2654 +#if OPENSSL_VERSION_NUMBER < 0x10100000L
2655 + /*
2656 + * As of version 1.1.0, OpenSSL will automatically allocate
2657 + * resources as-needed.
2658 + */
2507 2659 CRYPTO_malloc_init();
2508 2660 ERR_load_crypto_strings();
2509 2661 OpenSSL_add_all_algorithms();
2662 +#endif
2510 2663 did_init++;
2511 2664 }
2512 2665 k5_mutex_unlock(&init_mutex);
2513 2666 }
2514 2667 return (ret);
2515 2668 }
2516 2669
2517 2670 static krb5_error_code
2518 -pkinit_encode_dh_params(BIGNUM *p, BIGNUM *g, BIGNUM *q,
2671 +pkinit_encode_dh_params(const BIGNUM *p, const BIGNUM *g, const BIGNUM *q,
2519 2672 unsigned char **buf, unsigned int *buf_len)
2520 2673 {
2521 2674 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
2522 2675 int bufsize = 0, r = 0;
2523 2676 unsigned char *tmp = NULL;
2524 2677 ASN1_INTEGER *ap = NULL, *ag = NULL, *aq = NULL;
2525 2678
2526 2679 if ((ap = BN_to_ASN1_INTEGER(p, NULL)) == NULL)
2527 2680 goto cleanup;
2528 2681 if ((ag = BN_to_ASN1_INTEGER(g, NULL)) == NULL)
2529 2682 goto cleanup;
2530 2683 if ((aq = BN_to_ASN1_INTEGER(q, NULL)) == NULL)
2531 2684 goto cleanup;
2532 2685 bufsize = i2d_ASN1_INTEGER(ap, NULL);
2533 2686 bufsize += i2d_ASN1_INTEGER(ag, NULL);
2534 2687 bufsize += i2d_ASN1_INTEGER(aq, NULL);
2535 2688
2536 2689 r = ASN1_object_size(1, bufsize, V_ASN1_SEQUENCE);
2537 2690
2538 2691 tmp = *buf = (unsigned char *)malloc((size_t) r);
2539 2692 if (tmp == NULL)
2540 2693 goto cleanup;
2541 2694
2542 2695 ASN1_put_object(&tmp, 1, bufsize, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
2543 2696
2544 2697 i2d_ASN1_INTEGER(ap, &tmp);
2545 2698 i2d_ASN1_INTEGER(ag, &tmp);
2546 2699 i2d_ASN1_INTEGER(aq, &tmp);
2547 2700
2548 2701 *buf_len = r;
2549 2702
2550 2703 retval = 0;
2551 2704
2552 2705 cleanup:
|
↓ open down ↓ |
24 lines elided |
↑ open up ↑ |
2553 2706 if (ap != NULL)
2554 2707 ASN1_INTEGER_free(ap);
2555 2708 if (ag != NULL)
2556 2709 ASN1_INTEGER_free(ag);
2557 2710 if (aq != NULL)
2558 2711 ASN1_INTEGER_free(aq);
2559 2712
2560 2713 return retval;
2561 2714 }
2562 2715
2716 +#if OPENSSL_VERSION_NUMBER < 0x10100000L
2717 +
2563 2718 static DH *
2564 2719 pkinit_decode_dh_params(DH ** a, unsigned char **pp, unsigned int len)
2565 2720 {
2566 2721 ASN1_INTEGER ai, *aip = NULL;
2567 2722 long length = (long) len;
2568 2723
2569 2724 M_ASN1_D2I_vars(a, DH *, DH_new);
2570 2725
2571 2726 M_ASN1_D2I_Init();
2572 2727 M_ASN1_D2I_start_sequence();
2573 2728 aip = &ai;
2574 2729 ai.data = NULL;
2575 2730 ai.length = 0;
2576 2731 M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER);
2577 2732 if (aip == NULL)
2578 2733 return NULL;
2579 2734 else {
2580 2735 (*a)->p = ASN1_INTEGER_to_BN(aip, NULL);
2581 2736 if ((*a)->p == NULL)
2582 2737 return NULL;
2583 2738 if (ai.data != NULL) {
2584 2739 OPENSSL_free(ai.data);
2585 2740 ai.data = NULL;
2586 2741 ai.length = 0;
2587 2742 }
2588 2743 }
2589 2744 M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER);
2590 2745 if (aip == NULL)
2591 2746 return NULL;
2592 2747 else {
2593 2748 (*a)->g = ASN1_INTEGER_to_BN(aip, NULL);
2594 2749 if ((*a)->g == NULL)
2595 2750 return NULL;
2596 2751 if (ai.data != NULL) {
2597 2752 OPENSSL_free(ai.data);
2598 2753 ai.data = NULL;
2599 2754 ai.length = 0;
2600 2755 }
2601 2756
2602 2757 }
2603 2758 M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER);
2604 2759 if (aip == NULL)
2605 2760 return NULL;
2606 2761 else {
2607 2762 (*a)->q = ASN1_INTEGER_to_BN(aip, NULL);
2608 2763 if ((*a)->q == NULL)
2609 2764 return NULL;
2610 2765 if (ai.data != NULL) {
2611 2766 OPENSSL_free(ai.data);
|
↓ open down ↓ |
39 lines elided |
↑ open up ↑ |
2612 2767 ai.data = NULL;
2613 2768 ai.length = 0;
2614 2769 }
2615 2770
2616 2771 }
2617 2772 M_ASN1_D2I_end_sequence();
2618 2773 M_ASN1_D2I_Finish(a, DH_free, 0);
2619 2774
2620 2775 }
2621 2776
2777 +#else
2778 +
2779 +/*
2780 + * This is taken from the internal dh_asn1.c file in OpenSSL 1.1, modified to
2781 + * make q an optional field.
2782 + */
2783 +
2784 +typedef struct {
2785 + ASN1_BIT_STRING *seed;
2786 + BIGNUM *counter;
2787 +} int_dhvparams;
2788 +
2789 +typedef struct {
2790 + BIGNUM *p;
2791 + BIGNUM *q;
2792 + BIGNUM *g;
2793 + BIGNUM *j;
2794 + int_dhvparams *vparams;
2795 +} int_dhx942_dh;
2796 +
2797 +ASN1_SEQUENCE(DHvparams) = {
2798 + ASN1_SIMPLE(int_dhvparams, seed, ASN1_BIT_STRING),
2799 + ASN1_SIMPLE(int_dhvparams, counter, BIGNUM)
2800 +} static_ASN1_SEQUENCE_END_name(int_dhvparams, DHvparams)
2801 +
2802 +ASN1_SEQUENCE(DHxparams) = {
2803 + ASN1_SIMPLE(int_dhx942_dh, p, BIGNUM),
2804 + ASN1_SIMPLE(int_dhx942_dh, g, BIGNUM),
2805 + ASN1_OPT(int_dhx942_dh, q, BIGNUM),
2806 + ASN1_OPT(int_dhx942_dh, j, BIGNUM),
2807 + ASN1_OPT(int_dhx942_dh, vparams, DHvparams),
2808 +} static_ASN1_SEQUENCE_END_name(int_dhx942_dh, DHxparams)
2809 +
2810 +static DH *
2811 +pkinit_decode_dh_params(DH **a, unsigned char **pp, unsigned int len)
2812 +{
2813 + int_dhx942_dh *params;
2814 + DH *dh = *a;
2815 +
2816 + if (dh == NULL)
2817 + return NULL;
2818 +
2819 + params = (int_dhx942_dh *)ASN1_item_d2i(NULL,
2820 + (const unsigned char **)pp, len, ASN1_ITEM_rptr(DHxparams));
2821 + if (params == NULL) {
2822 + DH_free(dh);
2823 + return NULL;
2824 + }
2825 +
2826 + DH_set0_pqg(dh, params->p, params->q, params->g);
2827 + params->p = params->q = params->g = NULL;
2828 + ASN1_item_free((ASN1_VALUE *)params, ASN1_ITEM_rptr(DHxparams));
2829 + return dh;
2830 +}
2831 +
2832 +#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
2833 +
2622 2834 static krb5_error_code
2623 2835 pkinit_create_sequence_of_principal_identifiers(
2624 2836 krb5_context context,
2625 2837 pkinit_plg_crypto_context plg_cryptoctx,
2626 2838 pkinit_req_crypto_context req_cryptoctx,
2627 2839 pkinit_identity_crypto_context id_cryptoctx,
2628 2840 int type,
2629 2841 krb5_data **out_data)
2630 2842 {
2631 2843 krb5_error_code retval = KRB5KRB_ERR_GENERIC;
2632 2844 krb5_external_principal_identifier **krb5_trusted_certifiers = NULL;
2633 2845 krb5_data *td_certifiers = NULL, *data = NULL;
2634 2846 krb5_typed_data **typed_data = NULL;
2635 2847
2636 2848 switch(type) {
2637 2849 case TD_TRUSTED_CERTIFIERS:
2638 2850 retval = create_krb5_trustedCertifiers(context, plg_cryptoctx,
2639 2851 req_cryptoctx, id_cryptoctx, &krb5_trusted_certifiers);
2640 2852 if (retval) {
2641 2853 pkiDebug("create_krb5_trustedCertifiers failed\n");
2642 2854 goto cleanup;
2643 2855 }
2644 2856 break;
2645 2857 case TD_INVALID_CERTIFICATES:
2646 2858 retval = create_krb5_invalidCertificates(context, plg_cryptoctx,
2647 2859 req_cryptoctx, id_cryptoctx, &krb5_trusted_certifiers);
2648 2860 if (retval) {
2649 2861 pkiDebug("create_krb5_invalidCertificates failed\n");
2650 2862 goto cleanup;
2651 2863 }
2652 2864 break;
2653 2865 default:
2654 2866 retval = -1;
2655 2867 goto cleanup;
2656 2868 }
2657 2869
2658 2870 retval = k5int_encode_krb5_td_trusted_certifiers((const krb5_external_principal_identifier **)krb5_trusted_certifiers, &td_certifiers);
2659 2871 if (retval) {
2660 2872 pkiDebug("encode_krb5_td_trusted_certifiers failed\n");
2661 2873 goto cleanup;
2662 2874 }
2663 2875 #ifdef DEBUG_ASN1
2664 2876 print_buffer_bin((unsigned char *)td_certifiers->data,
2665 2877 td_certifiers->length, "/tmp/kdc_td_certifiers");
2666 2878 #endif
2667 2879 typed_data = malloc (2 * sizeof(krb5_typed_data *));
2668 2880 if (typed_data == NULL) {
2669 2881 retval = ENOMEM;
2670 2882 goto cleanup;
2671 2883 }
2672 2884 typed_data[1] = NULL;
2673 2885 init_krb5_typed_data(&typed_data[0]);
2674 2886 if (typed_data[0] == NULL) {
2675 2887 retval = ENOMEM;
2676 2888 goto cleanup;
2677 2889 }
2678 2890 typed_data[0]->type = type;
2679 2891 typed_data[0]->length = td_certifiers->length;
2680 2892 typed_data[0]->data = (unsigned char *)td_certifiers->data;
2681 2893 retval = k5int_encode_krb5_typed_data((const krb5_typed_data **)typed_data,
2682 2894 &data);
2683 2895 if (retval) {
2684 2896 pkiDebug("encode_krb5_typed_data failed\n");
2685 2897 goto cleanup;
2686 2898 }
2687 2899 #ifdef DEBUG_ASN1
2688 2900 print_buffer_bin((unsigned char *)data->data, data->length,
2689 2901 "/tmp/kdc_edata");
2690 2902 #endif
2691 2903 *out_data = (krb5_data *)malloc(sizeof(krb5_data));
2692 2904 (*out_data)->length = data->length;
2693 2905 (*out_data)->data = (char *)malloc(data->length);
2694 2906 (void) memcpy((*out_data)->data, data->data, data->length);
2695 2907
2696 2908 retval = 0;
2697 2909
2698 2910 cleanup:
2699 2911 if (krb5_trusted_certifiers != NULL)
2700 2912 free_krb5_external_principal_identifier(&krb5_trusted_certifiers);
2701 2913
2702 2914 if (data != NULL) {
2703 2915 if (data->data != NULL)
2704 2916 free(data->data);
2705 2917 free(data);
2706 2918 }
2707 2919
2708 2920 if (td_certifiers != NULL)
2709 2921 free(td_certifiers);
2710 2922
2711 2923 if (typed_data != NULL)
2712 2924 free_krb5_typed_data(&typed_data);
2713 2925
2714 2926 return retval;
2715 2927 }
2716 2928
2717 2929 krb5_error_code
2718 2930 pkinit_create_td_trusted_certifiers(krb5_context context,
2719 2931 pkinit_plg_crypto_context plg_cryptoctx,
2720 2932 pkinit_req_crypto_context req_cryptoctx,
2721 2933 pkinit_identity_crypto_context id_cryptoctx,
2722 2934 krb5_data **out_data)
2723 2935 {
2724 2936 krb5_error_code retval = KRB5KRB_ERR_GENERIC;
2725 2937
2726 2938 retval = pkinit_create_sequence_of_principal_identifiers(context,
2727 2939 plg_cryptoctx, req_cryptoctx, id_cryptoctx,
2728 2940 TD_TRUSTED_CERTIFIERS, out_data);
2729 2941
2730 2942 return retval;
2731 2943 }
2732 2944
2733 2945 krb5_error_code
2734 2946 pkinit_create_td_invalid_certificate(
2735 2947 krb5_context context,
2736 2948 pkinit_plg_crypto_context plg_cryptoctx,
2737 2949 pkinit_req_crypto_context req_cryptoctx,
2738 2950 pkinit_identity_crypto_context id_cryptoctx,
2739 2951 krb5_data **out_data)
2740 2952 {
2741 2953 krb5_error_code retval = KRB5KRB_ERR_GENERIC;
2742 2954
2743 2955 retval = pkinit_create_sequence_of_principal_identifiers(context,
2744 2956 plg_cryptoctx, req_cryptoctx, id_cryptoctx,
2745 2957 TD_INVALID_CERTIFICATES, out_data);
2746 2958
2747 2959 return retval;
2748 2960 }
2749 2961
2750 2962 /* ARGSUSED */
2751 2963 krb5_error_code
2752 2964 pkinit_create_td_dh_parameters(krb5_context context,
2753 2965 pkinit_plg_crypto_context plg_cryptoctx,
2754 2966 pkinit_req_crypto_context req_cryptoctx,
2755 2967 pkinit_identity_crypto_context id_cryptoctx,
|
↓ open down ↓ |
124 lines elided |
↑ open up ↑ |
2756 2968 pkinit_plg_opts *opts,
2757 2969 krb5_data **out_data)
2758 2970 {
2759 2971 /* Solaris Kerberos */
2760 2972 krb5_error_code retval = KRB5KRB_ERR_GENERIC;
2761 2973 unsigned int buf1_len = 0, buf2_len = 0, buf3_len = 0, i = 0;
2762 2974 unsigned char *buf1 = NULL, *buf2 = NULL, *buf3 = NULL;
2763 2975 krb5_typed_data **typed_data = NULL;
2764 2976 krb5_data *data = NULL, *encoded_algId = NULL;
2765 2977 krb5_algorithm_identifier **algId = NULL;
2978 + const BIGNUM *p, *q, *g;
2766 2979
2767 2980 /* Solaris Kerberos */
2768 2981 if (opts->dh_min_bits > 4096) {
2769 2982 retval = EINVAL;
2770 2983 goto cleanup;
2771 2984 }
2772 2985
2773 2986 if (opts->dh_min_bits <= 1024) {
2774 - retval = pkinit_encode_dh_params(plg_cryptoctx->dh_1024->p,
2775 - plg_cryptoctx->dh_1024->g, plg_cryptoctx->dh_1024->q,
2776 - &buf1, &buf1_len);
2987 + DH_get0_pqg(plg_cryptoctx->dh_1024, &p, &q, &g);
2988 + retval = pkinit_encode_dh_params(p, g, q, &buf1, &buf1_len);
2777 2989 if (retval)
2778 2990 goto cleanup;
2779 2991 }
2780 2992 if (opts->dh_min_bits <= 2048) {
2781 - retval = pkinit_encode_dh_params(plg_cryptoctx->dh_2048->p,
2782 - plg_cryptoctx->dh_2048->g, plg_cryptoctx->dh_2048->q,
2783 - &buf2, &buf2_len);
2993 + DH_get0_pqg(plg_cryptoctx->dh_2048, &p, &q, &g);
2994 + retval = pkinit_encode_dh_params(p, g, q, &buf2, &buf2_len);
2784 2995 if (retval)
2785 2996 goto cleanup;
2786 2997 }
2787 - retval = pkinit_encode_dh_params(plg_cryptoctx->dh_4096->p,
2788 - plg_cryptoctx->dh_4096->g, plg_cryptoctx->dh_4096->q,
2789 - &buf3, &buf3_len);
2998 + DH_get0_pqg(plg_cryptoctx->dh_4096, &p, &q, &g);
2999 + retval = pkinit_encode_dh_params(p, g, q, &buf3, &buf3_len);
2790 3000 if (retval)
2791 3001 goto cleanup;
2792 3002
2793 3003 if (opts->dh_min_bits <= 1024) {
2794 3004 algId = malloc(4 * sizeof(krb5_algorithm_identifier *));
2795 3005 if (algId == NULL)
2796 3006 goto cleanup;
2797 3007 algId[3] = NULL;
2798 3008 algId[0] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
2799 3009 if (algId[0] == NULL)
2800 3010 goto cleanup;
2801 3011 algId[0]->parameters.data = (unsigned char *)malloc(buf2_len);
2802 3012 if (algId[0]->parameters.data == NULL)
2803 3013 goto cleanup;
2804 3014 (void) memcpy(algId[0]->parameters.data, buf2, buf2_len);
2805 3015 algId[0]->parameters.length = buf2_len;
2806 3016 algId[0]->algorithm = dh_oid;
2807 3017
2808 3018 algId[1] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
2809 3019 if (algId[1] == NULL)
2810 3020 goto cleanup;
2811 3021 algId[1]->parameters.data = (unsigned char *)malloc(buf3_len);
2812 3022 if (algId[1]->parameters.data == NULL)
2813 3023 goto cleanup;
2814 3024 (void) memcpy(algId[1]->parameters.data, buf3, buf3_len);
2815 3025 algId[1]->parameters.length = buf3_len;
2816 3026 algId[1]->algorithm = dh_oid;
2817 3027
2818 3028 algId[2] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
2819 3029 if (algId[2] == NULL)
2820 3030 goto cleanup;
2821 3031 algId[2]->parameters.data = (unsigned char *)malloc(buf1_len);
2822 3032 if (algId[2]->parameters.data == NULL)
2823 3033 goto cleanup;
2824 3034 (void) memcpy(algId[2]->parameters.data, buf1, buf1_len);
2825 3035 algId[2]->parameters.length = buf1_len;
2826 3036 algId[2]->algorithm = dh_oid;
2827 3037
2828 3038 } else if (opts->dh_min_bits <= 2048) {
2829 3039 algId = malloc(3 * sizeof(krb5_algorithm_identifier *));
2830 3040 if (algId == NULL)
2831 3041 goto cleanup;
2832 3042 algId[2] = NULL;
2833 3043 algId[0] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
2834 3044 if (algId[0] == NULL)
2835 3045 goto cleanup;
2836 3046 algId[0]->parameters.data = (unsigned char *)malloc(buf2_len);
2837 3047 if (algId[0]->parameters.data == NULL)
2838 3048 goto cleanup;
2839 3049 (void) memcpy(algId[0]->parameters.data, buf2, buf2_len);
2840 3050 algId[0]->parameters.length = buf2_len;
2841 3051 algId[0]->algorithm = dh_oid;
2842 3052
2843 3053 algId[1] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
2844 3054 if (algId[1] == NULL)
2845 3055 goto cleanup;
2846 3056 algId[1]->parameters.data = (unsigned char *)malloc(buf3_len);
2847 3057 if (algId[1]->parameters.data == NULL)
2848 3058 goto cleanup;
2849 3059 (void) memcpy(algId[1]->parameters.data, buf3, buf3_len);
2850 3060 algId[1]->parameters.length = buf3_len;
2851 3061 algId[1]->algorithm = dh_oid;
2852 3062
2853 3063 } else if (opts->dh_min_bits <= 4096) {
2854 3064 algId = malloc(2 * sizeof(krb5_algorithm_identifier *));
2855 3065 if (algId == NULL)
2856 3066 goto cleanup;
2857 3067 algId[1] = NULL;
2858 3068 algId[0] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
2859 3069 if (algId[0] == NULL)
2860 3070 goto cleanup;
2861 3071 algId[0]->parameters.data = (unsigned char *)malloc(buf3_len);
2862 3072 if (algId[0]->parameters.data == NULL)
2863 3073 goto cleanup;
2864 3074 (void) memcpy(algId[0]->parameters.data, buf3, buf3_len);
2865 3075 algId[0]->parameters.length = buf3_len;
2866 3076 algId[0]->algorithm = dh_oid;
2867 3077
2868 3078 }
2869 3079 retval = k5int_encode_krb5_td_dh_parameters((const krb5_algorithm_identifier **)algId, &encoded_algId);
2870 3080 if (retval)
2871 3081 goto cleanup;
2872 3082 #ifdef DEBUG_ASN1
2873 3083 print_buffer_bin((unsigned char *)encoded_algId->data,
2874 3084 encoded_algId->length, "/tmp/kdc_td_dh_params");
2875 3085 #endif
2876 3086 typed_data = malloc (2 * sizeof(krb5_typed_data *));
2877 3087 if (typed_data == NULL) {
2878 3088 retval = ENOMEM;
2879 3089 goto cleanup;
2880 3090 }
2881 3091 typed_data[1] = NULL;
2882 3092 init_krb5_typed_data(&typed_data[0]);
2883 3093 if (typed_data == NULL) {
2884 3094 retval = ENOMEM;
2885 3095 goto cleanup;
2886 3096 }
2887 3097 typed_data[0]->type = TD_DH_PARAMETERS;
2888 3098 typed_data[0]->length = encoded_algId->length;
2889 3099 typed_data[0]->data = (unsigned char *)encoded_algId->data;
2890 3100 retval = k5int_encode_krb5_typed_data((const krb5_typed_data**)typed_data,
2891 3101 &data);
2892 3102 if (retval) {
2893 3103 pkiDebug("encode_krb5_typed_data failed\n");
2894 3104 goto cleanup;
2895 3105 }
2896 3106 #ifdef DEBUG_ASN1
2897 3107 print_buffer_bin((unsigned char *)data->data, data->length,
2898 3108 "/tmp/kdc_edata");
2899 3109 #endif
2900 3110 *out_data = (krb5_data *)malloc(sizeof(krb5_data));
2901 3111 if (*out_data == NULL)
2902 3112 goto cleanup;
2903 3113 (*out_data)->length = data->length;
2904 3114 (*out_data)->data = (char *)malloc(data->length);
2905 3115 if ((*out_data)->data == NULL) {
2906 3116 free(*out_data);
2907 3117 *out_data = NULL;
2908 3118 goto cleanup;
2909 3119 }
2910 3120 (void) memcpy((*out_data)->data, data->data, data->length);
2911 3121
2912 3122 retval = 0;
2913 3123 cleanup:
2914 3124
2915 3125 if (buf1 != NULL)
2916 3126 free(buf1);
2917 3127 if (buf2 != NULL)
2918 3128 free(buf2);
2919 3129 if (buf3 != NULL)
2920 3130 free(buf3);
2921 3131 if (data != NULL) {
2922 3132 if (data->data != NULL)
2923 3133 free(data->data);
2924 3134 free(data);
2925 3135 }
2926 3136 if (typed_data != NULL)
2927 3137 free_krb5_typed_data(&typed_data);
2928 3138 if (encoded_algId != NULL)
2929 3139 free(encoded_algId);
2930 3140
2931 3141 if (algId != NULL) {
2932 3142 while(algId[i] != NULL) {
2933 3143 if (algId[i]->parameters.data != NULL)
2934 3144 free(algId[i]->parameters.data);
2935 3145 free(algId[i]);
2936 3146 i++;
2937 3147 }
2938 3148 free(algId);
2939 3149 }
2940 3150
2941 3151 return retval;
2942 3152 }
2943 3153
2944 3154 /* ARGSUSED */
2945 3155 krb5_error_code
2946 3156 pkinit_check_kdc_pkid(krb5_context context,
2947 3157 pkinit_plg_crypto_context plg_cryptoctx,
2948 3158 pkinit_req_crypto_context req_cryptoctx,
2949 3159 pkinit_identity_crypto_context id_cryptoctx,
2950 3160 unsigned char *pdid_buf,
2951 3161 unsigned int pkid_len,
2952 3162 int *valid_kdcPkId)
2953 3163 {
2954 3164 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
2955 3165 PKCS7_ISSUER_AND_SERIAL *is = NULL;
2956 3166 const unsigned char *p = pdid_buf;
2957 3167 int status = 1;
2958 3168 X509 *kdc_cert = sk_X509_value(id_cryptoctx->my_certs, id_cryptoctx->cert_index);
2959 3169
2960 3170 *valid_kdcPkId = 0;
2961 3171 pkiDebug("found kdcPkId in AS REQ\n");
2962 3172 is = d2i_PKCS7_ISSUER_AND_SERIAL(NULL, &p, (int)pkid_len);
2963 3173 if (is == NULL)
2964 3174 goto cleanup;
2965 3175
2966 3176 status = X509_NAME_cmp(X509_get_issuer_name(kdc_cert), is->issuer);
2967 3177 if (!status) {
2968 3178 status = ASN1_INTEGER_cmp(X509_get_serialNumber(kdc_cert), is->serial);
2969 3179 if (!status)
2970 3180 *valid_kdcPkId = 1;
2971 3181 }
2972 3182
|
↓ open down ↓ |
173 lines elided |
↑ open up ↑ |
2973 3183 retval = 0;
2974 3184 cleanup:
2975 3185 X509_NAME_free(is->issuer);
2976 3186 ASN1_INTEGER_free(is->serial);
2977 3187 free(is);
2978 3188
2979 3189 return retval;
2980 3190 }
2981 3191
2982 3192 static int
2983 -pkinit_check_dh_params(BIGNUM * p1, BIGNUM * p2, BIGNUM * g1, BIGNUM * q1)
3193 +pkinit_check_dh_params(const BIGNUM *p1, const BIGNUM *p2, const BIGNUM *g1,
3194 + const BIGNUM *q1)
2984 3195 {
2985 3196 BIGNUM *g2 = NULL, *q2 = NULL;
2986 3197 /* Solaris Kerberos */
2987 3198 int retval = EINVAL;
2988 3199
2989 3200 if (!BN_cmp(p1, p2)) {
2990 3201 g2 = BN_new();
2991 3202 BN_set_word(g2, DH_GENERATOR_2);
2992 3203 if (!BN_cmp(g1, g2)) {
2993 3204 q2 = BN_new();
2994 3205 BN_rshift1(q2, p1);
2995 3206 if (!BN_cmp(q1, q2)) {
2996 3207 pkiDebug("good %d dhparams\n", BN_num_bits(p1));
2997 3208 retval = 0;
2998 3209 } else
2999 3210 pkiDebug("bad group 2 q dhparameter\n");
3000 3211 BN_free(q2);
3001 3212 } else
3002 3213 pkiDebug("bad g dhparameter\n");
3003 3214 BN_free(g2);
3004 3215 } else
3005 3216 pkiDebug("p is not well-known group 2 dhparameter\n");
3006 3217
3007 3218 return retval;
3008 3219 }
3009 3220
3010 3221 /* ARGSUSED */
3011 3222 krb5_error_code
3012 3223 pkinit_process_td_dh_params(krb5_context context,
3013 3224 pkinit_plg_crypto_context cryptoctx,
3014 3225 pkinit_req_crypto_context req_cryptoctx,
3015 3226 pkinit_identity_crypto_context id_cryptoctx,
3016 3227 krb5_algorithm_identifier **algId,
|
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
3017 3228 int *new_dh_size)
3018 3229 {
3019 3230 krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
3020 3231 int i = 0, use_sent_dh = 0, ok = 0;
3021 3232
3022 3233 pkiDebug("dh parameters\n");
3023 3234
3024 3235 while (algId[i] != NULL) {
3025 3236 DH *dh = NULL;
3026 3237 unsigned char *tmp = NULL;
3238 + const BIGNUM *p, *g, *q, *p2;
3027 3239 int dh_prime_bits = 0;
3028 3240
3029 3241 if (algId[i]->algorithm.length != dh_oid.length ||
3030 3242 memcmp(algId[i]->algorithm.data, dh_oid.data, dh_oid.length))
3031 3243 goto cleanup;
3032 3244
3033 3245 tmp = algId[i]->parameters.data;
3034 3246 dh = DH_new();
3035 3247 dh = pkinit_decode_dh_params(&dh, &tmp, algId[i]->parameters.length);
3036 - dh_prime_bits = BN_num_bits(dh->p);
3248 + dh_prime_bits = DH_bits(dh);
3037 3249 pkiDebug("client sent %d DH bits server prefers %d DH bits\n",
3038 3250 *new_dh_size, dh_prime_bits);
3251 + DH_get0_pqg(dh, &p, &q, &g);
3039 3252 switch(dh_prime_bits) {
3040 3253 case 1024:
3041 - if (pkinit_check_dh_params(cryptoctx->dh_1024->p, dh->p,
3042 - dh->g, dh->q) == 0) {
3254 + DH_get0_pqg(cryptoctx->dh_1024, &p2, NULL, NULL);
3255 + if (pkinit_check_dh_params(p2, p, g, q) == 0) {
3043 3256 *new_dh_size = 1024;
3044 3257 ok = 1;
3045 3258 }
3046 3259 break;
3047 3260 case 2048:
3048 - if (pkinit_check_dh_params(cryptoctx->dh_2048->p, dh->p,
3049 - dh->g, dh->q) == 0) {
3261 + DH_get0_pqg(cryptoctx->dh_2048, &p2, NULL, NULL);
3262 + if (pkinit_check_dh_params(p2, p, g, q) == 0) {
3050 3263 *new_dh_size = 2048;
3051 3264 ok = 1;
3052 3265 }
3053 3266 break;
3054 3267 case 4096:
3055 - if (pkinit_check_dh_params(cryptoctx->dh_4096->p, dh->p,
3056 - dh->g, dh->q) == 0) {
3268 + DH_get0_pqg(cryptoctx->dh_4096, &p2, NULL, NULL);
3269 + if (pkinit_check_dh_params(p2, p, g, q) == 0) {
3057 3270 *new_dh_size = 4096;
3058 3271 ok = 1;
3059 3272 }
3060 3273 break;
3061 3274 default:
3062 3275 break;
3063 3276 }
3064 3277 if (!ok) {
3065 3278 DH_check(dh, &retval);
3066 3279 if (retval != 0) {
3067 3280 pkiDebug("DH parameters provided by server are unacceptable\n");
3068 3281 retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
3069 3282 }
3070 3283 else {
3071 3284 use_sent_dh = 1;
3072 3285 ok = 1;
3073 3286 }
3074 3287 }
3075 3288 if (!use_sent_dh)
3076 3289 DH_free(dh);
3077 3290 if (ok) {
3078 3291 if (req_cryptoctx->dh != NULL) {
3079 3292 DH_free(req_cryptoctx->dh);
3080 3293 req_cryptoctx->dh = NULL;
3081 3294 }
3082 3295 if (use_sent_dh)
3083 3296 req_cryptoctx->dh = dh;
3084 3297 break;
3085 3298 }
|
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
3086 3299 i++;
3087 3300 }
3088 3301
3089 3302 if (ok)
3090 3303 retval = 0;
3091 3304
3092 3305 cleanup:
3093 3306 return retval;
3094 3307 }
3095 3308
3096 -/* ARGSUSED */
3309 +/* ARGSUSED */
3097 3310 static int
3098 3311 openssl_callback(int ok, X509_STORE_CTX * ctx)
3099 3312 {
3100 3313 #ifdef DEBUG
3101 3314 if (!ok) {
3102 3315 char buf[DN_BUF_LEN];
3103 3316
3104 3317 X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), buf, sizeof(buf));
3105 3318 pkiDebug("cert = %s\n", buf);
3106 3319 pkiDebug("callback function: %d (%s)\n", ctx->error,
3107 3320 X509_verify_cert_error_string(ctx->error));
3108 3321 }
3109 3322 #endif
3110 3323 return ok;
3111 3324 }
3112 3325
3113 3326 static int
3114 3327 openssl_callback_ignore_crls(int ok, X509_STORE_CTX * ctx)
3115 3328 {
3116 - if (!ok) {
3117 - switch (ctx->error) {
3118 - case X509_V_ERR_UNABLE_TO_GET_CRL:
3119 - return 1;
3120 - default:
3121 - return 0;
3122 - }
3123 - }
3329 + if (!ok)
3330 + return (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_UNABLE_TO_GET_CRL);
3124 3331 return ok;
3125 3332 }
3126 3333
3127 3334 static ASN1_OBJECT *
3128 3335 pkinit_pkcs7type2oid(pkinit_plg_crypto_context cryptoctx, int pkcs7_type)
3129 3336 {
3130 3337 int nid;
3131 3338
3132 3339 switch (pkcs7_type) {
3133 3340 case CMS_SIGN_CLIENT:
3134 3341 return cryptoctx->id_pkinit_authData;
3135 3342 case CMS_SIGN_DRAFT9:
3136 3343 /*
3137 3344 * Delay creating this OID until we know we need it.
3138 3345 * It shadows an existing OpenSSL oid. If it
3139 3346 * is created too early, it breaks things like
3140 3347 * the use of pkcs12 (which uses pkcs7 structures).
3141 3348 * We need this shadow version because our code
3142 3349 * depends on the "other" type to be unknown to the
3143 3350 * OpenSSL code.
3144 - */
3351 + */
3145 3352 if (cryptoctx->id_pkinit_authData9 == NULL) {
3146 3353 pkiDebug("%s: Creating shadow instance of pkcs7-data oid\n",
3147 3354 __FUNCTION__);
3148 3355 nid = OBJ_create("1.2.840.113549.1.7.1", "id-pkcs7-data",
3149 3356 "PKCS7 data");
3150 3357 if (nid == NID_undef)
3151 3358 return NULL;
3152 3359 cryptoctx->id_pkinit_authData9 = OBJ_nid2obj(nid);
3153 3360 }
3154 3361 return cryptoctx->id_pkinit_authData9;
3155 3362 case CMS_SIGN_SERVER:
3156 3363 return cryptoctx->id_pkinit_DHKeyData;
3157 3364 case CMS_ENVEL_SERVER:
3158 3365 return cryptoctx->id_pkinit_rkeyData;
3159 3366 default:
3160 3367 return NULL;
3161 3368 }
3162 3369
3163 3370 }
3164 3371
3165 3372 #ifdef LONGHORN_BETA_COMPAT
3166 3373 #if 0
3167 3374 /*
3168 3375 * This is a version that worked with Longhorn Beta 3.
3169 3376 */
3170 3377 static int
3171 3378 wrap_signeddata(unsigned char *data, unsigned int data_len,
3172 3379 unsigned char **out, unsigned int *out_len,
3173 3380 int is_longhorn_server)
3174 3381 {
3175 3382
3176 3383 unsigned int orig_len = 0, oid_len = 0, tot_len = 0;
3177 3384 ASN1_OBJECT *oid = NULL;
3178 3385 unsigned char *p = NULL;
3179 3386
3180 3387 pkiDebug("%s: This is the Longhorn version and is_longhorn_server = %d\n",
3181 3388 __FUNCTION__, is_longhorn_server);
3182 3389
3183 3390 /* Get length to wrap the original data with SEQUENCE tag */
3184 3391 tot_len = orig_len = ASN1_object_size(1, (int)data_len, V_ASN1_SEQUENCE);
3185 3392
3186 3393 if (is_longhorn_server == 0) {
3187 3394 /* Add the signedData OID and adjust lengths */
3188 3395 oid = OBJ_nid2obj(NID_pkcs7_signed);
3189 3396 oid_len = i2d_ASN1_OBJECT(oid, NULL);
3190 3397
3191 3398 tot_len = ASN1_object_size(1, (int)(orig_len+oid_len), V_ASN1_SEQUENCE);
3192 3399 }
3193 3400
3194 3401 p = *out = (unsigned char *)malloc(tot_len);
3195 3402 if (p == NULL) return -1;
3196 3403
3197 3404 if (is_longhorn_server == 0) {
3198 3405 ASN1_put_object(&p, 1, (int)(orig_len+oid_len),
3199 3406 V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
3200 3407
3201 3408 i2d_ASN1_OBJECT(oid, &p);
3202 3409
3203 3410 ASN1_put_object(&p, 1, (int)data_len, 0, V_ASN1_CONTEXT_SPECIFIC);
3204 3411 } else {
3205 3412 ASN1_put_object(&p, 1, (int)data_len, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
3206 3413 }
3207 3414 memcpy(p, data, data_len);
3208 3415
3209 3416 *out_len = tot_len;
3210 3417
3211 3418 return 0;
3212 3419 }
3213 3420 #else
3214 3421 /*
3215 3422 * This is a version that works with a patched Longhorn KDC.
3216 3423 * (Which should match SP1 ??).
3217 3424 */
3218 3425 static int
3219 3426 wrap_signeddata(unsigned char *data, unsigned int data_len,
3220 3427 unsigned char **out, unsigned int *out_len,
3221 3428 int is_longhorn_server)
3222 3429 {
3223 3430
3224 3431 unsigned int oid_len = 0, tot_len = 0, wrap_len = 0, tag_len = 0;
3225 3432 ASN1_OBJECT *oid = NULL;
3226 3433 unsigned char *p = NULL;
3227 3434
3228 3435 pkiDebug("%s: This is the Longhorn version and is_longhorn_server = %d\n",
3229 3436 __FUNCTION__, is_longhorn_server);
3230 3437
3231 3438 /* New longhorn is missing another sequence */
3232 3439 if (is_longhorn_server == 1)
3233 3440 wrap_len = ASN1_object_size(1, (int)(data_len), V_ASN1_SEQUENCE);
3234 3441 else
3235 3442 wrap_len = data_len;
3236 3443
3237 3444 /* Get length to wrap the original data with SEQUENCE tag */
3238 3445 tag_len = ASN1_object_size(1, (int)wrap_len, V_ASN1_SEQUENCE);
3239 3446
3240 3447 /* Always add oid */
3241 3448 oid = OBJ_nid2obj(NID_pkcs7_signed);
3242 3449 oid_len = i2d_ASN1_OBJECT(oid, NULL);
3243 3450 oid_len += tag_len;
3244 3451
3245 3452 tot_len = ASN1_object_size(1, (int)(oid_len), V_ASN1_SEQUENCE);
3246 3453
3247 3454 p = *out = (unsigned char *)malloc(tot_len);
3248 3455 if (p == NULL)
3249 3456 return -1;
3250 3457
3251 3458 ASN1_put_object(&p, 1, (int)(oid_len),
3252 3459 V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
3253 3460
3254 3461 i2d_ASN1_OBJECT(oid, &p);
3255 3462
3256 3463 ASN1_put_object(&p, 1, (int)wrap_len, 0, V_ASN1_CONTEXT_SPECIFIC);
3257 3464
3258 3465 /* Wrap in extra seq tag */
3259 3466 if (is_longhorn_server == 1) {
3260 3467 ASN1_put_object(&p, 1, (int)data_len, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
3261 3468 }
3262 3469 (void) memcpy(p, data, data_len);
3263 3470
3264 3471 *out_len = tot_len;
3265 3472
3266 3473 return 0;
3267 3474 }
3268 3475
3269 3476 #endif
3270 3477 #else
3271 3478 static int
3272 3479 wrap_signeddata(unsigned char *data, unsigned int data_len,
3273 3480 unsigned char **out, unsigned int *out_len)
3274 3481 {
3275 3482
3276 3483 unsigned int orig_len = 0, oid_len = 0, tot_len = 0;
3277 3484 ASN1_OBJECT *oid = NULL;
3278 3485 unsigned char *p = NULL;
3279 3486
3280 3487 /* Get length to wrap the original data with SEQUENCE tag */
3281 3488 tot_len = orig_len = ASN1_object_size(1, (int)data_len, V_ASN1_SEQUENCE);
3282 3489
3283 3490 /* Add the signedData OID and adjust lengths */
3284 3491 oid = OBJ_nid2obj(NID_pkcs7_signed);
3285 3492 oid_len = i2d_ASN1_OBJECT(oid, NULL);
3286 3493
3287 3494 tot_len = ASN1_object_size(1, (int)(orig_len+oid_len), V_ASN1_SEQUENCE);
3288 3495
3289 3496 p = *out = (unsigned char *)malloc(tot_len);
3290 3497 if (p == NULL) return -1;
3291 3498
3292 3499 ASN1_put_object(&p, 1, (int)(orig_len+oid_len),
3293 3500 V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
3294 3501
3295 3502 i2d_ASN1_OBJECT(oid, &p);
3296 3503
3297 3504 ASN1_put_object(&p, 1, (int)data_len, 0, V_ASN1_CONTEXT_SPECIFIC);
3298 3505 (void) memcpy(p, data, data_len);
3299 3506
3300 3507 *out_len = tot_len;
3301 3508
|
↓ open down ↓ |
147 lines elided |
↑ open up ↑ |
3302 3509 return 0;
3303 3510 }
3304 3511 #endif
3305 3512
3306 3513 static int
3307 3514 prepare_enc_data(unsigned char *indata,
3308 3515 int indata_len,
3309 3516 unsigned char **outdata,
3310 3517 int *outdata_len)
3311 3518 {
3312 - /* Solaris Kerberos */
3313 - ASN1_const_CTX c;
3314 - long length = indata_len;
3315 - int Ttag, Tclass;
3316 - long Tlen;
3519 + int tag, class;
3520 + long tlen, slen;
3521 + const uint8_t *p = indata, *oldp;
3317 3522
3318 - c.pp = (const unsigned char **)&indata;
3319 - c.q = *(const unsigned char **)&indata;
3320 - c.error = ERR_R_NESTED_ASN1_ERROR;
3321 - c.p= *(const unsigned char **)&indata;
3322 - c.max = (length == 0)?0:(c.p+length);
3523 + /* Top-bit set means that the conversion failed. */
3524 + if (ASN1_get_object(&p, &slen, &tag, &class, indata_len) & 0x80)
3525 + return EINVAL;
3526 + if (tag != V_ASN1_SEQUENCE)
3527 + return EINVAL;
3323 3528
3324 - asn1_GetSequence(&c,&length);
3529 + oldp = p;
3530 + if (ASN1_get_object(&p, &tlen, &tag, &class, slen) & 0x80)
3531 + return EINVAL;
3532 + p += tlen;
3533 + slen -= (p - oldp);
3325 3534
3326 - ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen);
3327 - c.p += Tlen;
3328 - ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen);
3535 + if (ASN1_get_object(&p, &tlen, &tag, &class, slen) & 0x80)
3536 + return EINVAL;
3329 3537
3330 - asn1_const_Finish(&c);
3538 + *outdata = malloc(tlen);
3539 + if (*outdata == NULL)
3540 + return ENOMEM;
3541 + memcpy(*outdata, p, tlen);
3542 + *outdata_len = tlen;
3331 3543
3332 - *outdata = (unsigned char *)malloc((size_t)Tlen);
3333 - /* Solaris Kerberos */
3334 - if (outdata == NULL)
3335 - return ENOMEM;
3336 -
3337 - (void) memcpy(*outdata, c.p, (size_t)Tlen);
3338 - *outdata_len = Tlen;
3339 -
3340 3544 return 0;
3341 3545 }
3342 3546
3343 3547 #ifndef WITHOUT_PKCS11
3344 3548 static void *
3345 3549 pkinit_C_LoadModule(const char *modname, CK_FUNCTION_LIST_PTR_PTR p11p)
3346 3550 {
3347 3551 void *handle;
3348 3552 CK_RV (*getflist)(CK_FUNCTION_LIST_PTR_PTR);
3349 3553
3350 3554 pkiDebug("loading module \"%s\"... ", modname);
3351 3555 /* Solaris Kerberos */
3352 3556 handle = dlopen(modname, RTLD_NOW | RTLD_GROUP);
3353 3557 if (handle == NULL) {
3354 3558 pkiDebug("not found\n");
3355 3559 return NULL;
3356 3560 }
3357 3561 getflist = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR)) dlsym(handle, "C_GetFunctionList");
3358 3562 if (getflist == NULL || (*getflist)(p11p) != CKR_OK) {
3359 3563 (void) dlclose(handle);
3360 3564 pkiDebug("failed\n");
3361 3565 return NULL;
3362 3566 }
3363 3567 pkiDebug("ok\n");
3364 3568 return handle;
3365 3569 }
3366 3570
3367 3571 static CK_RV
3368 3572 pkinit_C_UnloadModule(void *handle)
3369 3573 {
3370 3574 /* Solaris Kerberos */
3371 3575 if (dlclose(handle) != 0)
3372 3576 return CKR_GENERAL_ERROR;
3373 3577
3374 3578 return CKR_OK;
3375 3579 }
3376 3580
3377 3581 /*
3378 3582 * Solaris Kerberos: this is a new function that does not exist yet in the MIT
3379 3583 * code.
3380 3584 *
3381 3585 * labelstr will be C string containing token label with trailing white space
3382 3586 * removed.
3383 3587 */
3384 3588 static void
3385 3589 trim_token_label(CK_TOKEN_INFO *tinfo, char *labelstr, unsigned int labelstr_len)
3386 3590 {
3387 3591 int i;
3388 3592
3389 3593 assert(labelstr_len > sizeof (tinfo->label));
3390 3594 /*
3391 3595 * \0 terminate labelstr in case the last char in the token label is
3392 3596 * non-whitespace
3393 3597 */
3394 3598 labelstr[sizeof (tinfo->label)] = '\0';
3395 3599 (void) memcpy(labelstr, (char *) tinfo->label, sizeof (tinfo->label));
3396 3600
3397 3601 /* init i so terminating \0 is skipped */
3398 3602 for (i = sizeof (tinfo->label) - 1; i >= 0; i--) {
3399 3603 if (labelstr[i] == ' ')
3400 3604 labelstr[i] = '\0';
3401 3605 else
3402 3606 break;
3403 3607 }
3404 3608 }
3405 3609
3406 3610 /*
3407 3611 * Solaris Kerberos: this is a new function that does not exist yet in the MIT
3408 3612 * code.
3409 3613 */
3410 3614 static krb5_error_code
3411 3615 pkinit_prompt_user(krb5_context context,
3412 3616 pkinit_identity_crypto_context cctx,
3413 3617 krb5_data *reply,
3414 3618 char *prompt,
3415 3619 int hidden)
3416 3620 {
3417 3621 krb5_error_code r;
3418 3622 krb5_prompt kprompt;
3419 3623 krb5_prompt_type prompt_type;
3420 3624
3421 3625 if (cctx->prompter == NULL)
3422 3626 return (EINVAL);
3423 3627
3424 3628 kprompt.prompt = prompt;
3425 3629 kprompt.hidden = hidden;
3426 3630 kprompt.reply = reply;
3427 3631 /*
3428 3632 * Note, assuming this type for now, may need to be passed in in the future.
3429 3633 */
3430 3634 prompt_type = KRB5_PROMPT_TYPE_PREAUTH;
3431 3635
3432 3636 /* PROMPTER_INVOCATION */
3433 3637 k5int_set_prompt_types(context, &prompt_type);
3434 3638 r = (*cctx->prompter)(context, cctx->prompter_data,
3435 3639 NULL, NULL, 1, &kprompt);
3436 3640 k5int_set_prompt_types(context, NULL);
3437 3641 return (r);
3438 3642 }
3439 3643
3440 3644 /*
3441 3645 * Solaris Kerberos: this function was changed to support a PIN being passed
3442 3646 * in. If that is the case the user will not be prompted for their PIN.
3443 3647 */
3444 3648 static krb5_error_code
3445 3649 pkinit_login(krb5_context context,
3446 3650 pkinit_identity_crypto_context id_cryptoctx,
3447 3651 CK_TOKEN_INFO *tip)
3448 3652 {
3449 3653 krb5_data rdat;
3450 3654 char *prompt;
3451 3655 int prompt_len;
3452 3656 int r = 0;
3453 3657
3454 3658 if (tip->flags & CKF_PROTECTED_AUTHENTICATION_PATH) {
3455 3659 rdat.data = NULL;
3456 3660 rdat.length = 0;
3457 3661 } else if (id_cryptoctx->PIN != NULL) {
3458 3662 if ((rdat.data = strdup(id_cryptoctx->PIN)) == NULL)
3459 3663 return (ENOMEM);
3460 3664 /*
3461 3665 * Don't include NULL string terminator in length calculation as this
3462 3666 * PIN is passed to the C_Login function and only the text chars should
3463 3667 * be considered to be the PIN.
3464 3668 */
3465 3669 rdat.length = strlen(id_cryptoctx->PIN);
3466 3670 } else {
3467 3671 /* Solaris Kerberos - trim token label */
3468 3672 char tmplabel[sizeof (tip->label) + 1];
3469 3673
3470 3674 if (!id_cryptoctx->prompter) {
3471 3675 pkiDebug("pkinit_login: id_cryptoctx->prompter is NULL\n");
3472 3676 /* Solaris Kerberos: Improved error messages */
3473 3677 krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
3474 3678 gettext("Failed to log into token: prompter function is NULL"));
3475 3679 return (KRB5KDC_ERR_PREAUTH_FAILED);
3476 3680 }
3477 3681 /* Solaris Kerberos - Changes for gettext() */
3478 3682 prompt_len = sizeof (tip->label) + 256;
3479 3683 if ((prompt = (char *) malloc(prompt_len)) == NULL)
3480 3684 return ENOMEM;
3481 3685
3482 3686 /* Solaris Kerberos - trim token label which can be padded with space */
3483 3687 trim_token_label(tip, tmplabel, sizeof (tmplabel));
3484 3688 (void) snprintf(prompt, prompt_len, gettext("%s PIN"), tmplabel);
3485 3689
3486 3690 /* Solaris Kerberos */
3487 3691 if (tip->flags & CKF_USER_PIN_LOCKED)
3488 3692 (void) strlcat(prompt, gettext(" (Warning: PIN locked)"), prompt_len);
3489 3693 else if (tip->flags & CKF_USER_PIN_FINAL_TRY)
3490 3694 (void) strlcat(prompt, gettext(" (Warning: PIN final try)"), prompt_len);
3491 3695 else if (tip->flags & CKF_USER_PIN_COUNT_LOW)
3492 3696 (void) strlcat(prompt, gettext(" (Warning: PIN count low)"), prompt_len);
3493 3697 rdat.data = malloc(tip->ulMaxPinLen + 2);
3494 3698 rdat.length = tip->ulMaxPinLen + 1;
3495 3699 /*
3496 3700 * Note that the prompter function will set rdat.length such that the
3497 3701 * NULL terminator is not included
3498 3702 */
3499 3703 /* PROMPTER_INVOCATION */
3500 3704 r = pkinit_prompt_user(context, id_cryptoctx, &rdat, prompt, 1);
3501 3705 free(prompt);
3502 3706 }
3503 3707
3504 3708 if (r == 0) {
3505 3709 r = id_cryptoctx->p11->C_Login(id_cryptoctx->session, CKU_USER,
3506 3710 (u_char *) rdat.data, rdat.length);
3507 3711
3508 3712 if (r != CKR_OK) {
3509 3713 pkiDebug("C_Login: %s\n", pkinit_pkcs11_code_to_text(r));
3510 3714 /* Solaris Kerberos: Improved error messages */
3511 3715 krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
3512 3716 gettext("Failed to log into token: %s"),
3513 3717 pkinit_pkcs11_code_to_text(r));
3514 3718 r = KRB5KDC_ERR_PREAUTH_FAILED;
3515 3719 } else {
3516 3720 /* Solaris Kerberos: only need to login once */
3517 3721 id_cryptoctx->p11flags |= C_LOGIN_DONE;
3518 3722 }
3519 3723 }
3520 3724 if (rdat.data) {
3521 3725 (void) memset(rdat.data, 0, rdat.length);
3522 3726 free(rdat.data);
3523 3727 }
3524 3728
3525 3729 return (r);
3526 3730 }
3527 3731
3528 3732 /*
3529 3733 * Solaris Kerberos: added these structs in support of prompting user for
3530 3734 * missing token.
3531 3735 */
3532 3736 struct _token_entry {
3533 3737 CK_SLOT_ID slotID;
3534 3738 CK_SESSION_HANDLE session;
3535 3739 CK_TOKEN_INFO token_info;
3536 3740 };
3537 3741 struct _token_choices {
3538 3742 unsigned int numtokens;
3539 3743 struct _token_entry *token_array;
3540 3744 };
3541 3745
3542 3746
3543 3747 /*
3544 3748 * Solaris Kerberos: this is a new function that does not exist yet in the MIT
3545 3749 * code.
3546 3750 */
3547 3751 static krb5_error_code
3548 3752 pkinit_prompt_token(krb5_context context,
3549 3753 pkinit_identity_crypto_context cctx)
3550 3754 {
3551 3755 char tmpbuf[4];
3552 3756 krb5_data reply;
3553 3757 char *token_prompt = gettext("If you have a smartcard insert it now. "
3554 3758 "Press enter to continue");
3555 3759
3556 3760 reply.data = tmpbuf;
3557 3761 reply.length = sizeof(tmpbuf);
3558 3762
3559 3763 /* note, don't care about the reply */
3560 3764 return (pkinit_prompt_user(context, cctx, &reply, token_prompt, 0));
3561 3765 }
3562 3766
3563 3767 /*
3564 3768 * Solaris Kerberos: new defines for prompting support.
3565 3769 */
3566 3770 #define CHOOSE_THIS_TOKEN 0
3567 3771 #define CHOOSE_RESCAN 1
3568 3772 #define CHOOSE_SKIP 2
3569 3773 #define CHOOSE_SEE_NEXT 3
3570 3774
3571 3775 #define RESCAN_TOKENS -1
3572 3776 #define SKIP_TOKENS -2
3573 3777
3574 3778 /*
3575 3779 * Solaris Kerberos: this is a new function that does not exist yet in the MIT
3576 3780 * code.
3577 3781 *
3578 3782 * This prompts to user for various choices regarding a token to use. Note
3579 3783 * that if there is no error, choice will be set to one of:
3580 3784 * - the token_choices->token_array entry
3581 3785 * - RESCAN_TOKENS
3582 3786 * - SKIP_TOKENS
3583 3787 */
3584 3788 static int
3585 3789 pkinit_choose_tokens(krb5_context context,
3586 3790 pkinit_identity_crypto_context cctx,
3587 3791 struct _token_choices *token_choices,
3588 3792 int *choice)
3589 3793 {
3590 3794 krb5_error_code r;
3591 3795 /*
3592 3796 * Assuming that PAM_MAX_MSG_SIZE is a reasonable restriction. Note that -
3593 3797 * 2 is to account for the fact that a krb prompter to PAM conv bridge will
3594 3798 * add ": ".
3595 3799 */
3596 3800 char prompt[PAM_MAX_MSG_SIZE - 2];
3597 3801 char tmpbuf[4];
3598 3802 char tmplabel[sizeof (token_choices->token_array->token_info.label) + 1];
3599 3803 krb5_data reply;
3600 3804 int i, num_used, tmpchoice;
3601 3805
3602 3806 assert(token_choices != NULL);
3603 3807 assert(choice != NULL);
3604 3808
3605 3809 /* Create the menu prompt */
3606 3810
3607 3811 /* only need to do this once before the for loop */
3608 3812 reply.data = tmpbuf;
3609 3813
3610 3814 for (i = 0; i < token_choices->numtokens; i++) {
3611 3815
3612 3816 trim_token_label(&token_choices->token_array[i].token_info, tmplabel,
3613 3817 sizeof (tmplabel));
3614 3818
3615 3819 if (i == (token_choices->numtokens - 1)) {
3616 3820 /* no more smartcards/tokens */
3617 3821 if ((num_used = snprintf(prompt, sizeof (prompt),
3618 3822 "%s\n%d: %s \"%s\" %s %d\n%d: %s\n%d: %s\n",
3619 3823 /*
3620 3824 * TRANSLATION_NOTE: Translations of the
3621 3825 * following 5 strings must not exceed 450
3622 3826 * bytes total.
3623 3827 */
3624 3828 gettext("Select one of the following and press enter:"),
3625 3829 CHOOSE_THIS_TOKEN, gettext("Use smartcard"), tmplabel,
3626 3830 gettext("in slot"), token_choices->token_array[i].slotID,
3627 3831 CHOOSE_RESCAN, gettext("Rescan for newly inserted smartcard"),
3628 3832 CHOOSE_SKIP, gettext("Skip smartcard authentication")))
3629 3833 >= sizeof (prompt)) {
3630 3834 pkiDebug("pkinit_choose_tokens: buffer overflow num_used: %d,"
3631 3835 " sizeof prompt: %d\n", num_used, sizeof (prompt));
3632 3836 krb5_set_error_message(context, EINVAL,
3633 3837 gettext("In pkinit_choose_tokens: prompt size"
3634 3838 " %d exceeds prompt buffer size %d"),
3635 3839 num_used, sizeof(prompt));
3636 3840 (void) snprintf(prompt, sizeof (prompt), "%s",
3637 3841 gettext("Error: PKINIT prompt message is too large for buffer, "
3638 3842 "please alert the system administrator. Press enter to "
3639 3843 "continue"));
3640 3844 reply.length = sizeof(tmpbuf);
3641 3845 if ((r = pkinit_prompt_user(context, cctx, &reply, prompt, 0)) != 0 )
3642 3846 return (r);
3643 3847 return (EINVAL);
3644 3848 }
3645 3849 } else {
3646 3850 if ((num_used = snprintf(prompt, sizeof (prompt),
3647 3851 "%s\n%d: %s \"%s\" %s %d\n%d: %s\n%d: %s\n%d: %s\n",
3648 3852 /*
3649 3853 * TRANSLATION_NOTE: Translations of the
3650 3854 * following 6 strings must not exceed 445
3651 3855 * bytes total.
3652 3856 */
3653 3857 gettext("Select one of the following and press enter:"),
3654 3858 CHOOSE_THIS_TOKEN, gettext("Use smartcard"), tmplabel,
3655 3859 gettext("in slot"), token_choices->token_array[i].slotID,
3656 3860 CHOOSE_RESCAN, gettext("Rescan for newly inserted smartcard"),
3657 3861 CHOOSE_SKIP, gettext("Skip smartcard authentication"),
3658 3862 CHOOSE_SEE_NEXT, gettext("See next smartcard")))
3659 3863 >= sizeof (prompt)) {
3660 3864
3661 3865 pkiDebug("pkinit_choose_tokens: buffer overflow num_used: %d,"
3662 3866 " sizeof prompt: %d\n", num_used, sizeof (prompt));
3663 3867 krb5_set_error_message(context, EINVAL,
3664 3868 gettext("In pkinit_choose_tokens: prompt size"
3665 3869 " %d exceeds prompt buffer size %d"),
3666 3870 num_used, sizeof(prompt));
3667 3871 (void) snprintf(prompt, sizeof (prompt), "%s",
3668 3872 gettext("Error: PKINIT prompt message is too large for buffer, "
3669 3873 "please alert the system administrator. Press enter to "
3670 3874 "continue"));
3671 3875 reply.length = sizeof(tmpbuf);
3672 3876 if ((r = pkinit_prompt_user(context, cctx, &reply, prompt, 0)) != 0 )
3673 3877 return (r);
3674 3878 return (EINVAL);
3675 3879 }
3676 3880 }
3677 3881
3678 3882 /*
3679 3883 * reply.length needs to be reset to length of tmpbuf before calling
3680 3884 * prompter
3681 3885 */
3682 3886 reply.length = sizeof(tmpbuf);
3683 3887 if ((r = pkinit_prompt_user(context, cctx, &reply, prompt, 0)) != 0 )
3684 3888 return (r);
3685 3889
3686 3890 if (reply.length == 0) {
3687 3891 return (EINVAL);
3688 3892 } else {
3689 3893 char *cp = reply.data;
3690 3894 /* reply better be digits */
3691 3895 while (*cp != NULL) {
3692 3896 if (!isdigit(*cp++))
3693 3897 return (EINVAL);
3694 3898 }
3695 3899 errno = 0;
3696 3900 tmpchoice = (int) strtol(reply.data, (char **)NULL, 10);
3697 3901 if (errno != 0)
3698 3902 return (errno);
3699 3903 }
3700 3904
3701 3905 switch (tmpchoice) {
3702 3906 case CHOOSE_THIS_TOKEN:
3703 3907 *choice = i; /* chosen entry of token_choices->token_array */
3704 3908 return (0);
3705 3909 case CHOOSE_RESCAN:
3706 3910 *choice = RESCAN_TOKENS; /* rescan for new smartcard */
3707 3911 return (0);
3708 3912 case CHOOSE_SKIP:
3709 3913 *choice = SKIP_TOKENS; /* skip smartcard auth */
3710 3914 return (0);
3711 3915 case CHOOSE_SEE_NEXT: /* see next smartcard */
3712 3916 continue;
3713 3917 default:
3714 3918 return (EINVAL);
3715 3919 }
3716 3920 }
3717 3921
3718 3922 return (0);
3719 3923 }
3720 3924
3721 3925 /*
3722 3926 * Solaris Kerberos: this is a new function that does not exist yet in the MIT
3723 3927 * code.
3724 3928 *
3725 3929 * Note, this isn't the best solution to providing a function to check the
3726 3930 * certs in a token however I wanted to avoid rewriting a bunch of code so I
3727 3931 * settled for some duplication of processing.
3728 3932 */
3729 3933 static krb5_error_code
3730 3934 check_load_certs(krb5_context context,
3731 3935 CK_SESSION_HANDLE session,
3732 3936 pkinit_plg_crypto_context plg_cryptoctx,
3733 3937 pkinit_req_crypto_context req_cryptoctx,
3734 3938 pkinit_identity_crypto_context id_cryptoctx,
3735 3939 krb5_principal princ,
3736 3940 int do_matching,
3737 3941 int load_cert)
3738 3942 {
3739 3943 CK_OBJECT_CLASS cls;
3740 3944 CK_OBJECT_HANDLE obj;
3741 3945 CK_ATTRIBUTE attrs[4];
3742 3946 CK_ULONG count;
3743 3947 CK_CERTIFICATE_TYPE certtype;
3744 3948 CK_BYTE_PTR cert = NULL, cert_id = NULL;
3745 3949 const unsigned char *cp;
3746 3950 int i, r;
3747 3951 unsigned int nattrs;
3748 3952 X509 *x = NULL;
3749 3953
3750 3954 cls = CKO_CERTIFICATE;
3751 3955 attrs[0].type = CKA_CLASS;
3752 3956 attrs[0].pValue = &cls;
3753 3957 attrs[0].ulValueLen = sizeof cls;
3754 3958
3755 3959 certtype = CKC_X_509;
3756 3960 attrs[1].type = CKA_CERTIFICATE_TYPE;
3757 3961 attrs[1].pValue = &certtype;
3758 3962 attrs[1].ulValueLen = sizeof certtype;
3759 3963
3760 3964 nattrs = 2;
3761 3965
3762 3966 /* If a cert id and/or label were given, use them too */
3763 3967 if (id_cryptoctx->cert_id_len > 0) {
3764 3968 attrs[nattrs].type = CKA_ID;
3765 3969 attrs[nattrs].pValue = id_cryptoctx->cert_id;
3766 3970 attrs[nattrs].ulValueLen = id_cryptoctx->cert_id_len;
3767 3971 nattrs++;
3768 3972 }
3769 3973 if (id_cryptoctx->cert_label != NULL) {
3770 3974 attrs[nattrs].type = CKA_LABEL;
3771 3975 attrs[nattrs].pValue = id_cryptoctx->cert_label;
3772 3976 attrs[nattrs].ulValueLen = strlen(id_cryptoctx->cert_label);
3773 3977 nattrs++;
3774 3978 }
3775 3979
3776 3980 r = id_cryptoctx->p11->C_FindObjectsInit(session, attrs, nattrs);
3777 3981 if (r != CKR_OK) {
3778 3982 pkiDebug("C_FindObjectsInit: %s\n", pkinit_pkcs11_code_to_text(r));
3779 3983 krb5_set_error_message(context, EINVAL,
3780 3984 gettext("PKCS11 error from C_FindObjectsInit: %s"),
3781 3985 pkinit_pkcs11_code_to_text(r));
3782 3986 r = EINVAL;
3783 3987 goto out;
3784 3988 }
3785 3989
3786 3990 for (i = 0; ; i++) {
3787 3991 if (i >= MAX_CREDS_ALLOWED) {
3788 3992 r = EINVAL;
3789 3993 goto out;
3790 3994 }
3791 3995
3792 3996 /* Look for x.509 cert */
3793 3997 /* Solaris Kerberos */
3794 3998 if ((r = id_cryptoctx->p11->C_FindObjects(session, &obj, 1, &count))
3795 3999 != CKR_OK || count == 0) {
3796 4000 id_cryptoctx->creds[i] = NULL;
3797 4001 break;
3798 4002 }
3799 4003
3800 4004 /* Get cert and id len */
3801 4005 attrs[0].type = CKA_VALUE;
3802 4006 attrs[0].pValue = NULL;
3803 4007 attrs[0].ulValueLen = 0;
3804 4008
3805 4009 attrs[1].type = CKA_ID;
3806 4010 attrs[1].pValue = NULL;
3807 4011 attrs[1].ulValueLen = 0;
3808 4012
3809 4013 if ((r = id_cryptoctx->p11->C_GetAttributeValue(session,
3810 4014 obj,
3811 4015 attrs,
3812 4016 2)) != CKR_OK &&
3813 4017 r != CKR_BUFFER_TOO_SMALL) {
3814 4018 pkiDebug("C_GetAttributeValue: %s\n", pkinit_pkcs11_code_to_text(r));
3815 4019 krb5_set_error_message(context, EINVAL,
3816 4020 gettext("Error from PKCS11 C_GetAttributeValue: %s"),
3817 4021 pkinit_pkcs11_code_to_text(r));
3818 4022 r = EINVAL;
3819 4023 goto out;
3820 4024 }
3821 4025 cert = malloc((size_t) attrs[0].ulValueLen + 1);
3822 4026 if (cert == NULL) {
3823 4027 r = ENOMEM;
3824 4028 goto out;
3825 4029 }
3826 4030 cert_id = malloc((size_t) attrs[1].ulValueLen + 1);
3827 4031 if (cert_id == NULL) {
3828 4032 r = ENOMEM;
3829 4033 goto out;
3830 4034 }
3831 4035
3832 4036 /* Read the cert and id off the card */
3833 4037
3834 4038 attrs[0].type = CKA_VALUE;
3835 4039 attrs[0].pValue = cert;
3836 4040
3837 4041 attrs[1].type = CKA_ID;
3838 4042 attrs[1].pValue = cert_id;
3839 4043
3840 4044 if ((r = id_cryptoctx->p11->C_GetAttributeValue(session,
3841 4045 obj, attrs, 2)) != CKR_OK) {
3842 4046 pkiDebug("C_GetAttributeValue: %s\n", pkinit_pkcs11_code_to_text(r));
3843 4047 krb5_set_error_message(context, EINVAL,
3844 4048 gettext("Error from PKCS11 C_GetAttributeValue: %s"),
3845 4049 pkinit_pkcs11_code_to_text(r));
3846 4050 r = EINVAL;
3847 4051 goto out;
3848 4052 }
3849 4053
3850 4054 pkiDebug("cert %d size %d id %d idlen %d\n", i,
3851 4055 (int) attrs[0].ulValueLen, (int) cert_id[0],
3852 4056 (int) attrs[1].ulValueLen);
3853 4057
3854 4058 cp = (unsigned char *) cert;
3855 4059 x = d2i_X509(NULL, &cp, (int) attrs[0].ulValueLen);
3856 4060 if (x == NULL) {
3857 4061 r = EINVAL;
3858 4062 goto out;
3859 4063 }
3860 4064
3861 4065 id_cryptoctx->creds[i] = malloc(sizeof(struct _pkinit_cred_info));
3862 4066 if (id_cryptoctx->creds[i] == NULL) {
3863 4067 r = ENOMEM;
3864 4068 goto out;
3865 4069 }
3866 4070 id_cryptoctx->creds[i]->cert = x;
3867 4071 id_cryptoctx->creds[i]->key = NULL;
3868 4072 id_cryptoctx->creds[i]->cert_id = cert_id;
3869 4073 cert_id = NULL;
3870 4074 id_cryptoctx->creds[i]->cert_id_len = attrs[1].ulValueLen;
3871 4075 free(cert);
3872 4076 cert = NULL;
3873 4077 }
3874 4078 id_cryptoctx->p11->C_FindObjectsFinal(session);
3875 4079
3876 4080 if (id_cryptoctx->creds[0] == NULL || id_cryptoctx->creds[0]->cert == NULL) {
3877 4081 r = ENOENT;
3878 4082 } else if (do_matching){
3879 4083 /*
3880 4084 * Do not let pkinit_cert_matching set the primary cert in id_cryptoctx
3881 4085 * as this will be done later.
3882 4086 */
3883 4087 r = pkinit_cert_matching(context, plg_cryptoctx, req_cryptoctx,
3884 4088 id_cryptoctx, princ, FALSE);
3885 4089 }
3886 4090
3887 4091 out:
3888 4092 if ((r != 0 || !load_cert) &&
3889 4093 id_cryptoctx->creds[0] != NULL &&
3890 4094 id_cryptoctx->creds[0]->cert != NULL) {
3891 4095 /*
3892 4096 * If there's an error or load_cert isn't 1 free all the certs loaded
3893 4097 * onto id_cryptoctx.
|
↓ open down ↓ |
544 lines elided |
↑ open up ↑ |
3894 4098 */
3895 4099 (void) crypto_free_cert_info(context, plg_cryptoctx, req_cryptoctx,
3896 4100 id_cryptoctx);
3897 4101 }
3898 4102
3899 4103 if (cert)
3900 4104 free(cert);
3901 4105
3902 4106 if (cert_id)
3903 4107 free(cert_id);
3904 -
4108 +
3905 4109 return (r);
3906 4110 }
3907 4111
3908 4112 /*
3909 4113 * Solaris Kerberos: this function has been significantly modified to prompt
3910 4114 * the user in certain cases so defer to this version when resyncing MIT code.
3911 4115 *
3912 4116 * pkinit_open_session now does several things including prompting the user if
3913 4117 * do_matching is set which indicates the code is executing in a client
3914 4118 * context. This function fills out a pkinit_identity_crypto_context with a
3915 4119 * set of certs and a open session if a token can be found that matches all
3916 4120 * supplied criteria. If no token is found then the user is prompted one time
3917 4121 * to insert their token. If there is more than one token that matches all
3918 4122 * client criteria the user is prompted to make a choice if in client context.
3919 4123 * If do_matching is false (KDC context) then the first token matching all
3920 4124 * server criteria is chosen.
3921 4125 */
3922 4126 static krb5_error_code
3923 4127 pkinit_open_session(krb5_context context,
3924 4128 pkinit_plg_crypto_context plg_cryptoctx,
3925 4129 pkinit_req_crypto_context req_cryptoctx,
3926 4130 pkinit_identity_crypto_context cctx,
3927 4131 krb5_principal princ,
3928 4132 int do_matching)
3929 4133 {
3930 4134 int i, r;
3931 4135 CK_ULONG count = 0;
3932 4136 CK_SLOT_ID_PTR slotlist = NULL, tmpslotlist = NULL;
3933 4137 CK_TOKEN_INFO tinfo;
3934 4138 krb5_boolean tokenmatch = FALSE;
3935 4139 CK_SESSION_HANDLE tmpsession = NULL;
3936 4140 struct _token_choices token_choices;
3937 4141 int choice = 0;
3938 4142
3939 4143 if (cctx->session != CK_INVALID_HANDLE)
3940 4144 return 0; /* session already open */
3941 4145
3942 4146 /* Load module */
3943 4147 if (cctx->p11_module == NULL) {
3944 4148 cctx->p11_module =
3945 4149 pkinit_C_LoadModule(cctx->p11_module_name, &cctx->p11);
3946 4150 if (cctx->p11_module == NULL)
3947 4151 return KRB5KDC_ERR_PREAUTH_FAILED;
3948 4152 }
3949 4153
3950 4154 /* Init */
3951 4155 /* Solaris Kerberos: Don't fail if cryptoki is already initialized */
3952 4156 r = cctx->p11->C_Initialize(NULL);
3953 4157 if (r != CKR_OK && r != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
3954 4158 pkiDebug("C_Initialize: %s\n", pkinit_pkcs11_code_to_text(r));
3955 4159 krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
3956 4160 gettext("Error from PKCS11 C_Initialize: %s"),
3957 4161 pkinit_pkcs11_code_to_text(r));
|
↓ open down ↓ |
43 lines elided |
↑ open up ↑ |
3958 4162 return KRB5KDC_ERR_PREAUTH_FAILED;
3959 4163 }
3960 4164
3961 4165 (void) memset(&token_choices, 0, sizeof(token_choices));
3962 4166
3963 4167 /*
3964 4168 * Solaris Kerberos:
3965 4169 * If C_Initialize was already called by the process before the pkinit
3966 4170 * module was loaded then record that fact.
3967 4171 * "finalize_pkcs11" is used by pkinit_fini_pkcs11 to determine whether
3968 - * or not C_Finalize() should be called.
4172 + * or not C_Finalize() should be called.
3969 4173 */
3970 4174 cctx->finalize_pkcs11 =
3971 4175 (r == CKR_CRYPTOKI_ALREADY_INITIALIZED ? FALSE : TRUE);
3972 4176 /*
3973 4177 * First make sure that is an applicable slot otherwise fail.
3974 4178 *
3975 4179 * Start by getting a count of all slots with or without tokens.
3976 4180 */
3977 4181
3978 4182 if ((r = cctx->p11->C_GetSlotList(FALSE, NULL, &count)) != CKR_OK) {
3979 4183 pkiDebug("C_GetSlotList: %s\n", pkinit_pkcs11_code_to_text(r));
3980 4184 krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
3981 4185 gettext("Error trying to get PKCS11 slot list: %s"),
3982 4186 pkinit_pkcs11_code_to_text(r));
3983 4187 r = KRB5KDC_ERR_PREAUTH_FAILED;
3984 4188 goto out;
3985 4189 }
3986 4190
3987 4191 if (count == 0) {
3988 4192 /* There are no slots so bail */
3989 4193 r = KRB5KDC_ERR_PREAUTH_FAILED;
3990 4194 krb5_set_error_message(context, r,
3991 4195 gettext("No PKCS11 slots found"));
3992 4196 pkiDebug("pkinit_open_session: no slots, count: %d\n", count);
3993 4197 goto out;
3994 4198 } else if (cctx->slotid != PK_NOSLOT) {
3995 4199 /* See if any of the slots match the specified slotID */
3996 4200 tmpslotlist = malloc(count * sizeof (CK_SLOT_ID));
3997 4201 if (tmpslotlist == NULL) {
3998 4202 krb5_set_error_message(context, ENOMEM,
3999 4203 gettext("Memory allocation error:"));
4000 4204 r = KRB5KDC_ERR_PREAUTH_FAILED;
4001 4205 goto out;
4002 4206 }
4003 4207 if ((r = cctx->p11->C_GetSlotList(FALSE, tmpslotlist, &count)) != CKR_OK) {
4004 4208 krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
4005 4209 gettext("Error trying to get PKCS11 slot list: %s"),
4006 4210 pkinit_pkcs11_code_to_text(r));
4007 4211 pkiDebug("C_GetSlotList: %s\n", pkinit_pkcs11_code_to_text(r));
4008 4212 r = KRB5KDC_ERR_PREAUTH_FAILED;
4009 4213 goto out;
4010 4214 }
4011 4215
4012 4216 for (i = 0; i < count && cctx->slotid != tmpslotlist[i]; i++)
4013 4217 continue;
4014 4218
4015 4219 if (i >= count) {
|
↓ open down ↓ |
37 lines elided |
↑ open up ↑ |
4016 4220 /* no slots match */
4017 4221 r = KRB5KDC_ERR_PREAUTH_FAILED;
4018 4222 krb5_set_error_message(context, r,
4019 4223 gettext("Requested PKCS11 slot ID %d not found"),
4020 4224 cctx->slotid);
4021 4225 pkiDebug("open_session: no matching slot found for slotID %d\n",
4022 4226 cctx->slotid);
4023 4227 goto out;
4024 4228 }
4025 4229 }
4026 -
4230 +
4027 4231 tryagain:
4028 4232 /* get count of slots that have tokens */
4029 4233 if ((r = cctx->p11->C_GetSlotList(TRUE, NULL, &count)) != CKR_OK) {
4030 4234 pkiDebug("C_GetSlotList: %s\n", pkinit_pkcs11_code_to_text(r));
4031 4235 krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
4032 4236 gettext("Error trying to get PKCS11 slot list: %s"),
4033 4237 pkinit_pkcs11_code_to_text(r));
4034 4238 r = KRB5KDC_ERR_PREAUTH_FAILED;
4035 4239 goto out;
4036 4240 }
4037 4241
4038 4242 if (count == 0) {
4039 4243 /*
4040 4244 * Note, never prompt if !do_matching as this implies KDC side
4041 4245 * processing
4042 4246 */
4043 4247 if (!(cctx->p11flags & C_PROMPTED_USER) && do_matching) {
4044 4248 /* found slot(s) but no token so prompt and try again */
4045 4249 if ((r = pkinit_prompt_token(context, cctx)) == 0) {
4046 4250 cctx->p11flags |= C_PROMPTED_USER;
4047 4251 goto tryagain;
4048 4252 } else {
4049 4253 pkiDebug("open_session: prompt for token/smart card failed\n");
4050 4254 krb5_set_error_message(context, r,
4051 4255 gettext("Prompt for token/smart card failed"));
4052 4256 r = KRB5KDC_ERR_PREAUTH_FAILED;
4053 4257 goto out;
4054 4258 }
4055 4259
4056 4260 } else {
4057 4261 /* already prompted once so bailing */
|
↓ open down ↓ |
21 lines elided |
↑ open up ↑ |
4058 4262 r = KRB5KDC_ERR_PREAUTH_FAILED;
4059 4263 krb5_set_error_message(context, r,
4060 4264 gettext("No smart card tokens found"));
4061 4265 pkiDebug("pkinit_open_session: no token, already prompted\n");
4062 4266 goto out;
4063 4267 }
4064 4268 }
4065 4269
4066 4270 if (slotlist != NULL)
4067 4271 free(slotlist);
4068 -
4272 +
4069 4273 slotlist = malloc(count * sizeof (CK_SLOT_ID));
4070 4274 if (slotlist == NULL) {
4071 4275 krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
4072 4276 gettext("Memory allocation error"));
4073 4277 r = KRB5KDC_ERR_PREAUTH_FAILED;
4074 4278 goto out;
4075 4279 }
4076 4280 /*
4077 4281 * Solaris Kerberos: get list of PKCS11 slotid's that have tokens.
4078 4282 */
4079 4283 if (cctx->p11->C_GetSlotList(TRUE, slotlist, &count) != CKR_OK) {
4080 4284 krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
4081 4285 gettext("Error trying to get PKCS11 slot list: %s"),
4082 4286 pkinit_pkcs11_code_to_text(r));
4083 4287 pkiDebug("C_GetSlotList: %s\n", pkinit_pkcs11_code_to_text(r));
4084 4288 r = KRB5KDC_ERR_PREAUTH_FAILED;
4085 4289 goto out;
4086 4290 }
4087 4291
4088 4292 token_choices.numtokens = 0;
4089 4293 token_choices.token_array = malloc(count * sizeof (*token_choices.token_array));
4090 4294 if (token_choices.token_array == NULL) {
4091 4295 r = KRB5KDC_ERR_PREAUTH_FAILED;
4092 4296 krb5_set_error_message(context, r,
4093 4297 gettext("Memory allocation error"));
4094 4298 goto out;
4095 4299 }
4096 4300
4097 4301 /* examine all the tokens */
4098 4302 for (i = 0; i < count; i++) {
4099 4303 /*
4100 4304 * Solaris Kerberos: if a slotid was specified skip slots that don't
4101 4305 * match.
4102 4306 */
4103 4307 if (cctx->slotid != PK_NOSLOT && cctx->slotid != slotlist[i])
4104 4308 continue;
4105 4309
4106 4310 /* Open session */
4107 4311 if ((r = cctx->p11->C_OpenSession(slotlist[i], CKF_SERIAL_SESSION,
4108 4312 NULL, NULL, &tmpsession)) != CKR_OK) {
4109 4313 pkiDebug("C_OpenSession: %s\n", pkinit_pkcs11_code_to_text(r));
4110 4314 krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
4111 4315 gettext("Error trying to open PKCS11 session: %s"),
4112 4316 pkinit_pkcs11_code_to_text(r));
4113 4317 r = KRB5KDC_ERR_PREAUTH_FAILED;
4114 4318 goto out;
4115 4319 }
4116 4320
4117 4321 /* Get token info */
4118 4322 if ((r = cctx->p11->C_GetTokenInfo(slotlist[i], &tinfo)) != CKR_OK) {
4119 4323 pkiDebug("C_GetTokenInfo: %s\n", pkinit_pkcs11_code_to_text(r));
4120 4324 krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
4121 4325 gettext("Error trying to read PKCS11 token: %s"),
4122 4326 pkinit_pkcs11_code_to_text(r));
4123 4327 r = KRB5KDC_ERR_PREAUTH_FAILED;
4124 4328 cctx->p11->C_CloseSession(tmpsession);
4125 4329 goto out;
4126 4330 }
4127 4331
4128 4332 if (cctx->token_label == NULL) {
4129 4333 /*
4130 4334 * If the token doesn't require login to examine the certs then
4131 4335 * let's check the certs out to see if any match the criteria if
4132 4336 * any.
4133 4337 */
4134 4338 if (!(tinfo.flags & CKF_LOGIN_REQUIRED)) {
4135 4339 /*
4136 4340 * It's okay to check the certs if we don't have to login but
4137 4341 * don't load the certs onto cctx at this point, this will be
4138 4342 * done later in this function for the chosen token.
4139 4343 */
4140 4344 if ((r = check_load_certs(context, tmpsession, plg_cryptoctx,
4141 4345 req_cryptoctx, cctx, princ,
4142 4346 do_matching, 0)) == 0) {
4143 4347 tokenmatch = TRUE;
4144 4348 } else if (r != ENOENT){
4145 4349 r = KRB5KDC_ERR_PREAUTH_FAILED;
4146 4350 cctx->p11->C_CloseSession(tmpsession);
4147 4351 goto out;
4148 4352 } else {
4149 4353 /* ignore ENOENT here */
4150 4354 r = 0;
4151 4355 }
4152 4356 } else {
4153 4357 tokenmatch = TRUE;
4154 4358 }
4155 4359 } else {
4156 4360 /* + 1 so tokenlabelstr can be \0 terminated */
4157 4361 char tokenlabelstr[sizeof (tinfo.label) + 1];
4158 4362
4159 4363 /*
4160 4364 * Convert token label into C string with trailing white space
4161 4365 * trimmed.
4162 4366 */
4163 4367 trim_token_label(&tinfo, tokenlabelstr, sizeof (tokenlabelstr));
4164 4368
4165 4369 pkiDebug("open_session: slotid %d token found: \"%s\", "
4166 4370 "cctx->token_label: \"%s\"\n",
4167 4371 slotlist[i], tokenlabelstr, (char *) cctx->token_label);
4168 4372
4169 4373 if (!strcmp(cctx->token_label, tokenlabelstr)) {
4170 4374 if (!(tinfo.flags & CKF_LOGIN_REQUIRED)) {
4171 4375 /*
4172 4376 * It's okay to check the certs if we don't have to login but
4173 4377 * don't load the certs onto cctx at this point, this will be
4174 4378 * done later in this function for the chosen token.
4175 4379 */
4176 4380 if ((r = check_load_certs(context, tmpsession, plg_cryptoctx,
4177 4381 req_cryptoctx, cctx, princ,
4178 4382 do_matching, 0)) == 0) {
4179 4383 tokenmatch = TRUE;
4180 4384 } else if (r != ENOENT){
4181 4385 r = KRB5KDC_ERR_PREAUTH_FAILED;
4182 4386 cctx->p11->C_CloseSession(tmpsession);
4183 4387 goto out;
4184 4388 } else {
4185 4389 /* ignore ENOENT here */
4186 4390 r = 0;
4187 4391 }
4188 4392 } else {
4189 4393 tokenmatch = TRUE;
4190 4394 }
4191 4395 }
4192 4396 }
4193 4397
4194 4398 if (tokenmatch == TRUE) {
4195 4399 /* add the token to token_choices.token_array */
4196 4400 token_choices.token_array[token_choices.numtokens].slotID = slotlist[i];
4197 4401 token_choices.token_array[token_choices.numtokens].session = tmpsession;
4198 4402 token_choices.token_array[token_choices.numtokens].token_info = tinfo;
4199 4403 token_choices.numtokens++;
4200 4404 /* !do_matching implies we take the first matching token */
4201 4405 if (!do_matching)
4202 4406 break;
4203 4407 else
4204 4408 tokenmatch = FALSE;
4205 4409 } else {
4206 4410 cctx->p11->C_CloseSession(tmpsession);
4207 4411 }
4208 4412 }
4209 4413
4210 4414 if (token_choices.numtokens == 0) {
4211 4415 /*
4212 4416 * Solaris Kerberos: prompt for token one time if there was no token
4213 4417 * and do_matching is 1 (see earlier comment about do_matching).
4214 4418 */
4215 4419 if (!(cctx->p11flags & C_PROMPTED_USER) && do_matching) {
4216 4420 if ((r = pkinit_prompt_token(context, cctx)) == 0) {
4217 4421 cctx->p11flags |= C_PROMPTED_USER;
4218 4422 goto tryagain;
4219 4423 } else {
4220 4424 pkiDebug("open_session: prompt for token/smart card failed\n");
4221 4425 krb5_set_error_message(context, r,
4222 4426 gettext("Prompt for token/smart card failed"));
4223 4427 r = KRB5KDC_ERR_PREAUTH_FAILED;
4224 4428 goto out;
4225 4429 }
4226 4430 } else {
4227 4431 r = KRB5KDC_ERR_PREAUTH_FAILED;
4228 4432 krb5_set_error_message(context, r,
4229 4433 gettext("No smart card tokens found"));
4230 4434 pkiDebug("open_session: no matching token found\n");
4231 4435 goto out;
4232 4436 }
4233 4437 } else if (token_choices.numtokens == 1) {
4234 4438 if ((token_choices.token_array[0].token_info.flags & CKF_LOGIN_REQUIRED) &&
4235 4439 !(cctx->p11flags & C_PROMPTED_USER) &&
4236 4440 do_matching) {
4237 4441 if ((r = pkinit_choose_tokens(context, cctx, &token_choices, &choice)) != 0) {
4238 4442 pkiDebug("pkinit_open_session: pkinit_choose_tokens failed: %d\n", r);
4239 4443 r = KRB5KDC_ERR_PREAUTH_FAILED;
4240 4444 krb5_set_error_message(context, r,
4241 4445 gettext("Prompt for token/smart card failed"));
4242 4446 goto out;
4243 4447 }
4244 4448 if (choice == RESCAN_TOKENS) {
4245 4449 /* rescan for new smartcard/token */
4246 4450 for (i = 0; i < token_choices.numtokens; i++) {
4247 4451 /* close all sessions */
4248 4452 cctx->p11->C_CloseSession(token_choices.token_array[i].session);
4249 4453 }
4250 4454 free(token_choices.token_array);
4251 4455 token_choices.token_array = NULL;
4252 4456 token_choices.numtokens = 0;
4253 4457 goto tryagain;
4254 4458 } else if (choice == SKIP_TOKENS) {
4255 4459 /* do not use smartcard/token for auth */
4256 4460 cctx->p11flags |= (C_PROMPTED_USER|C_SKIP_PKCS11_AUTH);
4257 4461 r = KRB5KDC_ERR_PREAUTH_FAILED;
4258 4462 goto out;
4259 4463 } else {
4260 4464 cctx->p11flags |= C_PROMPTED_USER;
4261 4465 }
4262 4466 } else {
4263 4467 choice = 0; /* really the only choice is the first token_array entry */
4264 4468 }
4265 4469 } else if (!(cctx->p11flags & C_PROMPTED_USER) && do_matching) {
4266 4470 /* > 1 token so present menu of token choices, let the user decide. */
4267 4471 if ((r = pkinit_choose_tokens(context, cctx, &token_choices, &choice)) != 0) {
4268 4472 pkiDebug("pkinit_open_session: pkinit_choose_tokens failed: %d\n", r);
4269 4473 r = KRB5KDC_ERR_PREAUTH_FAILED;
4270 4474 krb5_set_error_message(context, r,
4271 4475 gettext("Prompt for token/smart card failed"));
4272 4476 goto out;
4273 4477 }
4274 4478 if (choice == RESCAN_TOKENS) {
4275 4479 /* rescan for new smartcard/token */
4276 4480 for (i = 0; i < token_choices.numtokens; i++) {
4277 4481 /* close all sessions */
4278 4482 cctx->p11->C_CloseSession(token_choices.token_array[i].session);
4279 4483 }
4280 4484 free(token_choices.token_array);
4281 4485 token_choices.token_array = NULL;
4282 4486 token_choices.numtokens = 0;
4283 4487 goto tryagain;
4284 4488 } else if (choice == SKIP_TOKENS) {
4285 4489 /* do not use smartcard/token for auth */
4286 4490 cctx->p11flags |= (C_PROMPTED_USER|C_SKIP_PKCS11_AUTH);
4287 4491 r = KRB5KDC_ERR_PREAUTH_FAILED;
4288 4492 goto out;
4289 4493 } else {
4290 4494 cctx->p11flags |= C_PROMPTED_USER;
4291 4495 }
4292 4496 } else {
4293 4497 r = KRB5KDC_ERR_PREAUTH_FAILED;
4294 4498 goto out;
4295 4499 }
4296 4500
4297 4501 cctx->slotid = token_choices.token_array[choice].slotID;
4298 4502 cctx->session = token_choices.token_array[choice].session;
4299 4503
4300 4504 pkiDebug("open_session: slotid %d (%d of %d)\n", (int) cctx->slotid,
4301 4505 i + 1, (int) count);
4302 4506
4303 4507 /* Login if needed */
4304 4508 /* Solaris Kerberos: added cctx->p11flags check */
4305 4509 if ((token_choices.token_array[choice].token_info.flags & CKF_LOGIN_REQUIRED) &&
4306 4510 !(cctx->p11flags & C_LOGIN_DONE)) {
4307 4511 r = pkinit_login(context, cctx, &token_choices.token_array[choice].token_info);
4308 4512 }
4309 4513
4310 4514 if (r == 0) {
4311 4515 /* Doing this again to load the certs into cctx. */
4312 4516 r = check_load_certs(context, cctx->session, plg_cryptoctx,
4313 4517 req_cryptoctx, cctx, princ, do_matching, 1);
4314 4518 }
4315 4519
4316 4520 out:
4317 4521 if (slotlist != NULL)
4318 4522 free(slotlist);
4319 4523
4320 4524 if (tmpslotlist != NULL)
4321 4525 free(tmpslotlist);
4322 4526
4323 4527 if (token_choices.token_array != NULL) {
4324 4528 if (r != 0) {
4325 4529 /* close all sessions if there's an error */
4326 4530 for (i = 0; i < token_choices.numtokens; i++) {
4327 4531 cctx->p11->C_CloseSession(token_choices.token_array[i].session);
4328 4532 }
4329 4533 cctx->session = CK_INVALID_HANDLE;
4330 4534 } else {
4331 4535 /* close sessions not chosen */
4332 4536 for (i = 0; i < token_choices.numtokens; i++) {
4333 4537 if (i != choice) {
4334 4538 cctx->p11->C_CloseSession(token_choices.token_array[i].session);
4335 4539 }
4336 4540 }
4337 4541 }
4338 4542 free(token_choices.token_array);
4339 4543 }
4340 4544
4341 4545 return (r);
4342 4546 }
4343 4547
4344 4548 /*
4345 4549 * Look for a key that's:
4346 4550 * 1. private
4347 4551 * 2. capable of the specified operation (usually signing or decrypting)
4348 4552 * 3. RSA (this may be wrong but it's all we can do for now)
4349 4553 * 4. matches the id of the cert we chose
4350 4554 *
4351 4555 * You must call pkinit_get_certs before calling pkinit_find_private_key
4352 4556 * (that's because we need the ID of the private key)
4353 4557 *
4354 4558 * pkcs11 says the id of the key doesn't have to match that of the cert, but
4355 4559 * I can't figure out any other way to decide which key to use.
4356 4560 *
4357 4561 * We should only find one key that fits all the requirements.
4358 4562 * If there are more than one, we just take the first one.
4359 4563 */
4360 4564
|
↓ open down ↓ |
282 lines elided |
↑ open up ↑ |
4361 4565 /* ARGSUSED */
4362 4566 krb5_error_code
4363 4567 pkinit_find_private_key(pkinit_identity_crypto_context id_cryptoctx,
4364 4568 CK_ATTRIBUTE_TYPE usage,
4365 4569 CK_OBJECT_HANDLE *objp)
4366 4570 {
4367 4571 CK_OBJECT_CLASS cls;
4368 4572 CK_ATTRIBUTE attrs[4];
4369 4573 CK_ULONG count;
4370 4574 CK_KEY_TYPE keytype;
4575 + RSA *rsa;
4371 4576 unsigned int nattrs = 0;
4372 4577 int r;
4373 4578 #ifdef PKINIT_USE_KEY_USAGE
4374 4579 CK_BBOOL true_false;
4375 4580 #endif
4376 4581
4377 4582 cls = CKO_PRIVATE_KEY;
4378 4583 attrs[nattrs].type = CKA_CLASS;
4379 4584 attrs[nattrs].pValue = &cls;
4380 4585 attrs[nattrs].ulValueLen = sizeof cls;
4381 4586 nattrs++;
4382 4587
4383 4588 #ifdef PKINIT_USE_KEY_USAGE
4384 4589 /*
4385 4590 * Some cards get confused if you try to specify a key usage,
4386 4591 * so don't, and hope for the best. This will fail if you have
4387 4592 * several keys with the same id and different usages but I have
4388 4593 * not seen this on real cards.
4389 4594 */
4390 4595 true_false = TRUE;
4391 4596 attrs[nattrs].type = usage;
4392 4597 attrs[nattrs].pValue = &true_false;
4393 4598 attrs[nattrs].ulValueLen = sizeof true_false;
4394 4599 nattrs++;
4395 4600 #endif
4396 4601
4397 4602 keytype = CKK_RSA;
4398 4603 attrs[nattrs].type = CKA_KEY_TYPE;
4399 4604 attrs[nattrs].pValue = &keytype;
4400 4605 attrs[nattrs].ulValueLen = sizeof keytype;
4401 4606 nattrs++;
4402 4607
4403 4608 attrs[nattrs].type = CKA_ID;
4404 4609 attrs[nattrs].pValue = id_cryptoctx->cert_id;
4405 4610 attrs[nattrs].ulValueLen = id_cryptoctx->cert_id_len;
4406 4611 nattrs++;
4407 4612
4408 4613 r = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs, nattrs);
4409 4614 if (r != CKR_OK) {
4410 4615 pkiDebug("krb5_pkinit_sign_data: C_FindObjectsInit: %s\n",
4411 4616 pkinit_pkcs11_code_to_text(r));
4412 4617 return KRB5KDC_ERR_PREAUTH_FAILED;
4413 4618 }
4414 4619
4415 4620 r = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session, objp, 1, &count);
4416 4621 id_cryptoctx->p11->C_FindObjectsFinal(id_cryptoctx->session);
4417 4622 pkiDebug("found %d private keys (%s)\n", (int) count, pkinit_pkcs11_code_to_text(r));
4418 4623
4419 4624 /*
4420 4625 * Solaris Kerberos:
|
↓ open down ↓ |
40 lines elided |
↑ open up ↑ |
4421 4626 * The CKA_ID may not be correctly set for the private key. For e.g. when
4422 4627 * storing a private key in softtoken pktool(1) doesn't generate or store
4423 4628 * a CKA_ID for the private key. Another way to identify the private key is
4424 4629 * to look for a private key with the same RSA modulus as the public key
4425 4630 * in the certificate.
4426 4631 */
4427 4632 if (r == CKR_OK && count != 1) {
4428 4633
4429 4634 EVP_PKEY *priv;
4430 4635 X509 *cert;
4636 + const BIGNUM *rsan;
4431 4637 unsigned int n_len;
4432 4638 unsigned char *n_bytes;
4433 4639
4434 4640 cert = sk_X509_value(id_cryptoctx->my_certs, 0);
4435 4641 priv = X509_get_pubkey(cert);
4436 4642 if (priv == NULL) {
4437 4643 pkiDebug("Failed to extract pub key from cert\n");
4438 4644 return KRB5KDC_ERR_PREAUTH_FAILED;
4439 4645 }
4440 4646
4441 4647 nattrs = 0;
4442 4648 cls = CKO_PRIVATE_KEY;
4443 4649 attrs[nattrs].type = CKA_CLASS;
4444 4650 attrs[nattrs].pValue = &cls;
4445 4651 attrs[nattrs].ulValueLen = sizeof cls;
4446 4652 nattrs++;
4447 4653
4448 4654 #ifdef PKINIT_USE_KEY_USAGE
4449 4655 true_false = TRUE;
4450 4656 attrs[nattrs].type = usage;
4451 4657 attrs[nattrs].pValue = &true_false;
|
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
4452 4658 attrs[nattrs].ulValueLen = sizeof true_false;
4453 4659 nattrs++;
4454 4660 #endif
4455 4661
4456 4662 keytype = CKK_RSA;
4457 4663 attrs[nattrs].type = CKA_KEY_TYPE;
4458 4664 attrs[nattrs].pValue = &keytype;
4459 4665 attrs[nattrs].ulValueLen = sizeof keytype;
4460 4666 nattrs++;
4461 4667
4462 - n_len = BN_num_bytes(priv->pkey.rsa->n);
4668 +#if OPENSSL_VERSION_NUMBER < 0x10100000L
4669 + rsa = priv->pkey.rsa;
4670 + rsan = rsa->n;
4671 + n_len = BN_num_bytes(rsan);
4672 +#else
4673 + rsa = EVP_PKEY_get0_RSA(priv);
4674 + RSA_get0_key(rsa, &rsan, NULL, NULL);
4675 + n_len = RSA_size(rsa);
4676 +#endif
4463 4677 n_bytes = (unsigned char *) malloc((size_t) n_len);
4464 4678 if (n_bytes == NULL) {
4465 4679 return (ENOMEM);
4466 4680 }
4467 4681
4468 - if (BN_bn2bin(priv->pkey.rsa->n, n_bytes) == 0) {
4682 + if (BN_bn2bin(rsan, n_bytes) == 0) {
4469 4683 free (n_bytes);
4470 - pkiDebug("zero-byte key modulus\n");
4684 + pkiDebug("zero-byte key modulus\n");
4471 4685 return KRB5KDC_ERR_PREAUTH_FAILED;
4472 4686 }
4473 4687
4474 4688 attrs[nattrs].type = CKA_MODULUS;
4475 - attrs[nattrs].ulValueLen = n_len;
4689 + attrs[nattrs].ulValueLen = n_len;
4476 4690 attrs[nattrs].pValue = n_bytes;
4477 4691
4478 4692 nattrs++;
4479 4693
4480 4694 r = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs, nattrs);
4481 4695 free (n_bytes);
4482 4696 if (r != CKR_OK) {
4483 4697 pkiDebug("krb5_pkinit_sign_data: C_FindObjectsInit: %s\n",
4484 4698 pkinit_pkcs11_code_to_text(r));
4485 4699 return KRB5KDC_ERR_PREAUTH_FAILED;
4486 4700 }
4487 4701
4488 4702 r = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session, objp, 1, &count);
4489 4703 id_cryptoctx->p11->C_FindObjectsFinal(id_cryptoctx->session);
4490 4704 pkiDebug("found %d private keys (%s)\n", (int) count, pkinit_pkcs11_code_to_text(r));
4491 4705
4492 4706 }
4493 4707
4494 4708 if (r != CKR_OK || count < 1)
4495 4709 return KRB5KDC_ERR_PREAUTH_FAILED;
4496 4710 return 0;
4497 4711 }
4498 4712 #endif
4499 4713
4500 4714 /* ARGSUSED */
4501 4715 static krb5_error_code
4502 4716 pkinit_decode_data_fs(krb5_context context,
4503 4717 pkinit_identity_crypto_context id_cryptoctx,
4504 4718 unsigned char *data,
4505 4719 unsigned int data_len,
4506 4720 unsigned char **decoded_data,
4507 4721 unsigned int *decoded_data_len)
4508 4722 {
4509 4723 if (decode_data(decoded_data, decoded_data_len, data, data_len,
4510 4724 id_cryptoctx->my_key, sk_X509_value(id_cryptoctx->my_certs,
4511 4725 id_cryptoctx->cert_index)) <= 0) {
4512 4726 pkiDebug("failed to decode data\n");
4513 4727 return KRB5KDC_ERR_PREAUTH_FAILED;
4514 4728 }
4515 4729 return 0;
4516 4730 }
4517 4731
4518 4732 #ifndef WITHOUT_PKCS11
4519 4733 #ifdef SILLYDECRYPT
4520 4734 CK_RV
4521 4735 pkinit_C_Decrypt(pkinit_identity_crypto_context id_cryptoctx,
4522 4736 CK_BYTE_PTR pEncryptedData,
4523 4737 CK_ULONG ulEncryptedDataLen,
4524 4738 CK_BYTE_PTR pData,
4525 4739 CK_ULONG_PTR pulDataLen)
4526 4740 {
4527 4741 CK_RV rv = CKR_OK;
4528 4742
4529 4743 rv = id_cryptoctx->p11->C_Decrypt(id_cryptoctx->session, pEncryptedData,
4530 4744 ulEncryptedDataLen, pData, pulDataLen);
4531 4745 if (rv == CKR_OK) {
4532 4746 pkiDebug("pData %x *pulDataLen %d\n", (int) pData, (int) *pulDataLen);
4533 4747 }
4534 4748 return rv;
4535 4749 }
4536 4750 #endif
4537 4751
4538 4752 static krb5_error_code
4539 4753 pkinit_decode_data_pkcs11(krb5_context context,
4540 4754 pkinit_identity_crypto_context id_cryptoctx,
4541 4755 unsigned char *data,
4542 4756 unsigned int data_len,
4543 4757 unsigned char **decoded_data,
4544 4758 unsigned int *decoded_data_len)
4545 4759 {
4546 4760 CK_OBJECT_HANDLE obj;
4547 4761 CK_ULONG len;
4548 4762 CK_MECHANISM mech;
4549 4763 unsigned char *cp;
4550 4764 int r;
4551 4765
4552 4766 /*
4553 4767 * Solaris Kerberos: assume session is open and libpkcs11 funcs have been
4554 4768 * loaded.
4555 4769 */
4556 4770 assert(id_cryptoctx->p11 != NULL);
4557 4771
4558 4772 /* Solaris Kerberos: Login, if needed, to access private object */
4559 4773 if (!(id_cryptoctx->p11flags & C_LOGIN_DONE)) {
4560 4774 CK_TOKEN_INFO tinfo;
4561 4775
4562 4776 r = id_cryptoctx->p11->C_GetTokenInfo(id_cryptoctx->slotid, &tinfo);
4563 4777 if (r != 0)
4564 4778 return r;
4565 4779
4566 4780 r = pkinit_login(context, id_cryptoctx, &tinfo);
4567 4781 if (r != 0)
4568 4782 return r;
4569 4783 }
4570 4784
4571 4785 r = pkinit_find_private_key(id_cryptoctx, CKA_DECRYPT, &obj);
4572 4786 if (r != 0)
4573 4787 return r;
4574 4788
4575 4789 mech.mechanism = CKM_RSA_PKCS;
4576 4790 mech.pParameter = NULL;
4577 4791 mech.ulParameterLen = 0;
4578 4792
4579 4793 if ((r = id_cryptoctx->p11->C_DecryptInit(id_cryptoctx->session, &mech,
4580 4794 obj)) != CKR_OK) {
4581 4795 pkiDebug("C_DecryptInit: 0x%x\n", (int) r);
4582 4796 return KRB5KDC_ERR_PREAUTH_FAILED;
4583 4797 }
4584 4798 pkiDebug("data_len = %d\n", data_len);
4585 4799 cp = (unsigned char *)malloc((size_t) data_len);
4586 4800 if (cp == NULL)
4587 4801 return ENOMEM;
4588 4802 len = data_len;
4589 4803 #ifdef SILLYDECRYPT
4590 4804 pkiDebug("session %x edata %x edata_len %d data %x datalen @%x %d\n",
4591 4805 (int) id_cryptoctx->session, (int) data, (int) data_len, (int) cp,
4592 4806 (int) &len, (int) len);
4593 4807 if ((r = pkinit_C_Decrypt(id_cryptoctx, data, (CK_ULONG) data_len,
4594 4808 cp, &len)) != CKR_OK) {
4595 4809 #else
4596 4810 if ((r = id_cryptoctx->p11->C_Decrypt(id_cryptoctx->session, data,
4597 4811 (CK_ULONG) data_len, cp, &len)) != CKR_OK) {
4598 4812 #endif
4599 4813 pkiDebug("C_Decrypt: %s\n", pkinit_pkcs11_code_to_text(r));
4600 4814 if (r == CKR_BUFFER_TOO_SMALL)
4601 4815 pkiDebug("decrypt %d needs %d\n", (int) data_len, (int) len);
4602 4816 return KRB5KDC_ERR_PREAUTH_FAILED;
4603 4817 }
4604 4818 pkiDebug("decrypt %d -> %d\n", (int) data_len, (int) len);
4605 4819 *decoded_data_len = len;
4606 4820 *decoded_data = cp;
4607 4821
4608 4822 return 0;
4609 4823 }
4610 4824 #endif
4611 4825
4612 4826 krb5_error_code
4613 4827 pkinit_decode_data(krb5_context context,
4614 4828 pkinit_identity_crypto_context id_cryptoctx,
4615 4829 unsigned char *data,
4616 4830 unsigned int data_len,
4617 4831 unsigned char **decoded_data,
4618 4832 unsigned int *decoded_data_len)
4619 4833 {
4620 4834 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
4621 4835
4622 4836 if (id_cryptoctx->pkcs11_method != 1)
4623 4837 retval = pkinit_decode_data_fs(context, id_cryptoctx, data, data_len,
4624 4838 decoded_data, decoded_data_len);
4625 4839 #ifndef WITHOUT_PKCS11
4626 4840 else
4627 4841 retval = pkinit_decode_data_pkcs11(context, id_cryptoctx, data,
4628 4842 data_len, decoded_data, decoded_data_len);
4629 4843 #endif
4630 4844
4631 4845 return retval;
4632 4846 }
4633 4847
4634 4848 /* ARGSUSED */
4635 4849 static krb5_error_code
4636 4850 pkinit_sign_data_fs(krb5_context context,
4637 4851 pkinit_identity_crypto_context id_cryptoctx,
4638 4852 unsigned char *data,
4639 4853 unsigned int data_len,
4640 4854 unsigned char **sig,
4641 4855 unsigned int *sig_len)
4642 4856 {
4643 4857 if (create_signature(sig, sig_len, data, data_len,
4644 4858 id_cryptoctx->my_key) != 0) {
4645 4859 pkiDebug("failed to create the signature\n");
4646 4860 return KRB5KDC_ERR_PREAUTH_FAILED;
4647 4861 }
4648 4862 return 0;
4649 4863 }
4650 4864
4651 4865 #ifndef WITHOUT_PKCS11
4652 4866 static krb5_error_code
4653 4867 pkinit_sign_data_pkcs11(krb5_context context,
4654 4868 pkinit_identity_crypto_context id_cryptoctx,
4655 4869 unsigned char *data,
4656 4870 unsigned int data_len,
4657 4871 unsigned char **sig,
4658 4872 unsigned int *sig_len)
4659 4873 {
4660 4874 CK_OBJECT_HANDLE obj;
4661 4875 CK_ULONG len;
4662 4876 CK_MECHANISM mech;
4663 4877 unsigned char *cp;
4664 4878 int r;
4665 4879
4666 4880 /*
4667 4881 * Solaris Kerberos: assume session is open and libpkcs11 funcs have been
4668 4882 * loaded.
4669 4883 */
4670 4884 assert(id_cryptoctx->p11 != NULL);
4671 4885
4672 4886 /* Solaris Kerberos: Login, if needed, to access private object */
4673 4887 if (!(id_cryptoctx->p11flags & C_LOGIN_DONE)) {
4674 4888 CK_TOKEN_INFO tinfo;
4675 4889
4676 4890 r = id_cryptoctx->p11->C_GetTokenInfo(id_cryptoctx->slotid, &tinfo);
4677 4891 if (r != 0)
4678 4892 return r;
4679 4893
4680 4894 r = pkinit_login(context, id_cryptoctx, &tinfo);
4681 4895 if (r != 0)
4682 4896 return r;
4683 4897 }
4684 4898
4685 4899 r = pkinit_find_private_key(id_cryptoctx, CKA_SIGN, &obj);
4686 4900 if (r != 0 )
4687 4901 return r;
4688 4902
4689 4903 mech.mechanism = id_cryptoctx->mech;
4690 4904 mech.pParameter = NULL;
4691 4905 mech.ulParameterLen = 0;
4692 4906
4693 4907 if ((r = id_cryptoctx->p11->C_SignInit(id_cryptoctx->session, &mech,
4694 4908 obj)) != CKR_OK) {
4695 4909 pkiDebug("C_SignInit: %s\n", pkinit_pkcs11_code_to_text(r));
4696 4910 return KRB5KDC_ERR_PREAUTH_FAILED;
4697 4911 }
4698 4912
4699 4913 /*
4700 4914 * Key len would give an upper bound on sig size, but there's no way to
4701 4915 * get that. So guess, and if it's too small, re-malloc.
4702 4916 */
4703 4917 len = PK_SIGLEN_GUESS;
4704 4918 cp = (unsigned char *)malloc((size_t) len);
4705 4919 if (cp == NULL)
4706 4920 return ENOMEM;
4707 4921
4708 4922 r = id_cryptoctx->p11->C_Sign(id_cryptoctx->session, data,
4709 4923 (CK_ULONG) data_len, cp, &len);
4710 4924 if (r == CKR_BUFFER_TOO_SMALL || (r == CKR_OK && len >= PK_SIGLEN_GUESS)) {
4711 4925 free(cp);
4712 4926 pkiDebug("C_Sign realloc %d\n", (int) len);
4713 4927 cp = (unsigned char *)malloc((size_t) len);
4714 4928 r = id_cryptoctx->p11->C_Sign(id_cryptoctx->session, data,
4715 4929 (CK_ULONG) data_len, cp, &len);
4716 4930 }
4717 4931 if (r != CKR_OK) {
4718 4932 pkiDebug("C_Sign: %s\n", pkinit_pkcs11_code_to_text(r));
4719 4933 return KRB5KDC_ERR_PREAUTH_FAILED;
4720 4934 }
4721 4935 pkiDebug("sign %d -> %d\n", (int) data_len, (int) len);
4722 4936 *sig_len = len;
4723 4937 *sig = cp;
4724 4938
4725 4939 return 0;
4726 4940 }
4727 4941 #endif
4728 4942
4729 4943 krb5_error_code
4730 4944 pkinit_sign_data(krb5_context context,
4731 4945 pkinit_identity_crypto_context id_cryptoctx,
4732 4946 unsigned char *data,
4733 4947 unsigned int data_len,
4734 4948 unsigned char **sig,
4735 4949 unsigned int *sig_len)
4736 4950 {
4737 4951 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
4738 4952
4739 4953 if (id_cryptoctx == NULL || id_cryptoctx->pkcs11_method != 1)
4740 4954 retval = pkinit_sign_data_fs(context, id_cryptoctx, data, data_len,
4741 4955 sig, sig_len);
4742 4956 #ifndef WITHOUT_PKCS11
4743 4957 else
4744 4958 retval = pkinit_sign_data_pkcs11(context, id_cryptoctx, data, data_len,
4745 4959 sig, sig_len);
4746 4960 #endif
4747 4961
4748 4962 return retval;
4749 4963 }
4750 4964
4751 4965
4752 4966 static krb5_error_code
4753 4967 decode_data(unsigned char **out_data, unsigned int *out_data_len,
4754 4968 unsigned char *data, unsigned int data_len,
4755 4969 EVP_PKEY *pkey, X509 *cert)
4756 4970 {
4757 4971 /* Solaris Kerberos */
4758 4972 int len;
4759 4973 unsigned char *buf = NULL;
4760 4974 int buf_len = 0;
4761 4975
4762 4976 /* Solaris Kerberos */
4763 4977 if (out_data == NULL || out_data_len == NULL)
4764 4978 return EINVAL;
4765 4979
4766 4980 if (cert && !X509_check_private_key(cert, pkey)) {
|
↓ open down ↓ |
281 lines elided |
↑ open up ↑ |
4767 4981 pkiDebug("private key does not match certificate\n");
4768 4982 /* Solaris Kerberos */
4769 4983 return EINVAL;
4770 4984 }
4771 4985
4772 4986 buf_len = EVP_PKEY_size(pkey);
4773 4987 buf = (unsigned char *)malloc((size_t) buf_len + 10);
4774 4988 if (buf == NULL)
4775 4989 return ENOMEM;
4776 4990
4777 -#if OPENSSL_VERSION_NUMBER < 0x10000000L
4778 - len = EVP_PKEY_decrypt(buf, data, (int)data_len, pkey);
4779 -#else
4780 4991 len = EVP_PKEY_decrypt_old(buf, data, (int)data_len, pkey);
4781 -#endif
4782 4992 if (len <= 0) {
4783 4993 pkiDebug("unable to decrypt received data (len=%d)\n", data_len);
4784 4994 /* Solaris Kerberos */
4785 4995 free(buf);
4786 4996 return KRB5KRB_ERR_GENERIC;
4787 4997 }
4788 4998 *out_data = buf;
4789 4999 *out_data_len = len;
4790 5000
4791 5001 return 0;
4792 5002 }
4793 5003
4794 5004 static krb5_error_code
4795 5005 create_signature(unsigned char **sig, unsigned int *sig_len,
4796 5006 unsigned char *data, unsigned int data_len, EVP_PKEY *pkey)
4797 5007 {
4798 5008 krb5_error_code retval = ENOMEM;
4799 - EVP_MD_CTX md_ctx;
5009 + EVP_MD_CTX *md_ctx;
4800 5010
4801 5011 if (pkey == NULL)
4802 5012 /* Solaris Kerberos */
4803 5013 return EINVAL;
4804 5014
4805 - EVP_VerifyInit(&md_ctx, EVP_sha1());
4806 - EVP_SignUpdate(&md_ctx, data, data_len);
5015 + if ((md_ctx = EVP_MD_CTX_new()) == NULL)
5016 + return EINVAL;
5017 +
5018 + EVP_VerifyInit(md_ctx, EVP_sha1());
5019 + EVP_SignUpdate(md_ctx, data, data_len);
4807 5020 *sig_len = EVP_PKEY_size(pkey);
4808 5021 if ((*sig = (unsigned char *) malloc((size_t) *sig_len)) == NULL)
4809 5022 goto cleanup;
4810 - EVP_SignFinal(&md_ctx, *sig, sig_len, pkey);
5023 + EVP_SignFinal(md_ctx, *sig, sig_len, pkey);
4811 5024
4812 5025 retval = 0;
4813 5026
4814 5027 cleanup:
4815 - EVP_MD_CTX_cleanup(&md_ctx);
5028 + EVP_MD_CTX_free(md_ctx);
4816 5029
4817 5030 return retval;
4818 5031 }
4819 5032
4820 5033 /*
4821 5034 * Note:
4822 5035 * This is not the routine the KDC uses to get its certificate.
4823 5036 * This routine is intended to be called by the client
4824 5037 * to obtain the KDC's certificate from some local storage
4825 5038 * to be sent as a hint in its request to the KDC.
4826 5039 */
4827 5040 /* ARGSUSED */
4828 5041 krb5_error_code
4829 5042 pkinit_get_kdc_cert(krb5_context context,
4830 5043 pkinit_plg_crypto_context plg_cryptoctx,
4831 5044 pkinit_req_crypto_context req_cryptoctx,
4832 5045 pkinit_identity_crypto_context id_cryptoctx,
4833 5046 krb5_principal princ)
4834 5047 {
4835 5048 /* Solaris Kerberos */
4836 5049 if (req_cryptoctx == NULL)
4837 5050 return EINVAL;
4838 5051
4839 5052 req_cryptoctx->received_cert = NULL;
4840 5053 return 0;
4841 5054 }
4842 5055
4843 5056 /* ARGSUSED */
4844 5057 static krb5_error_code
4845 5058 pkinit_get_certs_pkcs12(krb5_context context,
4846 5059 pkinit_plg_crypto_context plg_cryptoctx,
4847 5060 pkinit_req_crypto_context req_cryptoctx,
4848 5061 pkinit_identity_opts *idopts,
4849 5062 pkinit_identity_crypto_context id_cryptoctx,
4850 5063 krb5_principal princ)
4851 5064 {
4852 5065 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
4853 5066 X509 *x = NULL;
4854 5067 PKCS12 *p12 = NULL;
4855 5068 int ret;
4856 5069 FILE *fp;
4857 5070 EVP_PKEY *y = NULL;
4858 5071
4859 5072 if (idopts->cert_filename == NULL) {
4860 5073 /* Solaris Kerberos: Improved error messages */
4861 5074 krb5_set_error_message(context, retval,
4862 5075 gettext("Failed to get certificate location"));
4863 5076 pkiDebug("%s: failed to get user's cert location\n", __FUNCTION__);
4864 5077 goto cleanup;
4865 5078 }
4866 5079
4867 5080 if (idopts->key_filename == NULL) {
4868 5081 /* Solaris Kerberos: Improved error messages */
4869 5082 krb5_set_error_message(context, retval,
4870 5083 gettext("Failed to get private key location"));
4871 5084 pkiDebug("%s: failed to get user's private key location\n", __FUNCTION__);
4872 5085 goto cleanup;
4873 5086 }
4874 5087
4875 5088 fp = fopen(idopts->cert_filename, "rb");
4876 5089 if (fp == NULL) {
4877 5090 /* Solaris Kerberos: Improved error messages */
4878 5091 krb5_set_error_message(context, retval,
4879 5092 gettext("Failed to open PKCS12 file '%s': %s"),
4880 5093 idopts->cert_filename, error_message(errno));
4881 5094 pkiDebug("Failed to open PKCS12 file '%s', error %d\n",
4882 5095 idopts->cert_filename, errno);
4883 5096 goto cleanup;
4884 5097 }
4885 5098
4886 5099 p12 = d2i_PKCS12_fp(fp, NULL);
4887 5100 (void) fclose(fp);
4888 5101 if (p12 == NULL) {
4889 5102 krb5_set_error_message(context, retval,
4890 5103 gettext("Failed to decode PKCS12 file '%s' contents"),
4891 5104 idopts->cert_filename);
4892 5105 pkiDebug("Failed to decode PKCS12 file '%s' contents\n",
4893 5106 idopts->cert_filename);
4894 5107 goto cleanup;
4895 5108 }
4896 5109 /*
4897 5110 * Try parsing with no pass phrase first. If that fails,
4898 5111 * prompt for the pass phrase and try again.
4899 5112 */
4900 5113 ret = PKCS12_parse(p12, NULL, &y, &x, NULL);
4901 5114 if (ret == 0) {
4902 5115 krb5_data rdat;
4903 5116 krb5_prompt kprompt;
4904 5117 krb5_prompt_type prompt_type;
4905 5118 int r = 0;
4906 5119 char prompt_string[128];
4907 5120 char prompt_reply[128];
4908 5121 /* Solaris Kerberos */
4909 5122 char *prompt_prefix = gettext("Pass phrase for");
4910 5123
4911 5124 pkiDebug("Initial PKCS12_parse with no password failed\n");
4912 5125
4913 5126 if (id_cryptoctx->PIN != NULL) {
4914 5127 /* Solaris Kerberos: use PIN if set */
4915 5128 rdat.data = id_cryptoctx->PIN;
4916 5129 /* note rdat.length isn't needed in this case */
4917 5130 } else {
4918 5131 (void) memset(prompt_reply, '\0', sizeof(prompt_reply));
4919 5132 rdat.data = prompt_reply;
4920 5133 rdat.length = sizeof(prompt_reply);
4921 5134
4922 5135 r = snprintf(prompt_string, sizeof(prompt_string), "%s %s",
4923 5136 prompt_prefix, idopts->cert_filename);
4924 5137 if (r >= sizeof(prompt_string)) {
4925 5138 pkiDebug("Prompt string, '%s %s', is too long!\n",
4926 5139 prompt_prefix, idopts->cert_filename);
4927 5140 goto cleanup;
4928 5141 }
4929 5142 kprompt.prompt = prompt_string;
4930 5143 kprompt.hidden = 1;
4931 5144 kprompt.reply = &rdat;
4932 5145 prompt_type = KRB5_PROMPT_TYPE_PREAUTH;
4933 5146
4934 5147 /* PROMPTER_INVOCATION */
4935 5148 k5int_set_prompt_types(context, &prompt_type);
4936 5149 r = (*id_cryptoctx->prompter)(context, id_cryptoctx->prompter_data,
4937 5150 NULL, NULL, 1, &kprompt);
4938 5151 k5int_set_prompt_types(context, NULL);
4939 5152 }
4940 5153
4941 5154 ret = PKCS12_parse(p12, rdat.data, &y, &x, NULL);
4942 5155 if (ret == 0) {
4943 5156 /* Solaris Kerberos: Improved error messages */
4944 5157 krb5_set_error_message(context, retval,
4945 5158 gettext("Failed to parse PKCS12 file '%s' with password"),
4946 5159 idopts->cert_filename);
4947 5160 pkiDebug("Seconde PKCS12_parse with password failed\n");
4948 5161 goto cleanup;
4949 5162 }
4950 5163 }
4951 5164 id_cryptoctx->creds[0] = malloc(sizeof(struct _pkinit_cred_info));
4952 5165 if (id_cryptoctx->creds[0] == NULL)
4953 5166 goto cleanup;
4954 5167 id_cryptoctx->creds[0]->cert = x;
4955 5168 #ifndef WITHOUT_PKCS11
4956 5169 id_cryptoctx->creds[0]->cert_id = NULL;
4957 5170 id_cryptoctx->creds[0]->cert_id_len = 0;
4958 5171 #endif
4959 5172 id_cryptoctx->creds[0]->key = y;
4960 5173 id_cryptoctx->creds[1] = NULL;
4961 5174
4962 5175 retval = 0;
4963 5176
4964 5177 cleanup:
4965 5178 if (p12)
4966 5179 PKCS12_free(p12);
4967 5180 if (retval) {
4968 5181 if (x != NULL)
4969 5182 X509_free(x);
4970 5183 if (y != NULL)
4971 5184 EVP_PKEY_free(y);
4972 5185 }
4973 5186 return retval;
4974 5187 }
4975 5188
4976 5189 static krb5_error_code
4977 5190 pkinit_load_fs_cert_and_key(krb5_context context,
4978 5191 pkinit_identity_crypto_context id_cryptoctx,
4979 5192 char *certname,
4980 5193 char *keyname,
4981 5194 int cindex)
4982 5195 {
4983 5196 krb5_error_code retval;
4984 5197 X509 *x = NULL;
4985 5198 EVP_PKEY *y = NULL;
4986 5199
4987 5200 /* load the certificate */
4988 5201 retval = get_cert(certname, &x);
4989 5202 if (retval != 0 || x == NULL) {
4990 5203 /* Solaris Kerberos: Improved error messages */
4991 5204 krb5_set_error_message(context, retval,
4992 5205 gettext("Failed to load user's certificate from %s: %s"),
4993 5206 certname, error_message(retval));
4994 5207 pkiDebug("failed to load user's certificate from '%s'\n", certname);
4995 5208 goto cleanup;
4996 5209 }
4997 5210 retval = get_key(keyname, &y);
4998 5211 if (retval != 0 || y == NULL) {
4999 5212 /* Solaris Kerberos: Improved error messages */
5000 5213 krb5_set_error_message(context, retval,
5001 5214 gettext("Failed to load user's private key from %s: %s"),
5002 5215 keyname, error_message(retval));
5003 5216 pkiDebug("failed to load user's private key from '%s'\n", keyname);
5004 5217 goto cleanup;
5005 5218 }
5006 5219
5007 5220 id_cryptoctx->creds[cindex] = malloc(sizeof(struct _pkinit_cred_info));
5008 5221 if (id_cryptoctx->creds[cindex] == NULL) {
5009 5222 retval = ENOMEM;
5010 5223 goto cleanup;
5011 5224 }
5012 5225 id_cryptoctx->creds[cindex]->cert = x;
5013 5226 #ifndef WITHOUT_PKCS11
5014 5227 id_cryptoctx->creds[cindex]->cert_id = NULL;
5015 5228 id_cryptoctx->creds[cindex]->cert_id_len = 0;
5016 5229 #endif
5017 5230 id_cryptoctx->creds[cindex]->key = y;
5018 5231 id_cryptoctx->creds[cindex+1] = NULL;
5019 5232
5020 5233 retval = 0;
5021 5234
5022 5235 cleanup:
5023 5236 if (retval) {
5024 5237 if (x != NULL)
5025 5238 X509_free(x);
5026 5239 if (y != NULL)
5027 5240 EVP_PKEY_free(y);
5028 5241 }
5029 5242 return retval;
5030 5243 }
5031 5244
5032 5245 /* ARGSUSED */
5033 5246 static krb5_error_code
5034 5247 pkinit_get_certs_fs(krb5_context context,
5035 5248 pkinit_plg_crypto_context plg_cryptoctx,
5036 5249 pkinit_req_crypto_context req_cryptoctx,
5037 5250 pkinit_identity_opts *idopts,
5038 5251 pkinit_identity_crypto_context id_cryptoctx,
5039 5252 krb5_principal princ)
5040 5253 {
5041 5254 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
5042 5255
5043 5256 if (idopts->cert_filename == NULL) {
5044 5257 pkiDebug("%s: failed to get user's cert location\n", __FUNCTION__);
5045 5258 goto cleanup;
5046 5259 }
5047 5260
5048 5261 if (idopts->key_filename == NULL) {
5049 5262 pkiDebug("%s: failed to get user's private key location\n",
5050 5263 __FUNCTION__);
5051 5264 goto cleanup;
5052 5265 }
5053 5266
5054 5267 retval = pkinit_load_fs_cert_and_key(context, id_cryptoctx,
5055 5268 idopts->cert_filename,
5056 5269 idopts->key_filename, 0);
5057 5270 cleanup:
5058 5271 return retval;
5059 5272 }
5060 5273
5061 5274 /* ARGSUSED */
5062 5275 static krb5_error_code
5063 5276 pkinit_get_certs_dir(krb5_context context,
5064 5277 pkinit_plg_crypto_context plg_cryptoctx,
5065 5278 pkinit_req_crypto_context req_cryptoctx,
5066 5279 pkinit_identity_opts *idopts,
5067 5280 pkinit_identity_crypto_context id_cryptoctx,
5068 5281 krb5_principal princ)
5069 5282 {
5070 5283 /* Solaris Kerberos */
5071 5284 krb5_error_code retval = KRB5KRB_ERR_GENERIC;
5072 5285 DIR *d = NULL;
5073 5286 struct dirent *dentry = NULL;
5074 5287 char certname[1024];
5075 5288 char keyname[1024];
5076 5289 int i = 0, len;
5077 5290 char *dirname, *suf;
5078 5291
5079 5292 /* Solaris Kerberos */
5080 5293 if (idopts == NULL)
5081 5294 return EINVAL;
5082 5295
5083 5296 if (idopts->cert_filename == NULL) {
5084 5297 pkiDebug("%s: failed to get user's certificate directory location\n",
5085 5298 __FUNCTION__);
5086 5299 return ENOENT;
5087 5300 }
5088 5301
5089 5302 dirname = idopts->cert_filename;
5090 5303 d = opendir(dirname);
5091 5304 if (d == NULL) {
5092 5305 /* Solaris Kerberos: Improved error messages */
5093 5306 krb5_set_error_message(context, errno,
5094 5307 gettext("Failed to open directory \"%s\": %s"),
5095 5308 dirname, error_message(errno));
5096 5309 return errno;
5097 5310 }
5098 5311
5099 5312 /*
5100 5313 * We'll assume that certs are named XXX.crt and the corresponding
5101 5314 * key is named XXX.key
5102 5315 */
5103 5316 while ((i < MAX_CREDS_ALLOWED) && (dentry = readdir(d)) != NULL) {
5104 5317 /* Ignore subdirectories and anything starting with a dot */
5105 5318 #ifdef DT_DIR
5106 5319 if (dentry->d_type == DT_DIR)
5107 5320 continue;
5108 5321 #endif
5109 5322 if (dentry->d_name[0] == '.')
5110 5323 continue;
5111 5324 len = strlen(dentry->d_name);
5112 5325 if (len < 5)
5113 5326 continue;
5114 5327 suf = dentry->d_name + (len - 4);
5115 5328 if (strncmp(suf, ".crt", 4) != 0)
5116 5329 continue;
5117 5330
5118 5331 /* Checked length */
5119 5332 if (strlen(dirname) + strlen(dentry->d_name) + 2 > sizeof(certname)) {
5120 5333 pkiDebug("%s: Path too long -- directory '%s' and file '%s'\n",
5121 5334 __FUNCTION__, dirname, dentry->d_name);
5122 5335 continue;
5123 5336 }
5124 5337 (void) snprintf(certname, sizeof(certname), "%s/%s", dirname, dentry->d_name);
5125 5338 (void) snprintf(keyname, sizeof(keyname), "%s/%s", dirname, dentry->d_name);
5126 5339 len = strlen(keyname);
5127 5340 keyname[len - 3] = 'k';
5128 5341 keyname[len - 2] = 'e';
5129 5342 keyname[len - 1] = 'y';
5130 5343
5131 5344 retval = pkinit_load_fs_cert_and_key(context, id_cryptoctx,
5132 5345 certname, keyname, i);
5133 5346 if (retval == 0) {
5134 5347 pkiDebug("%s: Successfully loaded cert (and key) for %s\n",
5135 5348 __FUNCTION__, dentry->d_name);
5136 5349 i++;
5137 5350 }
5138 5351 else
5139 5352 continue;
5140 5353 }
5141 5354
5142 5355 if (i == 0) {
5143 5356 /* Solaris Kerberos: Improved error messages */
5144 5357 krb5_set_error_message(context, ENOENT,
5145 5358 gettext("No suitable cert/key pairs found in directory '%s'"),
|
↓ open down ↓ |
320 lines elided |
↑ open up ↑ |
5146 5359 idopts->cert_filename);
5147 5360 pkiDebug("%s: No cert/key pairs found in directory '%s'\n",
5148 5361 __FUNCTION__, idopts->cert_filename);
5149 5362 retval = ENOENT;
5150 5363 goto cleanup;
5151 5364 }
5152 5365
5153 5366 retval = 0;
5154 5367
5155 5368 cleanup:
5156 - if (d)
5369 + if (d)
5157 5370 (void) closedir(d);
5158 5371
5159 5372 return retval;
5160 5373 }
5161 5374
5162 5375 #ifndef WITHOUT_PKCS11
5163 5376 /* ARGSUSED */
5164 5377 static krb5_error_code
5165 5378 pkinit_get_certs_pkcs11(krb5_context context,
5166 5379 pkinit_plg_crypto_context plg_cryptoctx,
5167 5380 pkinit_req_crypto_context req_cryptoctx,
5168 5381 pkinit_identity_opts *idopts,
5169 5382 pkinit_identity_crypto_context id_cryptoctx,
5170 5383 krb5_principal princ,
5171 5384 int do_matching)
5172 5385 {
5173 5386 #ifdef PKINIT_USE_MECH_LIST
5174 5387 CK_MECHANISM_TYPE_PTR mechp = NULL;
5175 5388 CK_MECHANISM_INFO info;
5176 5389 #endif
5177 5390
5178 5391 if (id_cryptoctx->p11flags & C_SKIP_PKCS11_AUTH)
5179 5392 return KRB5KDC_ERR_PREAUTH_FAILED;
5180 5393
5181 5394 /* Copy stuff from idopts -> id_cryptoctx */
5182 5395 if (idopts->p11_module_name != NULL) {
5183 5396 id_cryptoctx->p11_module_name = strdup(idopts->p11_module_name);
5184 5397 if (id_cryptoctx->p11_module_name == NULL)
5185 5398 return ENOMEM;
5186 5399 }
5187 5400 if (idopts->token_label != NULL) {
5188 5401 id_cryptoctx->token_label = strdup(idopts->token_label);
5189 5402 if (id_cryptoctx->token_label == NULL)
5190 5403 return ENOMEM;
5191 5404 }
5192 5405 if (idopts->cert_label != NULL) {
5193 5406 id_cryptoctx->cert_label = strdup(idopts->cert_label);
5194 5407 if (id_cryptoctx->cert_label == NULL)
5195 5408 return ENOMEM;
5196 5409 }
5197 5410 if (idopts->PIN != NULL) {
5198 5411 id_cryptoctx->PIN = strdup(idopts->PIN);
5199 5412 if (id_cryptoctx->PIN == NULL)
5200 5413 return ENOMEM;
5201 5414 }
5202 5415 /* Convert the ascii cert_id string into a binary blob */
5203 5416 /*
5204 5417 * Solaris Kerberos:
5205 5418 * If the cert_id_string is empty then behave in a similar way to how
5206 5419 * an empty certlabel is treated - i.e. don't fail now but rather continue
5207 5420 * as though the certid wasn't specified.
5208 5421 */
5209 5422 if (idopts->cert_id_string != NULL && strlen(idopts->cert_id_string) != 0) {
5210 5423 BIGNUM *bn = NULL;
5211 5424 BN_hex2bn(&bn, idopts->cert_id_string);
5212 5425 if (bn == NULL)
5213 5426 return ENOMEM;
5214 5427 id_cryptoctx->cert_id_len = BN_num_bytes(bn);
5215 5428 id_cryptoctx->cert_id = malloc((size_t) id_cryptoctx->cert_id_len);
5216 5429 if (id_cryptoctx->cert_id == NULL) {
5217 5430 BN_free(bn);
5218 5431 return ENOMEM;
5219 5432 }
5220 5433 BN_bn2bin(bn, id_cryptoctx->cert_id);
5221 5434 BN_free(bn);
5222 5435 }
5223 5436 id_cryptoctx->slotid = idopts->slotid;
5224 5437 id_cryptoctx->pkcs11_method = 1;
5225 5438
5226 5439 #ifndef PKINIT_USE_MECH_LIST
5227 5440 /*
5228 5441 * We'd like to use CKM_SHA1_RSA_PKCS for signing if it's available, but
5229 5442 * many cards seems to be confused about whether they are capable of
5230 5443 * this or not. The safe thing seems to be to ignore the mechanism list,
5231 5444 * always use CKM_RSA_PKCS and calculate the sha1 digest ourselves.
5232 5445 */
5233 5446
5234 5447 id_cryptoctx->mech = CKM_RSA_PKCS;
5235 5448 #else
5236 5449 if ((r = id_cryptoctx->p11->C_GetMechanismList(id_cryptoctx->slotid, NULL,
5237 5450 &count)) != CKR_OK || count <= 0) {
5238 5451 pkiDebug("C_GetMechanismList: %s\n", pkinit_pkcs11_code_to_text(r));
5239 5452 return KRB5KDC_ERR_PREAUTH_FAILED;
5240 5453 }
5241 5454 mechp = (CK_MECHANISM_TYPE_PTR) malloc(count * sizeof (CK_MECHANISM_TYPE));
5242 5455 if (mechp == NULL)
5243 5456 return ENOMEM;
5244 5457 if ((r = id_cryptoctx->p11->C_GetMechanismList(id_cryptoctx->slotid,
5245 5458 mechp, &count)) != CKR_OK) {
5246 5459 free(mechp);
5247 5460 return KRB5KDC_ERR_PREAUTH_FAILED;
5248 5461 }
5249 5462 for (i = 0; i < count; i++) {
5250 5463 if ((r = id_cryptoctx->p11->C_GetMechanismInfo(id_cryptoctx->slotid,
5251 5464 mechp[i], &info)) != CKR_OK) {
5252 5465 free(mechp);
5253 5466 return KRB5KDC_ERR_PREAUTH_FAILED;
5254 5467 }
5255 5468 #ifdef DEBUG_MECHINFO
5256 5469 pkiDebug("mech %x flags %x\n", (int) mechp[i], (int) info.flags);
5257 5470 if ((info.flags & (CKF_SIGN|CKF_DECRYPT)) == (CKF_SIGN|CKF_DECRYPT))
5258 5471 pkiDebug(" this mech is good for sign & decrypt\n");
5259 5472 #endif
5260 5473 if (mechp[i] == CKM_RSA_PKCS) {
5261 5474 /* This seems backwards... */
5262 5475 id_cryptoctx->mech =
5263 5476 (info.flags & CKF_SIGN) ? CKM_SHA1_RSA_PKCS : CKM_RSA_PKCS;
5264 5477 }
5265 5478 }
5266 5479 free(mechp);
5267 5480
5268 5481 pkiDebug("got %d mechs from card\n", (int) count);
5269 5482 #endif
5270 5483
5271 5484 return (pkinit_open_session(context, plg_cryptoctx, req_cryptoctx,
5272 5485 id_cryptoctx, princ, do_matching));
5273 5486 }
5274 5487 #endif
5275 5488
5276 5489 /* ARGSUSED */
5277 5490 static void
5278 5491 free_cred_info(krb5_context context,
5279 5492 pkinit_identity_crypto_context id_cryptoctx,
5280 5493 struct _pkinit_cred_info *cred)
5281 5494 {
5282 5495 if (cred != NULL) {
5283 5496 if (cred->cert != NULL)
5284 5497 X509_free(cred->cert);
5285 5498 if (cred->key != NULL)
5286 5499 EVP_PKEY_free(cred->key);
5287 5500 #ifndef WITHOUT_PKCS11
5288 5501 if (cred->cert_id != NULL)
5289 5502 free(cred->cert_id);
5290 5503 #endif
5291 5504 free(cred);
5292 5505 }
5293 5506 }
5294 5507
5295 5508 /* ARGSUSED */
5296 5509 krb5_error_code
5297 5510 crypto_free_cert_info(krb5_context context,
5298 5511 pkinit_plg_crypto_context plg_cryptoctx,
5299 5512 pkinit_req_crypto_context req_cryptoctx,
5300 5513 pkinit_identity_crypto_context id_cryptoctx)
5301 5514 {
5302 5515 int i;
5303 5516
5304 5517 if (id_cryptoctx == NULL)
5305 5518 return EINVAL;
5306 5519
5307 5520 for (i = 0; i < MAX_CREDS_ALLOWED; i++) {
5308 5521 if (id_cryptoctx->creds[i] != NULL) {
5309 5522 free_cred_info(context, id_cryptoctx, id_cryptoctx->creds[i]);
5310 5523 id_cryptoctx->creds[i] = NULL;
5311 5524 }
5312 5525 }
5313 5526 return 0;
5314 5527 }
5315 5528
5316 5529 krb5_error_code
5317 5530 crypto_load_certs(krb5_context context,
5318 5531 pkinit_plg_crypto_context plg_cryptoctx,
5319 5532 pkinit_req_crypto_context req_cryptoctx,
5320 5533 pkinit_identity_opts *idopts,
5321 5534 pkinit_identity_crypto_context id_cryptoctx,
5322 5535 krb5_principal princ,
5323 5536 int do_matching)
5324 5537 {
5325 5538 krb5_error_code retval;
5326 5539
5327 5540 switch(idopts->idtype) {
5328 5541 case IDTYPE_FILE:
5329 5542 retval = pkinit_get_certs_fs(context, plg_cryptoctx,
5330 5543 req_cryptoctx, idopts,
5331 5544 id_cryptoctx, princ);
5332 5545 break;
5333 5546 case IDTYPE_DIR:
5334 5547 retval = pkinit_get_certs_dir(context, plg_cryptoctx,
5335 5548 req_cryptoctx, idopts,
5336 5549 id_cryptoctx, princ);
5337 5550 break;
5338 5551 #ifndef WITHOUT_PKCS11
5339 5552 case IDTYPE_PKCS11:
5340 5553 retval = pkinit_get_certs_pkcs11(context, plg_cryptoctx,
5341 5554 req_cryptoctx, idopts,
5342 5555 id_cryptoctx, princ, do_matching);
5343 5556 break;
5344 5557 #endif
5345 5558 case IDTYPE_PKCS12:
5346 5559 retval = pkinit_get_certs_pkcs12(context, plg_cryptoctx,
5347 5560 req_cryptoctx, idopts,
5348 5561 id_cryptoctx, princ);
5349 5562 break;
5350 5563 default:
5351 5564 retval = EINVAL;
5352 5565 }
5353 5566 /* Solaris Kerberos */
5354 5567
5355 5568 return retval;
5356 5569 }
5357 5570
5358 5571 /*
5359 5572 * Get number of certificates available after crypto_load_certs()
5360 5573 */
5361 5574 /* ARGSUSED */
5362 5575 krb5_error_code
5363 5576 crypto_cert_get_count(krb5_context context,
5364 5577 pkinit_plg_crypto_context plg_cryptoctx,
5365 5578 pkinit_req_crypto_context req_cryptoctx,
5366 5579 pkinit_identity_crypto_context id_cryptoctx,
5367 5580 int *cert_count)
5368 5581 {
5369 5582 int count;
5370 5583
5371 5584 if (id_cryptoctx == NULL || id_cryptoctx->creds[0] == NULL)
5372 5585 return EINVAL;
5373 5586
5374 5587 for (count = 0;
5375 5588 count <= MAX_CREDS_ALLOWED && id_cryptoctx->creds[count] != NULL;
5376 5589 count++);
5377 5590 *cert_count = count;
5378 5591 return 0;
5379 5592 }
5380 5593
5381 5594
5382 5595 /*
5383 5596 * Begin iteration over the certs loaded in crypto_load_certs()
5384 5597 */
5385 5598 /* ARGSUSED */
5386 5599 krb5_error_code
5387 5600 crypto_cert_iteration_begin(krb5_context context,
5388 5601 pkinit_plg_crypto_context plg_cryptoctx,
5389 5602 pkinit_req_crypto_context req_cryptoctx,
5390 5603 pkinit_identity_crypto_context id_cryptoctx,
5391 5604 pkinit_cert_iter_handle *ih_ret)
5392 5605 {
5393 5606 struct _pkinit_cert_iter_data *id;
5394 5607
5395 5608 if (id_cryptoctx == NULL || ih_ret == NULL)
5396 5609 return EINVAL;
5397 5610 if (id_cryptoctx->creds[0] == NULL) /* No cred info available */
5398 5611 return ENOENT;
5399 5612
5400 5613 id = calloc(1, sizeof(*id));
5401 5614 if (id == NULL)
5402 5615 return ENOMEM;
5403 5616 id->magic = ITER_MAGIC;
5404 5617 id->plgctx = plg_cryptoctx,
5405 5618 id->reqctx = req_cryptoctx,
5406 5619 id->idctx = id_cryptoctx;
5407 5620 id->index = 0;
5408 5621 *ih_ret = (pkinit_cert_iter_handle) id;
5409 5622 return 0;
5410 5623 }
5411 5624
5412 5625 /*
5413 5626 * End iteration over the certs loaded in crypto_load_certs()
5414 5627 */
5415 5628 /* ARGSUSED */
5416 5629 krb5_error_code
5417 5630 crypto_cert_iteration_end(krb5_context context,
5418 5631 pkinit_cert_iter_handle ih)
5419 5632 {
5420 5633 struct _pkinit_cert_iter_data *id = (struct _pkinit_cert_iter_data *)ih;
5421 5634
5422 5635 if (id == NULL || id->magic != ITER_MAGIC)
5423 5636 return EINVAL;
5424 5637 free(ih);
5425 5638 return 0;
5426 5639 }
5427 5640
5428 5641 /*
5429 5642 * Get next certificate handle
5430 5643 */
5431 5644 /* ARGSUSED */
5432 5645 krb5_error_code
5433 5646 crypto_cert_iteration_next(krb5_context context,
5434 5647 pkinit_cert_iter_handle ih,
5435 5648 pkinit_cert_handle *ch_ret)
5436 5649 {
5437 5650 struct _pkinit_cert_iter_data *id = (struct _pkinit_cert_iter_data *)ih;
5438 5651 struct _pkinit_cert_data *cd;
5439 5652 pkinit_identity_crypto_context id_cryptoctx;
5440 5653
5441 5654 if (id == NULL || id->magic != ITER_MAGIC)
5442 5655 return EINVAL;
|
↓ open down ↓ |
276 lines elided |
↑ open up ↑ |
5443 5656
5444 5657 if (ch_ret == NULL)
5445 5658 return EINVAL;
5446 5659
5447 5660 id_cryptoctx = id->idctx;
5448 5661 if (id_cryptoctx == NULL)
5449 5662 return EINVAL;
5450 5663
5451 5664 if (id_cryptoctx->creds[id->index] == NULL)
5452 5665 return PKINIT_ITER_NO_MORE;
5453 -
5666 +
5454 5667 cd = calloc(1, sizeof(*cd));
5455 5668 if (cd == NULL)
5456 5669 return ENOMEM;
5457 5670
5458 5671 cd->magic = CERT_MAGIC;
5459 5672 cd->plgctx = id->plgctx;
5460 5673 cd->reqctx = id->reqctx;
5461 5674 cd->idctx = id->idctx;
5462 5675 cd->index = id->index;
5463 5676 cd->cred = id_cryptoctx->creds[id->index++];
5464 5677 *ch_ret = (pkinit_cert_handle)cd;
5465 5678 return 0;
5466 5679 }
5467 5680
5468 5681 /*
5469 5682 * Release cert handle
5470 5683 */
5471 5684 /* ARGSUSED */
5472 5685 krb5_error_code
5473 5686 crypto_cert_release(krb5_context context,
5474 5687 pkinit_cert_handle ch)
5475 5688 {
5476 5689 struct _pkinit_cert_data *cd = (struct _pkinit_cert_data *)ch;
5477 5690 if (cd == NULL || cd->magic != CERT_MAGIC)
5478 5691 return EINVAL;
5479 5692 free(cd);
5480 5693 return 0;
5481 5694 }
5482 5695
5483 5696 /*
5484 5697 * Get certificate Key Usage and Extended Key Usage
5485 5698 */
5486 5699 /* ARGSUSED */
5487 5700 static krb5_error_code
5488 5701 crypto_retieve_X509_key_usage(krb5_context context,
5489 5702 pkinit_plg_crypto_context plgcctx,
5490 5703 pkinit_req_crypto_context reqcctx,
5491 5704 X509 *x,
5492 5705 unsigned int *ret_ku_bits,
5493 5706 unsigned int *ret_eku_bits)
5494 5707 {
5495 5708 /* Solaris Kerberos */
5496 5709 int i;
5497 5710 unsigned int eku_bits = 0, ku_bits = 0;
5498 5711 ASN1_BIT_STRING *usage = NULL;
|
↓ open down ↓ |
35 lines elided |
↑ open up ↑ |
5499 5712
5500 5713 if (ret_ku_bits == NULL && ret_eku_bits == NULL)
5501 5714 return EINVAL;
5502 5715
5503 5716 if (ret_eku_bits)
5504 5717 *ret_eku_bits = 0;
5505 5718 else {
5506 5719 pkiDebug("%s: EKUs not requested, not checking\n", __FUNCTION__);
5507 5720 goto check_kus;
5508 5721 }
5509 -
5722 +
5510 5723 /* Start with Extended Key usage */
5511 5724 i = X509_get_ext_by_NID(x, NID_ext_key_usage, -1);
5512 5725 if (i >= 0) {
5513 5726 EXTENDED_KEY_USAGE *eku;
5514 5727
5515 5728 eku = X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL);
5516 5729 if (eku) {
5517 5730 for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
5518 5731 ASN1_OBJECT *certoid;
5519 5732 certoid = sk_ASN1_OBJECT_value(eku, i);
5520 5733 if ((OBJ_cmp(certoid, plgcctx->id_pkinit_KPClientAuth)) == 0)
5521 5734 eku_bits |= PKINIT_EKU_PKINIT;
5522 5735 else if ((OBJ_cmp(certoid, OBJ_nid2obj(NID_ms_smartcard_login))) == 0)
5523 5736 eku_bits |= PKINIT_EKU_MSSCLOGIN;
5524 5737 else if ((OBJ_cmp(certoid, OBJ_nid2obj(NID_client_auth))) == 0)
5525 5738 eku_bits |= PKINIT_EKU_CLIENTAUTH;
5526 5739 else if ((OBJ_cmp(certoid, OBJ_nid2obj(NID_email_protect))) == 0)
5527 5740 eku_bits |= PKINIT_EKU_EMAILPROTECTION;
5528 5741 }
5529 5742 EXTENDED_KEY_USAGE_free(eku);
5530 5743 }
5531 5744 }
5532 5745 pkiDebug("%s: returning eku 0x%08x\n", __FUNCTION__, eku_bits);
5533 5746 *ret_eku_bits = eku_bits;
5534 5747
5535 5748 check_kus:
5536 5749 /* Now the Key Usage bits */
5537 5750 if (ret_ku_bits)
5538 5751 *ret_ku_bits = 0;
5539 5752 else {
5540 5753 pkiDebug("%s: KUs not requested, not checking\n", __FUNCTION__);
5541 5754 goto out;
5542 5755 }
5543 5756
5544 5757 /* Make sure usage exists before checking bits */
5545 5758 usage = X509_get_ext_d2i(x, NID_key_usage, NULL, NULL);
5546 5759 if (usage) {
5547 5760 if (!ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE))
5548 5761 ku_bits |= PKINIT_KU_DIGITALSIGNATURE;
5549 5762 if (!ku_reject(x, X509v3_KU_KEY_ENCIPHERMENT))
5550 5763 ku_bits |= PKINIT_KU_KEYENCIPHERMENT;
5551 5764 ASN1_BIT_STRING_free(usage);
5552 5765 }
5553 5766
5554 5767 pkiDebug("%s: returning ku 0x%08x\n", __FUNCTION__, ku_bits);
5555 5768 *ret_ku_bits = ku_bits;
5556 5769
5557 5770 out:
5558 5771 return 0;
5559 5772 }
5560 5773
5561 5774 /*
5562 5775 * Return a string format of an X509_NAME in buf where
5563 5776 * size is an in/out parameter. On input it is the size
5564 5777 * of the buffer, and on output it is the actual length
5565 5778 * of the name.
5566 5779 * If buf is NULL, returns the length req'd to hold name
5567 5780 */
5568 5781 static char *
5569 5782 X509_NAME_oneline_ex(X509_NAME * a,
5570 5783 char *buf,
5571 5784 unsigned int *size,
5572 5785 unsigned long flag)
5573 5786 {
5574 5787 BIO *out = NULL;
5575 5788
5576 5789 out = BIO_new(BIO_s_mem ());
5577 5790 if (X509_NAME_print_ex(out, a, 0, flag) > 0) {
5578 5791 if (buf != NULL && *size > (int) BIO_number_written(out)) {
5579 5792 (void) memset(buf, 0, *size);
5580 5793 BIO_read(out, buf, (int) BIO_number_written(out));
5581 5794 }
5582 5795 else {
5583 5796 *size = BIO_number_written(out);
5584 5797 }
5585 5798 }
5586 5799 BIO_free(out);
5587 5800 return (buf);
5588 5801 }
5589 5802
5590 5803 /*
5591 5804 * Get certificate information
5592 5805 */
5593 5806 krb5_error_code
5594 5807 crypto_cert_get_matching_data(krb5_context context,
5595 5808 pkinit_cert_handle ch,
5596 5809 pkinit_cert_matching_data **ret_md)
5597 5810 {
5598 5811 krb5_error_code retval;
5599 5812 pkinit_cert_matching_data *md;
5600 5813 krb5_principal *pkinit_sans =NULL, *upn_sans = NULL;
5601 5814 struct _pkinit_cert_data *cd = (struct _pkinit_cert_data *)ch;
5602 5815 int i, j;
5603 5816 char buf[DN_BUF_LEN];
5604 5817 unsigned int bufsize = sizeof(buf);
5605 5818
5606 5819 if (cd == NULL || cd->magic != CERT_MAGIC)
5607 5820 return EINVAL;
5608 5821 if (ret_md == NULL)
5609 5822 return EINVAL;
5610 5823
5611 5824 md = calloc(1, sizeof(*md));
5612 5825 if (md == NULL)
5613 5826 return ENOMEM;
5614 5827
5615 5828 md->ch = ch;
5616 5829
5617 5830 /* get the subject name (in rfc2253 format) */
5618 5831 X509_NAME_oneline_ex(X509_get_subject_name(cd->cred->cert),
5619 5832 buf, &bufsize, XN_FLAG_SEP_COMMA_PLUS);
5620 5833 md->subject_dn = strdup(buf);
5621 5834 if (md->subject_dn == NULL) {
5622 5835 retval = ENOMEM;
5623 5836 goto cleanup;
5624 5837 }
5625 5838
5626 5839 /* get the issuer name (in rfc2253 format) */
5627 5840 X509_NAME_oneline_ex(X509_get_issuer_name(cd->cred->cert),
5628 5841 buf, &bufsize, XN_FLAG_SEP_COMMA_PLUS);
5629 5842 md->issuer_dn = strdup(buf);
5630 5843 if (md->issuer_dn == NULL) {
5631 5844 retval = ENOMEM;
5632 5845 goto cleanup;
5633 5846 }
5634 5847
5635 5848 /* get the san data */
5636 5849 retval = crypto_retrieve_X509_sans(context, cd->plgctx, cd->reqctx,
5637 5850 cd->cred->cert, &pkinit_sans,
5638 5851 &upn_sans, NULL);
5639 5852 if (retval)
5640 5853 goto cleanup;
5641 5854
5642 5855 j = 0;
5643 5856 if (pkinit_sans != NULL) {
5644 5857 for (i = 0; pkinit_sans[i] != NULL; i++)
5645 5858 j++;
5646 5859 }
5647 5860 if (upn_sans != NULL) {
5648 5861 for (i = 0; upn_sans[i] != NULL; i++)
5649 5862 j++;
5650 5863 }
5651 5864 if (j != 0) {
5652 5865 md->sans = calloc((size_t)j+1, sizeof(*md->sans));
5653 5866 if (md->sans == NULL) {
5654 5867 retval = ENOMEM;
5655 5868 goto cleanup;
5656 5869 }
5657 5870 j = 0;
5658 5871 if (pkinit_sans != NULL) {
5659 5872 for (i = 0; pkinit_sans[i] != NULL; i++)
5660 5873 md->sans[j++] = pkinit_sans[i];
5661 5874 free(pkinit_sans);
5662 5875 }
5663 5876 if (upn_sans != NULL) {
5664 5877 for (i = 0; upn_sans[i] != NULL; i++)
5665 5878 md->sans[j++] = upn_sans[i];
5666 5879 free(upn_sans);
5667 5880 }
5668 5881 md->sans[j] = NULL;
5669 5882 } else
5670 5883 md->sans = NULL;
5671 5884
5672 5885 /* get the KU and EKU data */
5673 5886
5674 5887 retval = crypto_retieve_X509_key_usage(context, cd->plgctx, cd->reqctx,
5675 5888 cd->cred->cert,
5676 5889 &md->ku_bits, &md->eku_bits);
5677 5890 if (retval)
5678 5891 goto cleanup;
5679 5892
5680 5893 *ret_md = md;
5681 5894 retval = 0;
5682 5895 cleanup:
5683 5896 if (retval) {
5684 5897 if (md)
5685 5898 crypto_cert_free_matching_data(context, md);
5686 5899 }
5687 5900 return retval;
5688 5901 }
5689 5902
5690 5903 /*
5691 5904 * Free certificate information
5692 5905 */
5693 5906 krb5_error_code
5694 5907 crypto_cert_free_matching_data(krb5_context context,
5695 5908 pkinit_cert_matching_data *md)
5696 5909 {
5697 5910 krb5_principal p;
5698 5911 int i;
5699 5912
5700 5913 if (md == NULL)
5701 5914 return EINVAL;
5702 5915 if (md->subject_dn)
5703 5916 free(md->subject_dn);
5704 5917 if (md->issuer_dn)
5705 5918 free(md->issuer_dn);
5706 5919 if (md->sans) {
5707 5920 for (i = 0, p = md->sans[i]; p != NULL; p = md->sans[++i])
5708 5921 krb5_free_principal(context, p);
5709 5922 free(md->sans);
5710 5923 }
5711 5924 free(md);
5712 5925 return 0;
5713 5926 }
5714 5927
5715 5928 /*
5716 5929 * Make this matching certificate "the chosen one"
5717 5930 */
5718 5931 /* ARGSUSED */
5719 5932 krb5_error_code
|
↓ open down ↓ |
200 lines elided |
↑ open up ↑ |
5720 5933 crypto_cert_select(krb5_context context,
5721 5934 pkinit_cert_matching_data *md)
5722 5935 {
5723 5936 struct _pkinit_cert_data *cd;
5724 5937 if (md == NULL)
5725 5938 return EINVAL;
5726 5939
5727 5940 cd = (struct _pkinit_cert_data *)md->ch;
5728 5941 if (cd == NULL || cd->magic != CERT_MAGIC)
5729 5942 return EINVAL;
5730 -
5731 - /* copy the selected cert into our id_cryptoctx */
5943 +
5944 + /* copy the selected cert into our id_cryptoctx */
5732 5945 if (cd->idctx->my_certs != NULL) {
5733 5946 sk_X509_pop_free(cd->idctx->my_certs, X509_free);
5734 5947 }
5735 5948 cd->idctx->my_certs = sk_X509_new_null();
5736 5949 sk_X509_push(cd->idctx->my_certs, cd->cred->cert);
5737 5950 cd->idctx->creds[cd->index]->cert = NULL; /* Don't free it twice */
5738 5951 cd->idctx->cert_index = 0;
5739 5952
5740 5953 if (cd->idctx->pkcs11_method != 1) {
5741 5954 cd->idctx->my_key = cd->cred->key;
5742 5955 cd->idctx->creds[cd->index]->key = NULL; /* Don't free it twice */
5743 - }
5956 + }
5744 5957 #ifndef WITHOUT_PKCS11
5745 5958 else {
5746 5959 cd->idctx->cert_id = cd->cred->cert_id;
5747 5960 cd->idctx->creds[cd->index]->cert_id = NULL; /* Don't free it twice */
5748 5961 cd->idctx->cert_id_len = cd->cred->cert_id_len;
5749 5962 }
5750 5963 #endif
5751 5964 return 0;
5752 5965 }
5753 5966
5754 5967 /*
5755 5968 * Choose the default certificate as "the chosen one"
5756 5969 */
5757 5970 krb5_error_code
5758 5971 crypto_cert_select_default(krb5_context context,
5759 5972 pkinit_plg_crypto_context plg_cryptoctx,
5760 5973 pkinit_req_crypto_context req_cryptoctx,
5761 5974 pkinit_identity_crypto_context id_cryptoctx)
5762 5975 {
5763 5976 krb5_error_code retval;
5764 5977 int cert_count = 0;
5765 5978
5766 5979 retval = crypto_cert_get_count(context, plg_cryptoctx, req_cryptoctx,
5767 5980 id_cryptoctx, &cert_count);
5768 5981 if (retval) {
5769 5982 pkiDebug("%s: crypto_cert_get_count error %d, %s\n",
5770 5983 __FUNCTION__, retval, error_message(retval));
5771 5984 goto errout;
5772 5985 }
5773 5986 if (cert_count != 1) {
5774 5987 /* Solaris Kerberos: Improved error messages */
|
↓ open down ↓ |
21 lines elided |
↑ open up ↑ |
5775 5988 retval = EINVAL;
5776 5989 krb5_set_error_message(context, retval,
5777 5990 gettext("Failed to select default certificate: "
5778 5991 "found %d certs to choose from but there must be exactly one"),
5779 5992 cert_count);
5780 5993 pkiDebug("%s: ERROR: There are %d certs to choose from, "
5781 5994 "but there must be exactly one.\n",
5782 5995 __FUNCTION__, cert_count);
5783 5996 goto errout;
5784 5997 }
5785 - /* copy the selected cert into our id_cryptoctx */
5998 + /* copy the selected cert into our id_cryptoctx */
5786 5999 if (id_cryptoctx->my_certs != NULL) {
5787 6000 sk_X509_pop_free(id_cryptoctx->my_certs, X509_free);
5788 6001 }
5789 6002 id_cryptoctx->my_certs = sk_X509_new_null();
5790 6003 sk_X509_push(id_cryptoctx->my_certs, id_cryptoctx->creds[0]->cert);
5791 6004 id_cryptoctx->creds[0]->cert = NULL; /* Don't free it twice */
5792 6005 id_cryptoctx->cert_index = 0;
5793 6006
5794 6007 if (id_cryptoctx->pkcs11_method != 1) {
5795 6008 id_cryptoctx->my_key = id_cryptoctx->creds[0]->key;
5796 6009 id_cryptoctx->creds[0]->key = NULL; /* Don't free it twice */
5797 - }
6010 + }
5798 6011 #ifndef WITHOUT_PKCS11
5799 6012 else {
5800 6013 id_cryptoctx->cert_id = id_cryptoctx->creds[0]->cert_id;
5801 6014 id_cryptoctx->creds[0]->cert_id = NULL; /* Don't free it twice */
5802 6015 id_cryptoctx->cert_id_len = id_cryptoctx->creds[0]->cert_id_len;
5803 6016 }
5804 6017 #endif
5805 6018 retval = 0;
5806 6019 errout:
5807 6020 return retval;
5808 6021 }
5809 6022
5810 6023
5811 6024 /* ARGSUSED */
5812 6025 static krb5_error_code
5813 6026 load_cas_and_crls(krb5_context context,
5814 6027 pkinit_plg_crypto_context plg_cryptoctx,
5815 6028 pkinit_req_crypto_context req_cryptoctx,
5816 6029 pkinit_identity_crypto_context id_cryptoctx,
5817 6030 int catype,
5818 6031 char *filename)
5819 6032 {
5820 6033 STACK_OF(X509_INFO) *sk = NULL;
5821 6034 STACK_OF(X509) *ca_certs = NULL;
5822 6035 STACK_OF(X509_CRL) *ca_crls = NULL;
5823 6036 BIO *in = NULL;
5824 6037 /* Solaris Kerberos */
5825 6038 krb5_error_code retval = KRB5KRB_ERR_GENERIC;
5826 6039 int i = 0;
5827 6040
5828 6041 /* If there isn't already a stack in the context,
5829 6042 * create a temporary one now */
5830 6043 switch(catype) {
5831 6044 case CATYPE_ANCHORS:
5832 6045 if (id_cryptoctx->trustedCAs != NULL)
5833 6046 ca_certs = id_cryptoctx->trustedCAs;
5834 6047 else {
5835 6048 ca_certs = sk_X509_new_null();
5836 6049 if (ca_certs == NULL)
5837 6050 return ENOMEM;
5838 6051 }
5839 6052 break;
5840 6053 case CATYPE_INTERMEDIATES:
5841 6054 if (id_cryptoctx->intermediateCAs != NULL)
5842 6055 ca_certs = id_cryptoctx->intermediateCAs;
5843 6056 else {
5844 6057 ca_certs = sk_X509_new_null();
5845 6058 if (ca_certs == NULL)
5846 6059 return ENOMEM;
5847 6060 }
5848 6061 break;
5849 6062 case CATYPE_CRLS:
5850 6063 if (id_cryptoctx->revoked != NULL)
5851 6064 ca_crls = id_cryptoctx->revoked;
5852 6065 else {
5853 6066 ca_crls = sk_X509_CRL_new_null();
5854 6067 if (ca_crls == NULL)
5855 6068 return ENOMEM;
5856 6069 }
5857 6070 break;
5858 6071 default:
5859 6072 return ENOTSUP;
5860 6073 }
5861 6074
5862 6075 if (!(in = BIO_new_file(filename, "r"))) {
5863 6076 retval = errno;
5864 6077 pkiDebug("%s: error opening file '%s': %s\n", __FUNCTION__,
5865 6078 filename, error_message(errno));
5866 6079 goto cleanup;
5867 6080 }
5868 6081
5869 6082 /* This loads from a file, a stack of x509/crl/pkey sets */
5870 6083 if ((sk = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL)) == NULL) {
|
↓ open down ↓ |
63 lines elided |
↑ open up ↑ |
5871 6084 pkiDebug("%s: error reading file '%s'\n", __FUNCTION__, filename);
5872 6085 retval = EIO;
5873 6086 goto cleanup;
5874 6087 }
5875 6088
5876 6089 /* scan over the stack created from loading the file contents,
5877 6090 * weed out duplicates, and push new ones onto the return stack
5878 6091 */
5879 6092 for (i = 0; i < sk_X509_INFO_num(sk); i++) {
5880 6093 X509_INFO *xi = sk_X509_INFO_value(sk, i);
5881 - if (xi != NULL && xi->x509 != NULL && catype != CATYPE_CRLS) {
6094 + if (xi != NULL && xi->x509 != NULL && catype != CATYPE_CRLS) {
5882 6095 int j = 0, size = sk_X509_num(ca_certs), flag = 0;
5883 6096
5884 6097 if (!size) {
5885 6098 sk_X509_push(ca_certs, xi->x509);
5886 6099 xi->x509 = NULL;
5887 6100 continue;
5888 6101 }
5889 6102 for (j = 0; j < size; j++) {
5890 6103 X509 *x = sk_X509_value(ca_certs, j);
5891 6104 flag = X509_cmp(x, xi->x509);
5892 6105 if (flag == 0)
5893 6106 break;
5894 - else
6107 + else
5895 6108 continue;
5896 6109 }
5897 6110 if (flag != 0) {
5898 6111 sk_X509_push(ca_certs, X509_dup(xi->x509));
5899 6112 }
5900 6113 } else if (xi != NULL && xi->crl != NULL && catype == CATYPE_CRLS) {
5901 6114 int j = 0, size = sk_X509_CRL_num(ca_crls), flag = 0;
5902 6115 if (!size) {
5903 6116 sk_X509_CRL_push(ca_crls, xi->crl);
5904 6117 xi->crl = NULL;
5905 6118 continue;
5906 6119 }
5907 6120 for (j = 0; j < size; j++) {
5908 6121 X509_CRL *x = sk_X509_CRL_value(ca_crls, j);
5909 6122 flag = X509_CRL_cmp(x, xi->crl);
5910 6123 if (flag == 0)
5911 6124 break;
5912 6125 else
5913 6126 continue;
5914 6127 }
5915 6128 if (flag != 0) {
5916 6129 sk_X509_CRL_push(ca_crls, X509_CRL_dup(xi->crl));
5917 6130 }
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
5918 6131 }
5919 6132 }
5920 6133
5921 6134 /* If we added something and there wasn't a stack in the
5922 6135 * context before, add the temporary stack to the context.
5923 6136 */
5924 6137 switch(catype) {
5925 6138 case CATYPE_ANCHORS:
5926 6139 if (sk_X509_num(ca_certs) == 0) {
5927 6140 pkiDebug("no anchors in file, %s\n", filename);
5928 - if (id_cryptoctx->trustedCAs == NULL)
6141 + if (id_cryptoctx->trustedCAs == NULL)
5929 6142 sk_X509_free(ca_certs);
5930 6143 } else {
5931 6144 if (id_cryptoctx->trustedCAs == NULL)
5932 6145 id_cryptoctx->trustedCAs = ca_certs;
5933 6146 }
5934 6147 break;
5935 6148 case CATYPE_INTERMEDIATES:
5936 6149 if (sk_X509_num(ca_certs) == 0) {
5937 6150 pkiDebug("no intermediates in file, %s\n", filename);
5938 - if (id_cryptoctx->intermediateCAs == NULL)
6151 + if (id_cryptoctx->intermediateCAs == NULL)
5939 6152 sk_X509_free(ca_certs);
5940 6153 } else {
5941 6154 if (id_cryptoctx->intermediateCAs == NULL)
5942 6155 id_cryptoctx->intermediateCAs = ca_certs;
5943 6156 }
5944 6157 break;
5945 6158 case CATYPE_CRLS:
5946 6159 if (sk_X509_CRL_num(ca_crls) == 0) {
5947 6160 pkiDebug("no crls in file, %s\n", filename);
5948 6161 if (id_cryptoctx->revoked == NULL)
5949 6162 sk_X509_CRL_free(ca_crls);
5950 6163 } else {
5951 6164 if (id_cryptoctx->revoked == NULL)
5952 6165 id_cryptoctx->revoked = ca_crls;
5953 6166 }
5954 6167 break;
5955 6168 default:
5956 6169 /* Should have been caught above! */
5957 6170 retval = EINVAL;
5958 6171 goto cleanup;
5959 6172 /* Solaris Kerberos: removed "break" as it's never reached */
5960 6173 }
5961 6174
5962 6175 retval = 0;
5963 6176
5964 6177 cleanup:
5965 6178 if (in != NULL)
5966 6179 BIO_free(in);
5967 6180 if (sk != NULL)
5968 6181 sk_X509_INFO_pop_free(sk, X509_INFO_free);
|
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
5969 6182
5970 6183 return retval;
5971 6184 }
5972 6185
5973 6186 static krb5_error_code
5974 6187 load_cas_and_crls_dir(krb5_context context,
5975 6188 pkinit_plg_crypto_context plg_cryptoctx,
5976 6189 pkinit_req_crypto_context req_cryptoctx,
5977 6190 pkinit_identity_crypto_context id_cryptoctx,
5978 6191 int catype,
5979 - char *dirname)
6192 + char *dirname)
5980 6193 {
5981 6194 krb5_error_code retval = EINVAL;
5982 6195 DIR *d = NULL;
5983 6196 struct dirent *dentry = NULL;
5984 6197 char filename[1024];
5985 6198
5986 6199 if (dirname == NULL)
5987 6200 return EINVAL;
5988 6201
5989 6202 d = opendir(dirname);
5990 - if (d == NULL)
6203 + if (d == NULL)
5991 6204 return ENOENT;
5992 6205
5993 6206 while ((dentry = readdir(d))) {
5994 6207 if (strlen(dirname) + strlen(dentry->d_name) + 2 > sizeof(filename)) {
5995 6208 pkiDebug("%s: Path too long -- directory '%s' and file '%s'\n",
5996 6209 __FUNCTION__, dirname, dentry->d_name);
5997 6210 goto cleanup;
5998 6211 }
5999 6212 /* Ignore subdirectories and anything starting with a dot */
6000 6213 #ifdef DT_DIR
6001 6214 if (dentry->d_type == DT_DIR)
6002 6215 continue;
6003 6216 #endif
6004 6217 if (dentry->d_name[0] == '.')
6005 6218 continue;
6006 6219 (void) snprintf(filename, sizeof(filename), "%s/%s", dirname, dentry->d_name);
|
↓ open down ↓ |
6 lines elided |
↑ open up ↑ |
6007 6220
6008 6221 retval = load_cas_and_crls(context, plg_cryptoctx, req_cryptoctx,
6009 6222 id_cryptoctx, catype, filename);
6010 6223 if (retval)
6011 6224 goto cleanup;
6012 6225 }
6013 6226
6014 6227 retval = 0;
6015 6228
6016 6229 cleanup:
6017 - if (d != NULL)
6230 + if (d != NULL)
6018 6231 (void) closedir(d);
6019 6232
6020 6233 return retval;
6021 6234 }
6022 6235
6023 6236 /* ARGSUSED */
6024 6237 krb5_error_code
6025 6238 crypto_load_cas_and_crls(krb5_context context,
6026 6239 pkinit_plg_crypto_context plg_cryptoctx,
6027 6240 pkinit_req_crypto_context req_cryptoctx,
6028 6241 pkinit_identity_opts *idopts,
6029 6242 pkinit_identity_crypto_context id_cryptoctx,
6030 6243 int idtype,
6031 6244 int catype,
6032 - char *id)
6245 + char *id)
6033 6246 {
6034 6247 pkiDebug("%s: called with idtype %s and catype %s\n",
6035 6248 __FUNCTION__, idtype2string(idtype), catype2string(catype));
6036 6249 /* Solaris Kerberos: Removed "break"'s as they are never reached */
6037 6250 switch (idtype) {
6038 6251 case IDTYPE_FILE:
6039 6252 return load_cas_and_crls(context, plg_cryptoctx, req_cryptoctx,
6040 6253 id_cryptoctx, catype, id);
6041 6254 case IDTYPE_DIR:
6042 6255 return load_cas_and_crls_dir(context, plg_cryptoctx, req_cryptoctx,
6043 6256 id_cryptoctx, catype, id);
6044 6257 default:
6045 6258 return ENOTSUP;
6046 6259 }
6047 6260 }
6048 6261
6049 6262 static krb5_error_code
6050 6263 create_identifiers_from_stack(STACK_OF(X509) *sk,
6051 6264 krb5_external_principal_identifier *** ids)
6052 6265 {
6053 6266 krb5_error_code retval = ENOMEM;
6054 6267 int i = 0, sk_size = sk_X509_num(sk);
6055 6268 krb5_external_principal_identifier **krb5_cas = NULL;
6056 6269 X509 *x = NULL;
6057 6270 X509_NAME *xn = NULL;
6058 6271 unsigned char *p = NULL;
6059 6272 int len = 0;
6060 6273 PKCS7_ISSUER_AND_SERIAL *is = NULL;
6061 6274 char buf[DN_BUF_LEN];
6062 6275
6063 6276 *ids = NULL;
6064 6277
6065 6278 krb5_cas =
6066 6279 malloc((sk_size + 1) * sizeof(krb5_external_principal_identifier *));
6067 6280 if (krb5_cas == NULL)
6068 6281 return ENOMEM;
6069 6282 krb5_cas[sk_size] = NULL;
6070 6283
6071 6284 for (i = 0; i < sk_size; i++) {
6072 6285 krb5_cas[i] = (krb5_external_principal_identifier *)malloc(sizeof(krb5_external_principal_identifier));
6073 6286
6074 6287 x = sk_X509_value(sk, i);
6075 6288
6076 6289 X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf));
6077 6290 pkiDebug("#%d cert= %s\n", i, buf);
6078 6291
6079 6292 /* fill-in subjectName */
6080 6293 krb5_cas[i]->subjectName.magic = 0;
6081 6294 krb5_cas[i]->subjectName.length = 0;
6082 6295 krb5_cas[i]->subjectName.data = NULL;
6083 6296
6084 6297 xn = X509_get_subject_name(x);
6085 6298 len = i2d_X509_NAME(xn, NULL);
6086 6299 if ((p = krb5_cas[i]->subjectName.data = (unsigned char *)malloc((size_t) len)) == NULL)
6087 6300 goto cleanup;
6088 6301 i2d_X509_NAME(xn, &p);
6089 6302 krb5_cas[i]->subjectName.length = len;
6090 6303
|
↓ open down ↓ |
48 lines elided |
↑ open up ↑ |
6091 6304 /* fill-in issuerAndSerialNumber */
6092 6305 krb5_cas[i]->issuerAndSerialNumber.length = 0;
6093 6306 krb5_cas[i]->issuerAndSerialNumber.magic = 0;
6094 6307 krb5_cas[i]->issuerAndSerialNumber.data = NULL;
6095 6308
6096 6309 #ifdef LONGHORN_BETA_COMPAT
6097 6310 if (longhorn == 0) { /* XXX Longhorn doesn't like this */
6098 6311 #endif
6099 6312 is = PKCS7_ISSUER_AND_SERIAL_new();
6100 6313 X509_NAME_set(&is->issuer, X509_get_issuer_name(x));
6101 - M_ASN1_INTEGER_free(is->serial);
6102 - is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(x));
6314 + ASN1_INTEGER_free(is->serial);
6315 + is->serial = ASN1_INTEGER_dup(X509_get_serialNumber(x));
6103 6316 len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
6104 6317 if ((p = krb5_cas[i]->issuerAndSerialNumber.data =
6105 6318 (unsigned char *)malloc((size_t) len)) == NULL)
6106 6319 goto cleanup;
6107 6320 i2d_PKCS7_ISSUER_AND_SERIAL(is, &p);
6108 6321 krb5_cas[i]->issuerAndSerialNumber.length = len;
6109 6322 #ifdef LONGHORN_BETA_COMPAT
6110 6323 }
6111 6324 #endif
6112 6325
6113 6326 /* fill-in subjectKeyIdentifier */
6114 6327 krb5_cas[i]->subjectKeyIdentifier.length = 0;
6115 6328 krb5_cas[i]->subjectKeyIdentifier.magic = 0;
6116 6329 krb5_cas[i]->subjectKeyIdentifier.data = NULL;
6117 6330
6118 6331
6119 6332 #ifdef LONGHORN_BETA_COMPAT
6120 6333 if (longhorn == 0) { /* XXX Longhorn doesn't like this */
6121 6334 #endif
6122 6335 if (X509_get_ext_by_NID(x, NID_subject_key_identifier, -1) >= 0) {
6123 6336 ASN1_OCTET_STRING *ikeyid = NULL;
6124 6337
6125 6338 if ((ikeyid = X509_get_ext_d2i(x, NID_subject_key_identifier, NULL,
6126 6339 NULL))) {
6127 6340 len = i2d_ASN1_OCTET_STRING(ikeyid, NULL);
6128 6341 if ((p = krb5_cas[i]->subjectKeyIdentifier.data =
6129 6342 (unsigned char *)malloc((size_t) len)) == NULL)
6130 6343 goto cleanup;
6131 6344 i2d_ASN1_OCTET_STRING(ikeyid, &p);
6132 6345 krb5_cas[i]->subjectKeyIdentifier.length = len;
6133 6346 }
6134 6347 if (ikeyid != NULL)
6135 6348 ASN1_OCTET_STRING_free(ikeyid);
6136 6349 }
6137 6350 #ifdef LONGHORN_BETA_COMPAT
6138 6351 }
6139 6352 #endif
6140 6353 if (is != NULL) {
6141 6354 if (is->issuer != NULL)
6142 6355 X509_NAME_free(is->issuer);
6143 6356 if (is->serial != NULL)
6144 6357 ASN1_INTEGER_free(is->serial);
6145 6358 free(is);
6146 6359 }
6147 6360 }
6148 6361
6149 6362 *ids = krb5_cas;
6150 6363
6151 6364 retval = 0;
6152 6365 cleanup:
6153 6366 if (retval)
6154 6367 free_krb5_external_principal_identifier(&krb5_cas);
6155 6368
6156 6369 return retval;
6157 6370 }
6158 6371
6159 6372 /* ARGSUSED */
6160 6373 static krb5_error_code
6161 6374 create_krb5_invalidCertificates(krb5_context context,
6162 6375 pkinit_plg_crypto_context plg_cryptoctx,
6163 6376 pkinit_req_crypto_context req_cryptoctx,
6164 6377 pkinit_identity_crypto_context id_cryptoctx,
6165 6378 krb5_external_principal_identifier *** ids)
|
↓ open down ↓ |
53 lines elided |
↑ open up ↑ |
6166 6379 {
6167 6380
6168 6381 krb5_error_code retval = ENOMEM;
6169 6382 STACK_OF(X509) *sk = NULL;
6170 6383
6171 6384 *ids = NULL;
6172 6385 if (req_cryptoctx->received_cert == NULL)
6173 6386 return KRB5KDC_ERR_PREAUTH_FAILED;
6174 6387
6175 6388 sk = sk_X509_new_null();
6176 - if (sk == NULL)
6389 + if (sk == NULL)
6177 6390 goto cleanup;
6178 6391 sk_X509_push(sk, req_cryptoctx->received_cert);
6179 6392
6180 6393 retval = create_identifiers_from_stack(sk, ids);
6181 6394
6182 6395 sk_X509_free(sk);
6183 6396 cleanup:
6184 6397
6185 6398 return retval;
6186 6399 }
6187 6400
6188 6401 /* ARGSUSED */
6189 6402 krb5_error_code
6190 6403 create_krb5_supportedCMSTypes(krb5_context context,
6191 6404 pkinit_plg_crypto_context plg_cryptoctx,
6192 6405 pkinit_req_crypto_context req_cryptoctx,
6193 6406 pkinit_identity_crypto_context id_cryptoctx,
6194 6407 krb5_algorithm_identifier ***oids)
6195 6408 {
6196 6409
6197 6410 krb5_error_code retval = ENOMEM;
6198 6411 krb5_algorithm_identifier **loids = NULL;
6199 6412 krb5_octet_data des3oid = {0, 8, (unsigned char *)"\x2A\x86\x48\x86\xF7\x0D\x03\x07" };
6200 6413
6201 6414 *oids = NULL;
6202 6415 loids = malloc(2 * sizeof(krb5_algorithm_identifier *));
6203 6416 if (loids == NULL)
6204 6417 goto cleanup;
6205 6418 loids[1] = NULL;
6206 6419 loids[0] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
6207 6420 if (loids[0] == NULL) {
6208 6421 free(loids);
6209 6422 goto cleanup;
6210 6423 }
6211 6424 retval = pkinit_copy_krb5_octet_data(&loids[0]->algorithm, &des3oid);
6212 6425 if (retval) {
6213 6426 free(loids[0]);
6214 6427 free(loids);
6215 6428 goto cleanup;
6216 6429 }
6217 6430 loids[0]->parameters.length = 0;
6218 6431 loids[0]->parameters.data = NULL;
6219 6432
6220 6433 *oids = loids;
6221 6434 retval = 0;
6222 6435 cleanup:
6223 6436
6224 6437 return retval;
6225 6438 }
6226 6439
6227 6440 /* ARGSUSED */
6228 6441 krb5_error_code
6229 6442 create_krb5_trustedCertifiers(krb5_context context,
6230 6443 pkinit_plg_crypto_context plg_cryptoctx,
6231 6444 pkinit_req_crypto_context req_cryptoctx,
6232 6445 pkinit_identity_crypto_context id_cryptoctx,
6233 6446 krb5_external_principal_identifier *** ids)
|
↓ open down ↓ |
47 lines elided |
↑ open up ↑ |
6234 6447 {
6235 6448
6236 6449 /* Solaris Kerberos */
6237 6450 STACK_OF(X509) *sk = id_cryptoctx->trustedCAs;
6238 6451
6239 6452 *ids = NULL;
6240 6453 if (id_cryptoctx->trustedCAs == NULL)
6241 6454 return KRB5KDC_ERR_PREAUTH_FAILED;
6242 6455
6243 6456 return create_identifiers_from_stack(sk, ids);
6244 -
6457 +
6245 6458 }
6246 6459
6247 6460 /* ARGSUSED */
6248 6461 krb5_error_code
6249 6462 create_krb5_trustedCas(krb5_context context,
6250 6463 pkinit_plg_crypto_context plg_cryptoctx,
6251 6464 pkinit_req_crypto_context req_cryptoctx,
6252 6465 pkinit_identity_crypto_context id_cryptoctx,
6253 6466 int flag,
6254 6467 krb5_trusted_ca *** ids)
6255 6468 {
6256 6469 krb5_error_code retval = ENOMEM;
6257 6470 STACK_OF(X509) *sk = id_cryptoctx->trustedCAs;
6258 6471 int i = 0, len = 0, sk_size = sk_X509_num(sk);
6259 6472 krb5_trusted_ca **krb5_cas = NULL;
6260 6473 X509 *x = NULL;
6261 6474 char buf[DN_BUF_LEN];
6262 6475 X509_NAME *xn = NULL;
6263 6476 unsigned char *p = NULL;
6264 6477 PKCS7_ISSUER_AND_SERIAL *is = NULL;
6265 6478
6266 6479 *ids = NULL;
6267 6480 if (id_cryptoctx->trustedCAs == NULL)
6268 6481 return KRB5KDC_ERR_PREAUTH_FAILED;
6269 6482
6270 6483 krb5_cas = malloc((sk_size + 1) * sizeof(krb5_trusted_ca *));
6271 6484 if (krb5_cas == NULL)
6272 6485 return ENOMEM;
6273 6486 krb5_cas[sk_size] = NULL;
6274 6487
6275 6488 for (i = 0; i < sk_size; i++) {
6276 6489 krb5_cas[i] = (krb5_trusted_ca *)malloc(sizeof(krb5_trusted_ca));
6277 6490 if (krb5_cas[i] == NULL)
6278 6491 goto cleanup;
6279 6492 x = sk_X509_value(sk, i);
6280 6493
6281 6494 X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf));
6282 6495 pkiDebug("#%d cert= %s\n", i, buf);
6283 6496
6284 6497 switch (flag) {
6285 6498 case choice_trusted_cas_principalName:
6286 6499 krb5_cas[i]->choice = choice_trusted_cas_principalName;
6287 6500 break;
6288 6501 case choice_trusted_cas_caName:
6289 6502 krb5_cas[i]->choice = choice_trusted_cas_caName;
6290 6503 krb5_cas[i]->u.caName.data = NULL;
6291 6504 krb5_cas[i]->u.caName.length = 0;
6292 6505 xn = X509_get_subject_name(x);
6293 6506 len = i2d_X509_NAME(xn, NULL);
6294 6507 if ((p = krb5_cas[i]->u.caName.data =
6295 6508 (unsigned char *)malloc((size_t) len)) == NULL)
|
↓ open down ↓ |
41 lines elided |
↑ open up ↑ |
6296 6509 goto cleanup;
6297 6510 i2d_X509_NAME(xn, &p);
6298 6511 krb5_cas[i]->u.caName.length = len;
6299 6512 break;
6300 6513 case choice_trusted_cas_issuerAndSerial:
6301 6514 krb5_cas[i]->choice = choice_trusted_cas_issuerAndSerial;
6302 6515 krb5_cas[i]->u.issuerAndSerial.data = NULL;
6303 6516 krb5_cas[i]->u.issuerAndSerial.length = 0;
6304 6517 is = PKCS7_ISSUER_AND_SERIAL_new();
6305 6518 X509_NAME_set(&is->issuer, X509_get_issuer_name(x));
6306 - M_ASN1_INTEGER_free(is->serial);
6307 - is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(x));
6519 + ASN1_INTEGER_free(is->serial);
6520 + is->serial = ASN1_INTEGER_dup(X509_get_serialNumber(x));
6308 6521 len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
6309 6522 if ((p = krb5_cas[i]->u.issuerAndSerial.data =
6310 6523 (unsigned char *)malloc((size_t) len)) == NULL)
6311 6524 goto cleanup;
6312 6525 i2d_PKCS7_ISSUER_AND_SERIAL(is, &p);
6313 6526 krb5_cas[i]->u.issuerAndSerial.length = len;
6314 6527 if (is != NULL) {
6315 6528 if (is->issuer != NULL)
6316 6529 X509_NAME_free(is->issuer);
6317 6530 if (is->serial != NULL)
6318 6531 ASN1_INTEGER_free(is->serial);
6319 6532 free(is);
6320 6533 }
6321 6534 break;
6322 6535 default: break;
6323 6536 }
6324 6537 }
6325 6538 retval = 0;
6326 6539 *ids = krb5_cas;
6327 6540 cleanup:
6328 6541 if (retval)
6329 6542 free_krb5_trusted_ca(&krb5_cas);
6330 6543
6331 6544 return retval;
6332 6545 }
6333 6546
6334 6547 /* ARGSUSED */
6335 6548 krb5_error_code
6336 6549 create_issuerAndSerial(krb5_context context,
6337 6550 pkinit_plg_crypto_context plg_cryptoctx,
6338 6551 pkinit_req_crypto_context req_cryptoctx,
6339 6552 pkinit_identity_crypto_context id_cryptoctx,
6340 6553 unsigned char **out,
6341 6554 unsigned int *out_len)
6342 6555 {
6343 6556 unsigned char *p = NULL;
6344 6557 PKCS7_ISSUER_AND_SERIAL *is = NULL;
6345 6558 int len = 0;
|
↓ open down ↓ |
28 lines elided |
↑ open up ↑ |
6346 6559 krb5_error_code retval = ENOMEM;
6347 6560 X509 *cert = req_cryptoctx->received_cert;
6348 6561
6349 6562 *out = NULL;
6350 6563 *out_len = 0;
6351 6564 if (req_cryptoctx->received_cert == NULL)
6352 6565 return 0;
6353 6566
6354 6567 is = PKCS7_ISSUER_AND_SERIAL_new();
6355 6568 X509_NAME_set(&is->issuer, X509_get_issuer_name(cert));
6356 - M_ASN1_INTEGER_free(is->serial);
6357 - is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert));
6569 + ASN1_INTEGER_free(is->serial);
6570 + is->serial = ASN1_INTEGER_dup(X509_get_serialNumber(cert));
6358 6571 len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
6359 6572 if ((p = *out = (unsigned char *)malloc((size_t) len)) == NULL)
6360 6573 goto cleanup;
6361 6574 i2d_PKCS7_ISSUER_AND_SERIAL(is, &p);
6362 6575 *out_len = len;
6363 6576 retval = 0;
6364 6577
6365 6578 cleanup:
6366 6579 X509_NAME_free(is->issuer);
6367 6580 ASN1_INTEGER_free(is->serial);
6368 6581 free(is);
6369 6582
6370 6583 return retval;
6371 6584 }
6372 6585
6373 6586 static int
6374 6587 pkcs7_decrypt(krb5_context context,
6375 6588 pkinit_identity_crypto_context id_cryptoctx,
6376 6589 PKCS7 *p7,
6377 6590 BIO *data)
6378 6591 {
6379 6592 BIO *tmpmem = NULL;
6380 6593 /* Solaris Kerberos */
6381 6594 int i = 0;
6382 6595 char buf[4096];
6383 6596
6384 6597 if(p7 == NULL)
6385 6598 return 0;
6386 6599
6387 6600 if(!PKCS7_type_is_enveloped(p7)) {
6388 6601 pkiDebug("wrong pkcs7 content type\n");
6389 6602 return 0;
6390 6603 }
6391 6604
6392 6605 if(!(tmpmem = pkcs7_dataDecode(context, id_cryptoctx, p7))) {
6393 6606 pkiDebug("unable to decrypt pkcs7 object\n");
6394 6607 return 0;
6395 6608 }
6396 6609 /* Solaris Kerberos: Suppress sun studio compiler warning */
|
↓ open down ↓ |
29 lines elided |
↑ open up ↑ |
6397 6610 #pragma error_messages (off, E_END_OF_LOOP_CODE_NOT_REACHED)
6398 6611 for(;;) {
6399 6612 i = BIO_read(tmpmem, buf, sizeof(buf));
6400 6613 if (i <= 0) break;
6401 6614 BIO_write(data, buf, i);
6402 6615 BIO_free_all(tmpmem);
6403 6616 return 1;
6404 6617 }
6405 6618 #pragma error_messages (default, E_END_OF_LOOP_CODE_NOT_REACHED)
6406 6619
6407 - return 0;
6620 + return 0;
6408 6621 }
6409 6622
6410 6623 krb5_error_code
6411 6624 pkinit_process_td_trusted_certifiers(
6412 6625 krb5_context context,
6413 6626 pkinit_plg_crypto_context plg_cryptoctx,
6414 6627 pkinit_req_crypto_context req_cryptoctx,
6415 6628 pkinit_identity_crypto_context id_cryptoctx,
6416 6629 krb5_external_principal_identifier **krb5_trusted_certifiers,
6417 6630 int td_type)
6418 6631 {
6419 6632 krb5_error_code retval = ENOMEM;
6420 6633 STACK_OF(X509_NAME) *sk_xn = NULL;
6421 6634 X509_NAME *xn = NULL;
6422 6635 PKCS7_ISSUER_AND_SERIAL *is = NULL;
6423 6636 ASN1_OCTET_STRING *id = NULL;
6424 6637 const unsigned char *p = NULL;
6425 6638 char buf[DN_BUF_LEN];
6426 6639 int i = 0;
6427 6640
6428 6641 if (td_type == TD_TRUSTED_CERTIFIERS)
6429 6642 pkiDebug("received trusted certifiers\n");
6430 6643 else
6431 6644 pkiDebug("received invalid certificate\n");
6432 6645
6433 6646 sk_xn = sk_X509_NAME_new_null();
6434 6647 while(krb5_trusted_certifiers[i] != NULL) {
6435 6648 if (krb5_trusted_certifiers[i]->subjectName.data != NULL) {
6436 6649 p = krb5_trusted_certifiers[i]->subjectName.data;
6437 6650 xn = d2i_X509_NAME(NULL, &p,
6438 6651 (int)krb5_trusted_certifiers[i]->subjectName.length);
6439 6652 if (xn == NULL)
6440 6653 goto cleanup;
6441 6654 X509_NAME_oneline(xn, buf, sizeof(buf));
6442 6655 if (td_type == TD_TRUSTED_CERTIFIERS)
6443 6656 pkiDebug("#%d cert = %s is trusted by kdc\n", i, buf);
6444 6657 else
6445 6658 pkiDebug("#%d cert = %s is invalid\n", i, buf);
6446 6659 sk_X509_NAME_push(sk_xn, xn);
6447 6660 }
6448 6661
6449 6662 if (krb5_trusted_certifiers[i]->issuerAndSerialNumber.data != NULL) {
6450 6663 p = krb5_trusted_certifiers[i]->issuerAndSerialNumber.data;
6451 6664 is = d2i_PKCS7_ISSUER_AND_SERIAL(NULL, &p,
6452 6665 (int)krb5_trusted_certifiers[i]->issuerAndSerialNumber.length);
6453 6666 if (is == NULL)
6454 6667 goto cleanup;
6455 6668 X509_NAME_oneline(is->issuer, buf, sizeof(buf));
6456 6669 if (td_type == TD_TRUSTED_CERTIFIERS)
6457 6670 pkiDebug("#%d issuer = %s serial = %ld is trusted bu kdc\n", i,
6458 6671 buf, ASN1_INTEGER_get(is->serial));
6459 6672 else
6460 6673 pkiDebug("#%d issuer = %s serial = %ld is invalid\n", i, buf,
6461 6674 ASN1_INTEGER_get(is->serial));
6462 6675 PKCS7_ISSUER_AND_SERIAL_free(is);
6463 6676 }
6464 6677
6465 6678 if (krb5_trusted_certifiers[i]->subjectKeyIdentifier.data != NULL) {
6466 6679 p = krb5_trusted_certifiers[i]->subjectKeyIdentifier.data;
6467 6680 id = d2i_ASN1_OCTET_STRING(NULL, &p,
6468 6681 (int)krb5_trusted_certifiers[i]->subjectKeyIdentifier.length);
6469 6682 if (id == NULL)
6470 6683 goto cleanup;
6471 6684 /* XXX */
6472 6685 ASN1_OCTET_STRING_free(id);
6473 6686 }
6474 6687 i++;
6475 6688 }
6476 6689 /* XXX Since we not doing anything with received trusted certifiers
6477 6690 * return an error. this is the place where we can pick a different
6478 6691 * client certificate based on the information in td_trusted_certifiers
6479 6692 */
6480 6693 retval = KRB5KDC_ERR_PREAUTH_FAILED;
6481 6694 cleanup:
6482 6695 if (sk_xn != NULL)
6483 6696 sk_X509_NAME_pop_free(sk_xn, X509_NAME_free);
6484 6697
6485 6698 return retval;
6486 6699 }
6487 6700
6488 6701 static BIO *
6489 6702 pkcs7_dataDecode(krb5_context context,
6490 6703 pkinit_identity_crypto_context id_cryptoctx,
6491 6704 PKCS7 *p7)
6492 6705 {
6493 6706 int i = 0;
6494 6707 unsigned int jj = 0, tmp_len = 0;
6495 6708 BIO *out=NULL,*etmp=NULL,*bio=NULL;
6496 6709 unsigned char *tmp=NULL;
6497 6710 ASN1_OCTET_STRING *data_body=NULL;
6498 6711 const EVP_CIPHER *evp_cipher=NULL;
6499 6712 EVP_CIPHER_CTX *evp_ctx=NULL;
6500 6713 X509_ALGOR *enc_alg=NULL;
6501 6714 STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
6502 6715 /* Solaris Kerberos: Not used */
6503 6716 #if 0
6504 6717 X509_ALGOR *xalg=NULL;
6505 6718 #endif
6506 6719 PKCS7_RECIP_INFO *ri=NULL;
6507 6720 X509 *cert = sk_X509_value(id_cryptoctx->my_certs,
6508 6721 id_cryptoctx->cert_index);
6509 6722
6510 6723 p7->state=PKCS7_S_HEADER;
6511 6724
6512 6725 rsk=p7->d.enveloped->recipientinfo;
6513 6726 enc_alg=p7->d.enveloped->enc_data->algorithm;
6514 6727 data_body=p7->d.enveloped->enc_data->enc_data;
6515 6728 evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm);
6516 6729 if (evp_cipher == NULL) {
6517 6730 PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
6518 6731 goto cleanup;
6519 6732 }
6520 6733 /* Solaris Kerberos: Not used */
6521 6734 #if 0
6522 6735 xalg=p7->d.enveloped->enc_data->algorithm;
6523 6736 #endif
6524 6737
6525 6738 if ((etmp=BIO_new(BIO_f_cipher())) == NULL) {
6526 6739 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
6527 6740 goto cleanup;
6528 6741 }
6529 6742
6530 6743 /* It was encrypted, we need to decrypt the secret key
6531 6744 * with the private key */
|
↓ open down ↓ |
114 lines elided |
↑ open up ↑ |
6532 6745
6533 6746 /* Find the recipientInfo which matches the passed certificate
6534 6747 * (if any)
6535 6748 */
6536 6749
6537 6750 if (cert) {
6538 6751 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
6539 6752 int tmp_ret = 0;
6540 6753 ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
6541 6754 tmp_ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
6542 - cert->cert_info->issuer);
6755 + X509_get_issuer_name(cert));
6543 6756 if (!tmp_ret) {
6544 - tmp_ret = M_ASN1_INTEGER_cmp(cert->cert_info->serialNumber,
6757 + tmp_ret = ASN1_INTEGER_cmp(X509_get_serialNumber(cert),
6545 6758 ri->issuer_and_serial->serial);
6546 6759 if (!tmp_ret)
6547 6760 break;
6548 6761 }
6549 6762 ri=NULL;
6550 6763 }
6551 6764 if (ri == NULL) {
6552 6765 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
6553 6766 PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
6554 6767 goto cleanup;
6555 6768 }
6556 6769
6557 6770 }
6558 6771
6559 6772 /* If we haven't got a certificate try each ri in turn */
6560 6773
6561 6774 if (cert == NULL) {
6562 6775 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
6563 6776 ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
6564 6777 jj = pkinit_decode_data(context, id_cryptoctx,
6565 - M_ASN1_STRING_data(ri->enc_key),
6566 - (unsigned int) M_ASN1_STRING_length(ri->enc_key),
6778 + (unsigned char *)ASN1_STRING_get0_data(ri->enc_key),
6779 + ASN1_STRING_length(ri->enc_key),
6567 6780 &tmp, &tmp_len);
6568 6781 if (jj) {
6569 6782 PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB);
6570 6783 goto cleanup;
6571 6784 }
6572 6785
6573 6786 if (!jj && tmp_len > 0) {
6574 6787 jj = tmp_len;
6575 6788 break;
6576 6789 }
6577 6790
6578 6791 ERR_clear_error();
6579 6792 ri = NULL;
6580 6793 }
6581 6794
6582 6795 if (ri == NULL) {
6583 - PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_RECIPIENT_MATCHES_KEY);
6796 + PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
6584 6797 goto cleanup;
6585 6798 }
6586 6799 }
6587 6800 else {
6588 6801 jj = pkinit_decode_data(context, id_cryptoctx,
6589 - M_ASN1_STRING_data(ri->enc_key),
6590 - (unsigned int) M_ASN1_STRING_length(ri->enc_key),
6802 + (unsigned char *)ASN1_STRING_get0_data(ri->enc_key),
6803 + ASN1_STRING_length(ri->enc_key),
6591 6804 &tmp, &tmp_len);
6592 6805 /* Solaris Kerberos: tmp_len is unsigned. Cannot be < 0 */
6593 6806 if (jj || tmp_len == 0) {
6594 6807 PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB);
6595 6808 goto cleanup;
6596 6809 }
6597 6810 jj = tmp_len;
6598 6811 }
6599 6812
6600 6813 evp_ctx=NULL;
6601 6814 BIO_get_cipher_ctx(etmp,&evp_ctx);
6602 6815 if (EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0) <= 0)
6603 6816 goto cleanup;
|
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
6604 6817 if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
6605 6818 goto cleanup;
6606 6819
6607 6820 if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) {
6608 6821 /* Some S/MIME clients don't use the same key
6609 6822 * and effective key length. The key length is
6610 6823 * determined by the size of the decrypted RSA key.
6611 6824 */
6612 6825 if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, (int)jj)) {
6613 6826 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
6614 - PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
6827 + PKCS7_R_DECRYPT_ERROR);
6615 6828 goto cleanup;
6616 6829 }
6617 6830 }
6618 6831 if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0)
6619 6832 goto cleanup;
6620 6833
6621 6834 OPENSSL_cleanse(tmp,jj);
6622 6835
6623 6836 if (out == NULL)
6624 6837 out=etmp;
6625 6838 else
6626 6839 BIO_push(out,etmp);
6627 6840 etmp=NULL;
6628 6841
6629 6842 if (data_body->length > 0)
6630 6843 bio = BIO_new_mem_buf(data_body->data, data_body->length);
6631 6844 else {
6632 6845 bio=BIO_new(BIO_s_mem());
6633 6846 BIO_set_mem_eof_return(bio,0);
6634 6847 }
6635 6848 BIO_push(out,bio);
6636 6849 bio=NULL;
6637 6850
6638 6851 /* Solaris Kerberos */
6639 6852 goto out;
6640 6853
6641 6854 cleanup:
6642 6855 if (out != NULL) BIO_free_all(out);
6643 6856 if (etmp != NULL) BIO_free_all(etmp);
6644 6857 if (bio != NULL) BIO_free_all(bio);
6645 6858 out=NULL;
6646 6859
6647 6860 out:
6648 6861 if (tmp != NULL)
6649 6862 free(tmp);
6650 6863
6651 6864 return(out);
6652 6865 }
6653 6866
6654 6867 static krb5_error_code
6655 6868 der_decode_data(unsigned char *data, long data_len,
6656 6869 unsigned char **out, long *out_len)
6657 6870 {
6658 6871 /* Solaris Kerberos */
6659 6872 krb5_error_code retval = KRB5KRB_ERR_GENERIC;
6660 6873 ASN1_OCTET_STRING *s = NULL;
6661 6874 const unsigned char *p = data;
6662 6875
6663 6876 if ((s = d2i_ASN1_BIT_STRING(NULL, &p, data_len)) == NULL)
6664 6877 goto cleanup;
6665 6878 *out_len = s->length;
6666 6879 if ((*out = (unsigned char *) malloc((size_t) *out_len + 1)) == NULL) {
6667 6880 retval = ENOMEM;
6668 6881 goto cleanup;
6669 6882 }
6670 6883 (void) memcpy(*out, s->data, (size_t) s->length);
6671 6884 (*out)[s->length] = '\0';
6672 6885
6673 6886 retval = 0;
6674 6887 cleanup:
6675 6888 if (s != NULL)
6676 6889 ASN1_OCTET_STRING_free(s);
6677 6890
6678 6891 return retval;
6679 6892 }
6680 6893
6681 6894
6682 6895 #ifdef DEBUG_DH
6683 6896 static void
6684 6897 print_dh(DH * dh, char *msg)
6685 6898 {
6686 6899 BIO *bio_err = NULL;
6687 6900
6688 6901 bio_err = BIO_new(BIO_s_file());
6689 6902 BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
6690 6903
6691 6904 if (msg)
6692 6905 BIO_puts(bio_err, (const char *)msg);
6693 6906 if (dh)
6694 6907 DHparams_print(bio_err, dh);
6695 6908
6696 6909 BN_print(bio_err, dh->q);
6697 6910 BIO_puts(bio_err, (const char *)"\n");
6698 6911 BIO_free(bio_err);
6699 6912
6700 6913 }
6701 6914
6702 6915 static void
6703 6916 print_pubkey(BIGNUM * key, char *msg)
6704 6917 {
6705 6918 BIO *bio_err = NULL;
6706 6919
6707 6920 bio_err = BIO_new(BIO_s_file());
6708 6921 BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
6709 6922
6710 6923 if (msg)
6711 6924 BIO_puts(bio_err, (const char *)msg);
6712 6925 if (key)
6713 6926 BN_print(bio_err, key);
6714 6927 BIO_puts(bio_err, "\n");
6715 6928
6716 6929 BIO_free(bio_err);
6717 6930
6718 6931 }
6719 6932 #endif
6720 6933
6721 6934 /*
6722 6935 * Solaris Kerberos:
6723 6936 * Error message generation has changed so gettext() can be used
6724 6937 */
6725 6938 #if 0
6726 6939 static char *
6727 6940 pkinit_pkcs11_code_to_text(int err)
6728 6941 {
6729 6942 int i;
6730 6943 static char uc[64];
6731 6944
6732 6945 for (i = 0; pkcs11_errstrings[i].text != NULL; i++)
6733 6946 if (pkcs11_errstrings[i].code == err)
6734 6947 break;
6735 6948 if (pkcs11_errstrings[i].text != NULL)
6736 6949 return (pkcs11_errstrings[i].text);
6737 6950 snprintf(uc, 64, gettext("unknown code 0x%x"), err);
6738 6951 return (uc);
6739 6952 }
6740 6953 #endif
6741 6954
6742 6955 static char *
6743 6956 pkinit_pkcs11_code_to_text(int err) {
6744 6957 return pkcs11_error_table(err);
6745 6958 }
|
↓ open down ↓ |
121 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX