1 /* 2 * COPYRIGHT (C) 2006,2007 3 * THE REGENTS OF THE UNIVERSITY OF MICHIGAN 4 * ALL RIGHTS RESERVED 5 * 6 * Permission is granted to use, copy, create derivative works 7 * and redistribute this software and such derivative works 8 * for any purpose, so long as the name of The University of 9 * Michigan is not used in any advertising or publicity 10 * pertaining to the use of distribution of this software 11 * without specific, written prior authorization. If the 12 * above copyright notice or any other identification of the 13 * University of Michigan is included in any copy of any 14 * portion of this software, then the disclaimer below must 15 * also be included. 16 * 17 * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION 18 * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY 19 * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF 20 * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING 21 * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF 22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE 23 * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE 24 * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR 25 * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING 26 * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN 27 * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGES. 29 */ 30 31 /* 32 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 33 */ 34 35 #include <errno.h> 36 #include <string.h> 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <dlfcn.h> 40 #include <unistd.h> 41 #include <dirent.h> 42 43 44 /* Solaris Kerberos */ 45 #include <libintl.h> 46 #include "k5-int.h" 47 #include <ctype.h> 48 49 /* 50 * Q: What is this SILLYDECRYPT stuff about? 51 * A: When using the ActivCard Linux pkcs11 library (v2.0.1), 52 * the decrypt function fails. By inserting an extra 53 * function call, which serves nothing but to change the 54 * stack, we were able to work around the issue. If the 55 * ActivCard library is fixed in the future, this 56 * definition and related code can be removed. 57 */ 58 #define SILLYDECRYPT 59 60 #include "pkinit_crypto_openssl.h" 61 62 /* 63 * Solaris Kerberos: 64 * Changed to a switch statement so gettext() can be used 65 * for internationization. 66 * Use defined constants rather than raw numbers for error codes. 67 */ 68 static char * 69 pkcs11_error_table(short code) { 70 switch (code) { 71 case CKR_OK: 72 return (gettext("ok")); 73 case CKR_CANCEL: 74 return (gettext("cancel")); 75 case CKR_HOST_MEMORY: 76 return (gettext("host memory")); 77 case CKR_SLOT_ID_INVALID: 78 return (gettext("slot id invalid")); 79 case CKR_GENERAL_ERROR: 80 return (gettext("general error")); 81 case CKR_FUNCTION_FAILED: 82 return (gettext("function failed")); 83 case CKR_ARGUMENTS_BAD: 84 return (gettext("arguments bad")); 85 case CKR_NO_EVENT: 86 return (gettext("no event")); 87 case CKR_NEED_TO_CREATE_THREADS: 88 return (gettext("need to create threads")); 89 case CKR_CANT_LOCK: 90 return (gettext("cant lock")); 91 case CKR_ATTRIBUTE_READ_ONLY: 92 return (gettext("attribute read only")); 93 case CKR_ATTRIBUTE_SENSITIVE: 94 return (gettext("attribute sensitive")); 95 case CKR_ATTRIBUTE_TYPE_INVALID: 96 return (gettext("attribute type invalid")); 97 case CKR_ATTRIBUTE_VALUE_INVALID: 98 return (gettext("attribute value invalid")); 99 case CKR_DATA_INVALID: 100 return (gettext("data invalid")); 101 case CKR_DATA_LEN_RANGE: 102 return (gettext("data len range")); 103 case CKR_DEVICE_ERROR: 104 return (gettext("device error")); 105 case CKR_DEVICE_MEMORY: 106 return (gettext("device memory")); 107 case CKR_DEVICE_REMOVED: 108 return (gettext("device removed")); 109 case CKR_ENCRYPTED_DATA_INVALID: 110 return (gettext("encrypted data invalid")); 111 case CKR_ENCRYPTED_DATA_LEN_RANGE: 112 return (gettext("encrypted data len range")); 113 case CKR_FUNCTION_CANCELED: 114 return (gettext("function canceled")); 115 case CKR_FUNCTION_NOT_PARALLEL: 116 return (gettext("function not parallel")); 117 case CKR_FUNCTION_NOT_SUPPORTED: 118 return (gettext("function not supported")); 119 case CKR_KEY_HANDLE_INVALID: 120 return (gettext("key handle invalid")); 121 case CKR_KEY_SIZE_RANGE: 122 return (gettext("key size range")); 123 case CKR_KEY_TYPE_INCONSISTENT: 124 return (gettext("key type inconsistent")); 125 case CKR_KEY_NOT_NEEDED: 126 return (gettext("key not needed")); 127 case CKR_KEY_CHANGED: 128 return (gettext("key changed")); 129 case CKR_KEY_NEEDED: 130 return (gettext("key needed")); 131 case CKR_KEY_INDIGESTIBLE: 132 return (gettext("key indigestible")); 133 case CKR_KEY_FUNCTION_NOT_PERMITTED: 134 return (gettext("key function not permitted")); 135 case CKR_KEY_NOT_WRAPPABLE: 136 return (gettext("key not wrappable")); 137 case CKR_KEY_UNEXTRACTABLE: 138 return (gettext("key unextractable")); 139 case CKR_MECHANISM_INVALID: 140 return (gettext("mechanism invalid")); 141 case CKR_MECHANISM_PARAM_INVALID: 142 return (gettext("mechanism param invalid")); 143 case CKR_OBJECT_HANDLE_INVALID: 144 return (gettext("object handle invalid")); 145 case CKR_OPERATION_ACTIVE: 146 return (gettext("operation active")); 147 case CKR_OPERATION_NOT_INITIALIZED: 148 return (gettext("operation not initialized")); 149 case CKR_PIN_INCORRECT: 150 return (gettext("pin incorrect")); 151 case CKR_PIN_INVALID: 152 return (gettext("pin invalid")); 153 case CKR_PIN_LEN_RANGE: 154 return (gettext("pin len range")); 155 case CKR_PIN_EXPIRED: 156 return (gettext("pin expired")); 157 case CKR_PIN_LOCKED: 158 return (gettext("pin locked")); 159 case CKR_SESSION_CLOSED: 160 return (gettext("session closed")); 161 case CKR_SESSION_COUNT: 162 return (gettext("session count")); 163 case CKR_SESSION_HANDLE_INVALID: 164 return (gettext("session handle invalid")); 165 case CKR_SESSION_PARALLEL_NOT_SUPPORTED: 166 return (gettext("session parallel not supported")); 167 case CKR_SESSION_READ_ONLY: 168 return (gettext("session read only")); 169 case CKR_SESSION_EXISTS: 170 return (gettext("session exists")); 171 case CKR_SESSION_READ_ONLY_EXISTS: 172 return (gettext("session read only exists")); 173 case CKR_SESSION_READ_WRITE_SO_EXISTS: 174 return (gettext("session read write so exists")); 175 case CKR_SIGNATURE_INVALID: 176 return (gettext("signature invalid")); 177 case CKR_SIGNATURE_LEN_RANGE: 178 return (gettext("signature len range")); 179 case CKR_TEMPLATE_INCOMPLETE: 180 return (gettext("template incomplete")); 181 case CKR_TEMPLATE_INCONSISTENT: 182 return (gettext("template inconsistent")); 183 case CKR_TOKEN_NOT_PRESENT: 184 return (gettext("token not present")); 185 case CKR_TOKEN_NOT_RECOGNIZED: 186 return (gettext("token not recognized")); 187 case CKR_TOKEN_WRITE_PROTECTED: 188 return (gettext("token write protected")); 189 case CKR_UNWRAPPING_KEY_HANDLE_INVALID: 190 return (gettext("unwrapping key handle invalid")); 191 case CKR_UNWRAPPING_KEY_SIZE_RANGE: 192 return (gettext("unwrapping key size range")); 193 case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT: 194 return (gettext("unwrapping key type inconsistent")); 195 case CKR_USER_ALREADY_LOGGED_IN: 196 return (gettext("user already logged in")); 197 case CKR_USER_NOT_LOGGED_IN: 198 return (gettext("user not logged in")); 199 case CKR_USER_PIN_NOT_INITIALIZED: 200 return (gettext("user pin not initialized")); 201 case CKR_USER_TYPE_INVALID: 202 return (gettext("user type invalid")); 203 case CKR_USER_ANOTHER_ALREADY_LOGGED_IN: 204 return (gettext("user another already logged in")); 205 case CKR_USER_TOO_MANY_TYPES: 206 return (gettext("user too many types")); 207 case CKR_WRAPPED_KEY_INVALID: 208 return (gettext("wrapped key invalid")); 209 case CKR_WRAPPED_KEY_LEN_RANGE: 210 return (gettext("wrapped key len range")); 211 case CKR_WRAPPING_KEY_HANDLE_INVALID: 212 return (gettext("wrapping key handle invalid")); 213 case CKR_WRAPPING_KEY_SIZE_RANGE: 214 return (gettext("wrapping key size range")); 215 case CKR_WRAPPING_KEY_TYPE_INCONSISTENT: 216 return (gettext("wrapping key type inconsistent")); 217 case CKR_RANDOM_SEED_NOT_SUPPORTED: 218 return (gettext("random seed not supported")); 219 case CKR_RANDOM_NO_RNG: 220 return (gettext("random no rng")); 221 case CKR_DOMAIN_PARAMS_INVALID: 222 return (gettext("domain params invalid")); 223 case CKR_BUFFER_TOO_SMALL: 224 return (gettext("buffer too small")); 225 case CKR_SAVED_STATE_INVALID: 226 return (gettext("saved state invalid")); 227 case CKR_INFORMATION_SENSITIVE: 228 return (gettext("information sensitive")); 229 case CKR_STATE_UNSAVEABLE: 230 return (gettext("state unsaveable")); 231 case CKR_CRYPTOKI_NOT_INITIALIZED: 232 return (gettext("cryptoki not initialized")); 233 case CKR_CRYPTOKI_ALREADY_INITIALIZED: 234 return (gettext("cryptoki already initialized")); 235 case CKR_MUTEX_BAD: 236 return (gettext("mutex bad")); 237 case CKR_MUTEX_NOT_LOCKED: 238 return (gettext("mutex not locked")); 239 case CKR_FUNCTION_REJECTED: 240 return (gettext("function rejected")); 241 default: 242 return (gettext("unknown error")); 243 } 244 } 245 246 /* DH parameters */ 247 unsigned char pkinit_1024_dhprime[128] = { 248 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 249 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, 250 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 251 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 252 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 253 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, 254 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 255 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, 256 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 257 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 258 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 259 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, 260 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 261 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, 262 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, 263 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 264 }; 265 266 unsigned char pkinit_2048_dhprime[2048/8] = { 267 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 268 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, 269 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 270 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 271 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 272 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, 273 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 274 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, 275 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 276 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 277 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 278 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, 279 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 280 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, 281 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 282 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 283 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 284 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, 285 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 286 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, 287 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 288 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 289 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 290 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, 291 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 292 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, 293 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 294 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 295 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 296 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, 297 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 298 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 299 }; 300 301 unsigned char pkinit_4096_dhprime[4096/8] = { 302 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 303 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, 304 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 305 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 306 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 307 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, 308 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 309 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, 310 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 311 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 312 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 313 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, 314 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 315 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, 316 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 317 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 318 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 319 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, 320 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 321 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, 322 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 323 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 324 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 325 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, 326 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 327 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, 328 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 329 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 330 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 331 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, 332 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 333 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, 334 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, 335 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 336 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, 337 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, 338 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 339 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, 340 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, 341 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 342 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, 343 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, 344 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 345 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, 346 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, 347 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 348 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, 349 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, 350 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 351 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, 352 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, 353 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 354 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, 355 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, 356 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 357 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, 358 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, 359 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 360 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, 361 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, 362 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 363 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, 364 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99, 365 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 366 }; 367 368 /* Solaris Kerberos */ 369 static k5_mutex_t oids_mutex = K5_MUTEX_PARTIAL_INITIALIZER; 370 static int pkinit_oids_refs = 0; 371 372 krb5_error_code 373 pkinit_init_plg_crypto(pkinit_plg_crypto_context *cryptoctx) { 374 375 krb5_error_code retval = ENOMEM; 376 pkinit_plg_crypto_context ctx = NULL; 377 378 /* initialize openssl routines */ 379 /* Solaris Kerberos */ 380 retval = openssl_init(); 381 if (retval != 0) 382 goto out; 383 384 ctx = (pkinit_plg_crypto_context)malloc(sizeof(*ctx)); 385 if (ctx == NULL) 386 goto out; 387 (void) memset(ctx, 0, sizeof(*ctx)); 388 389 pkiDebug("%s: initializing openssl crypto context at %p\n", 390 __FUNCTION__, ctx); 391 retval = pkinit_init_pkinit_oids(ctx); 392 if (retval) 393 goto out; 394 395 retval = pkinit_init_dh_params(ctx); 396 if (retval) 397 goto out; 398 399 *cryptoctx = ctx; 400 401 out: 402 if (retval && ctx != NULL) 403 pkinit_fini_plg_crypto(ctx); 404 405 return retval; 406 } 407 408 void 409 pkinit_fini_plg_crypto(pkinit_plg_crypto_context cryptoctx) 410 { 411 pkiDebug("%s: freeing context at %p\n", __FUNCTION__, cryptoctx); 412 413 if (cryptoctx == NULL) 414 return; 415 pkinit_fini_pkinit_oids(cryptoctx); 416 pkinit_fini_dh_params(cryptoctx); 417 free(cryptoctx); 418 } 419 420 krb5_error_code 421 pkinit_init_identity_crypto(pkinit_identity_crypto_context *idctx) 422 { 423 krb5_error_code retval = ENOMEM; 424 pkinit_identity_crypto_context ctx = NULL; 425 426 ctx = (pkinit_identity_crypto_context)malloc(sizeof(*ctx)); 427 if (ctx == NULL) 428 goto out; 429 (void) memset(ctx, 0, sizeof(*ctx)); 430 431 retval = pkinit_init_certs(ctx); 432 if (retval) 433 goto out; 434 435 retval = pkinit_init_pkcs11(ctx); 436 if (retval) 437 goto out; 438 439 pkiDebug("%s: returning ctx at %p\n", __FUNCTION__, ctx); 440 *idctx = ctx; 441 442 out: 443 if (retval) { 444 if (ctx) 445 pkinit_fini_identity_crypto(ctx); 446 } 447 448 return retval; 449 } 450 451 void 452 pkinit_fini_identity_crypto(pkinit_identity_crypto_context idctx) 453 { 454 if (idctx == NULL) 455 return; 456 457 pkiDebug("%s: freeing ctx at %p\n", __FUNCTION__, idctx); 458 pkinit_fini_certs(idctx); 459 pkinit_fini_pkcs11(idctx); 460 free(idctx); 461 } 462 463 krb5_error_code 464 pkinit_init_req_crypto(pkinit_req_crypto_context *cryptoctx) 465 { 466 467 pkinit_req_crypto_context ctx = NULL; 468 469 /* Solaris Kerberos */ 470 if (cryptoctx == NULL) 471 return EINVAL; 472 473 ctx = (pkinit_req_crypto_context)malloc(sizeof(*ctx)); 474 if (ctx == NULL) 475 return ENOMEM; 476 (void) memset(ctx, 0, sizeof(*ctx)); 477 478 ctx->dh = NULL; 479 ctx->received_cert = NULL; 480 481 *cryptoctx = ctx; 482 483 pkiDebug("%s: returning ctx at %p\n", __FUNCTION__, ctx); 484 485 return 0; 486 } 487 488 void 489 pkinit_fini_req_crypto(pkinit_req_crypto_context req_cryptoctx) 490 { 491 if (req_cryptoctx == NULL) 492 return; 493 494 pkiDebug("%s: freeing ctx at %p\n", __FUNCTION__, req_cryptoctx); 495 if (req_cryptoctx->dh != NULL) 496 DH_free(req_cryptoctx->dh); 497 if (req_cryptoctx->received_cert != NULL) 498 X509_free(req_cryptoctx->received_cert); 499 500 free(req_cryptoctx); 501 } 502 503 static krb5_error_code 504 pkinit_init_pkinit_oids(pkinit_plg_crypto_context ctx) 505 { 506 krb5_error_code retval = ENOMEM; 507 int nid = 0; 508 509 /* 510 * If OpenSSL already knows about the OID, use the 511 * existing definition. Otherwise, create an OID object. 512 */ 513 #define CREATE_OBJ_IF_NEEDED(oid, vn, sn, ln) \ 514 nid = OBJ_txt2nid(oid); \ 515 if (nid == NID_undef) { \ 516 nid = OBJ_create(oid, sn, ln); \ 517 if (nid == NID_undef) { \ 518 pkiDebug("Error creating oid object for '%s'\n", oid); \ 519 goto out; \ 520 } \ 521 } \ 522 ctx->vn = OBJ_nid2obj(nid); 523 524 /* Solaris Kerberos */ 525 retval = k5_mutex_lock(&oids_mutex); 526 if (retval != 0) 527 goto out; 528 529 CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.2", id_pkinit_san, 530 "id-pkinit-san", "KRB5PrincipalName"); 531 532 CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.1", id_pkinit_authData, 533 "id-pkinit-authdata", "PKINIT signedAuthPack"); 534 535 CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.2", id_pkinit_DHKeyData, 536 "id-pkinit-DHKeyData", "PKINIT dhSignedData"); 537 538 CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.3", id_pkinit_rkeyData, 539 "id-pkinit-rkeyData", "PKINIT encKeyPack"); 540 541 CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.4", id_pkinit_KPClientAuth, 542 "id-pkinit-KPClientAuth", "PKINIT Client EKU"); 543 544 CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.5", id_pkinit_KPKdc, 545 "id-pkinit-KPKdc", "KDC EKU"); 546 547 #if 0 548 CREATE_OBJ_IF_NEEDED("1.2.840.113549.1.7.1", id_pkinit_authData9, 549 "id-pkcs7-data", "PKCS7 data"); 550 #else 551 /* See note in pkinit_pkcs7type2oid() */ 552 ctx->id_pkinit_authData9 = NULL; 553 #endif 554 555 CREATE_OBJ_IF_NEEDED("1.3.6.1.4.1.311.20.2.2", id_ms_kp_sc_logon, 556 "id-ms-kp-sc-logon EKU", "Microsoft SmartCard Login EKU"); 557 558 CREATE_OBJ_IF_NEEDED("1.3.6.1.4.1.311.20.2.3", id_ms_san_upn, 559 "id-ms-san-upn", "Microsoft Universal Principal Name"); 560 561 CREATE_OBJ_IF_NEEDED("1.3.6.1.5.5.7.3.1", id_kp_serverAuth, 562 "id-kp-serverAuth EKU", "Server Authentication EKU"); 563 564 /* Success */ 565 retval = 0; 566 567 pkinit_oids_refs++; 568 /* Solaris Kerberos */ 569 k5_mutex_unlock(&oids_mutex); 570 571 out: 572 return retval; 573 } 574 575 static krb5_error_code 576 get_cert(char *filename, X509 **retcert) 577 { 578 X509 *cert = NULL; 579 BIO *tmp = NULL; 580 int code; 581 krb5_error_code retval; 582 583 if (filename == NULL || retcert == NULL) 584 return EINVAL; 585 586 *retcert = NULL; 587 588 tmp = BIO_new(BIO_s_file()); 589 if (tmp == NULL) 590 return ENOMEM; 591 592 code = BIO_read_filename(tmp, filename); 593 if (code == 0) { 594 retval = errno; 595 goto cleanup; 596 } 597 598 cert = (X509 *) PEM_read_bio_X509(tmp, NULL, NULL, NULL); 599 if (cert == NULL) { 600 retval = EIO; 601 pkiDebug("failed to read certificate from %s\n", filename); 602 goto cleanup; 603 } 604 *retcert = cert; 605 retval = 0; 606 cleanup: 607 if (tmp != NULL) 608 BIO_free(tmp); 609 return retval; 610 } 611 612 static krb5_error_code 613 get_key(char *filename, EVP_PKEY **retkey) 614 { 615 EVP_PKEY *pkey = NULL; 616 BIO *tmp = NULL; 617 int code; 618 krb5_error_code retval; 619 620 if (filename == NULL || retkey == NULL) 621 return EINVAL; 622 623 tmp = BIO_new(BIO_s_file()); 624 if (tmp == NULL) 625 return ENOMEM; 626 627 code = BIO_read_filename(tmp, filename); 628 if (code == 0) { 629 retval = errno; 630 goto cleanup; 631 } 632 pkey = (EVP_PKEY *) PEM_read_bio_PrivateKey(tmp, NULL, NULL, NULL); 633 if (pkey == NULL) { 634 retval = EIO; 635 pkiDebug("failed to read private key from %s\n", filename); 636 goto cleanup; 637 } 638 *retkey = pkey; 639 retval = 0; 640 cleanup: 641 if (tmp != NULL) 642 BIO_free(tmp); 643 return retval; 644 } 645 646 static void 647 pkinit_fini_pkinit_oids(pkinit_plg_crypto_context ctx) 648 { 649 if (ctx == NULL) 650 return; 651 652 /* Only call OBJ_cleanup once! */ 653 /* Solaris Kerberos: locking */ 654 k5_mutex_lock(&oids_mutex); 655 if (--pkinit_oids_refs == 0) 656 OBJ_cleanup(); 657 k5_mutex_unlock(&oids_mutex); 658 } 659 660 static krb5_error_code 661 pkinit_init_dh_params(pkinit_plg_crypto_context plgctx) 662 { 663 krb5_error_code retval = ENOMEM; 664 665 plgctx->dh_1024 = DH_new(); 666 if (plgctx->dh_1024 == NULL) 667 goto cleanup; 668 plgctx->dh_1024->p = BN_bin2bn(pkinit_1024_dhprime, 669 sizeof(pkinit_1024_dhprime), NULL); 670 if ((plgctx->dh_1024->g = BN_new()) == NULL || 671 (plgctx->dh_1024->q = BN_new()) == NULL) 672 goto cleanup; 673 BN_set_word(plgctx->dh_1024->g, DH_GENERATOR_2); 674 BN_rshift1(plgctx->dh_1024->q, plgctx->dh_1024->p); 675 676 plgctx->dh_2048 = DH_new(); 677 if (plgctx->dh_2048 == NULL) 678 goto cleanup; 679 plgctx->dh_2048->p = BN_bin2bn(pkinit_2048_dhprime, 680 sizeof(pkinit_2048_dhprime), NULL); 681 if ((plgctx->dh_2048->g = BN_new()) == NULL || 682 (plgctx->dh_2048->q = BN_new()) == NULL) 683 goto cleanup; 684 BN_set_word(plgctx->dh_2048->g, DH_GENERATOR_2); 685 BN_rshift1(plgctx->dh_2048->q, plgctx->dh_2048->p); 686 687 plgctx->dh_4096 = DH_new(); 688 if (plgctx->dh_4096 == NULL) 689 goto cleanup; 690 plgctx->dh_4096->p = BN_bin2bn(pkinit_4096_dhprime, 691 sizeof(pkinit_4096_dhprime), NULL); 692 if ((plgctx->dh_4096->g = BN_new()) == NULL || 693 (plgctx->dh_4096->q = BN_new()) == NULL) 694 goto cleanup; 695 BN_set_word(plgctx->dh_4096->g, DH_GENERATOR_2); 696 BN_rshift1(plgctx->dh_4096->q, plgctx->dh_4096->p); 697 698 retval = 0; 699 700 cleanup: 701 if (retval) 702 pkinit_fini_dh_params(plgctx); 703 704 return retval; 705 } 706 707 static void 708 pkinit_fini_dh_params(pkinit_plg_crypto_context plgctx) 709 { 710 if (plgctx->dh_1024 != NULL) 711 DH_free(plgctx->dh_1024); 712 if (plgctx->dh_2048 != NULL) 713 DH_free(plgctx->dh_2048); 714 if (plgctx->dh_4096 != NULL) 715 DH_free(plgctx->dh_4096); 716 717 plgctx->dh_1024 = plgctx->dh_2048 = plgctx->dh_4096 = NULL; 718 } 719 720 static krb5_error_code 721 pkinit_init_certs(pkinit_identity_crypto_context ctx) 722 { 723 /* Solaris Kerberos */ 724 int i; 725 726 for (i = 0; i < MAX_CREDS_ALLOWED; i++) 727 ctx->creds[i] = NULL; 728 ctx->my_certs = NULL; 729 ctx->cert_index = 0; 730 ctx->my_key = NULL; 731 ctx->trustedCAs = NULL; 732 ctx->intermediateCAs = NULL; 733 ctx->revoked = NULL; 734 735 return 0; 736 } 737 738 static void 739 pkinit_fini_certs(pkinit_identity_crypto_context ctx) 740 { 741 if (ctx == NULL) 742 return; 743 744 if (ctx->my_certs != NULL) 745 sk_X509_pop_free(ctx->my_certs, X509_free); 746 747 if (ctx->my_key != NULL) 748 EVP_PKEY_free(ctx->my_key); 749 750 if (ctx->trustedCAs != NULL) 751 sk_X509_pop_free(ctx->trustedCAs, X509_free); 752 753 if (ctx->intermediateCAs != NULL) 754 sk_X509_pop_free(ctx->intermediateCAs, X509_free); 755 756 if (ctx->revoked != NULL) 757 sk_X509_CRL_pop_free(ctx->revoked, X509_CRL_free); 758 } 759 760 static krb5_error_code 761 pkinit_init_pkcs11(pkinit_identity_crypto_context ctx) 762 { 763 /* Solaris Kerberos */ 764 765 #ifndef WITHOUT_PKCS11 766 ctx->p11_module_name = strdup(PKCS11_MODNAME); 767 if (ctx->p11_module_name == NULL) 768 return ENOMEM; 769 ctx->p11_module = NULL; 770 ctx->slotid = PK_NOSLOT; 771 ctx->token_label = NULL; 772 ctx->cert_label = NULL; 773 ctx->PIN = NULL; 774 ctx->session = CK_INVALID_HANDLE; 775 ctx->p11 = NULL; 776 ctx->p11flags = 0; /* Solaris Kerberos */ 777 #endif 778 ctx->pkcs11_method = 0; 779 780 return 0; 781 } 782 783 static void 784 pkinit_fini_pkcs11(pkinit_identity_crypto_context ctx) 785 { 786 #ifndef WITHOUT_PKCS11 787 if (ctx == NULL) 788 return; 789 790 if (ctx->p11 != NULL) { 791 if (ctx->session) { 792 ctx->p11->C_CloseSession(ctx->session); 793 ctx->session = CK_INVALID_HANDLE; 794 } 795 /* 796 * Solaris Kerberos: 797 * Only call C_Finalize if the process was not already using pkcs11. 798 */ 799 if (ctx->finalize_pkcs11 == TRUE) 800 ctx->p11->C_Finalize(NULL_PTR); 801 802 ctx->p11 = NULL; 803 } 804 if (ctx->p11_module != NULL) { 805 pkinit_C_UnloadModule(ctx->p11_module); 806 ctx->p11_module = NULL; 807 } 808 if (ctx->p11_module_name != NULL) 809 free(ctx->p11_module_name); 810 if (ctx->token_label != NULL) 811 free(ctx->token_label); 812 if (ctx->cert_id != NULL) 813 free(ctx->cert_id); 814 if (ctx->cert_label != NULL) 815 free(ctx->cert_label); 816 if (ctx->PIN != NULL) { 817 (void) memset(ctx->PIN, 0, strlen(ctx->PIN)); 818 free(ctx->PIN); 819 } 820 #endif 821 } 822 823 krb5_error_code 824 pkinit_identity_set_prompter(pkinit_identity_crypto_context id_cryptoctx, 825 krb5_prompter_fct prompter, 826 void *prompter_data) 827 { 828 id_cryptoctx->prompter = prompter; 829 id_cryptoctx->prompter_data = prompter_data; 830 831 return 0; 832 } 833 834 /* ARGSUSED */ 835 krb5_error_code 836 cms_signeddata_create(krb5_context context, 837 pkinit_plg_crypto_context plg_cryptoctx, 838 pkinit_req_crypto_context req_cryptoctx, 839 pkinit_identity_crypto_context id_cryptoctx, 840 int cms_msg_type, 841 int include_certchain, 842 unsigned char *data, 843 unsigned int data_len, 844 unsigned char **signed_data, 845 unsigned int *signed_data_len) 846 { 847 /* Solaris Kerberos */ 848 krb5_error_code retval = KRB5KRB_ERR_GENERIC; 849 PKCS7 *p7 = NULL, *inner_p7 = NULL; 850 PKCS7_SIGNED *p7s = NULL; 851 PKCS7_SIGNER_INFO *p7si = NULL; 852 unsigned char *p; 853 ASN1_TYPE *pkinit_data = NULL; 854 STACK_OF(X509) * cert_stack = NULL; 855 ASN1_OCTET_STRING *digest_attr = NULL; 856 EVP_MD_CTX ctx, ctx2; 857 const EVP_MD *md_tmp = NULL; 858 unsigned char md_data[EVP_MAX_MD_SIZE], md_data2[EVP_MAX_MD_SIZE]; 859 unsigned char *digestInfo_buf = NULL, *abuf = NULL; 860 unsigned int md_len, md_len2, alen, digestInfo_len; 861 STACK_OF(X509_ATTRIBUTE) * sk; 862 unsigned char *sig = NULL; 863 unsigned int sig_len = 0; 864 X509_ALGOR *alg = NULL; 865 ASN1_OCTET_STRING *digest = NULL; 866 unsigned int alg_len = 0, digest_len = 0; 867 unsigned char *y = NULL, *alg_buf = NULL, *digest_buf = NULL; 868 X509 *cert = NULL; 869 ASN1_OBJECT *oid = NULL; 870 871 /* Solaris Kerberos */ 872 if (signed_data == NULL) 873 return EINVAL; 874 875 if (signed_data_len == NULL) 876 return EINVAL; 877 878 /* start creating PKCS7 data */ 879 if ((p7 = PKCS7_new()) == NULL) 880 goto cleanup; 881 p7->type = OBJ_nid2obj(NID_pkcs7_signed); 882 883 if ((p7s = PKCS7_SIGNED_new()) == NULL) 884 goto cleanup; 885 p7->d.sign = p7s; 886 if (!ASN1_INTEGER_set(p7s->version, 3)) 887 goto cleanup; 888 889 /* create a cert chain that has at least the signer's certificate */ 890 if ((cert_stack = sk_X509_new_null()) == NULL) 891 goto cleanup; 892 893 cert = sk_X509_value(id_cryptoctx->my_certs, id_cryptoctx->cert_index); 894 if (!include_certchain) { 895 pkiDebug("only including signer's certificate\n"); 896 sk_X509_push(cert_stack, X509_dup(cert)); 897 } else { 898 /* create a cert chain */ 899 X509_STORE *certstore = NULL; 900 X509_STORE_CTX certctx; 901 STACK_OF(X509) *certstack = NULL; 902 char buf[DN_BUF_LEN]; 903 int i = 0, size = 0; 904 905 if ((certstore = X509_STORE_new()) == NULL) 906 goto cleanup; 907 pkiDebug("building certificate chain\n"); 908 X509_STORE_set_verify_cb_func(certstore, openssl_callback); 909 X509_STORE_CTX_init(&certctx, certstore, cert, 910 id_cryptoctx->intermediateCAs); 911 X509_STORE_CTX_trusted_stack(&certctx, id_cryptoctx->trustedCAs); 912 /* Solaris Kerberos */ 913 if (X509_verify_cert(&certctx) <= 0) { 914 pkiDebug("failed to create a certificate chain: %s\n", 915 X509_verify_cert_error_string(X509_STORE_CTX_get_error(&certctx))); 916 if (!sk_X509_num(id_cryptoctx->trustedCAs)) 917 pkiDebug("No trusted CAs found. Check your X509_anchors\n"); 918 goto cleanup; 919 } 920 certstack = X509_STORE_CTX_get1_chain(&certctx); 921 size = sk_X509_num(certstack); 922 pkiDebug("size of certificate chain = %d\n", size); 923 for(i = 0; i < size - 1; i++) { 924 X509 *x = sk_X509_value(certstack, i); 925 X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf)); 926 pkiDebug("cert #%d: %s\n", i, buf); 927 sk_X509_push(cert_stack, X509_dup(x)); 928 } 929 X509_STORE_CTX_cleanup(&certctx); 930 X509_STORE_free(certstore); 931 sk_X509_pop_free(certstack, X509_free); 932 } 933 p7s->cert = cert_stack; 934 935 /* fill-in PKCS7_SIGNER_INFO */ 936 if ((p7si = PKCS7_SIGNER_INFO_new()) == NULL) 937 goto cleanup; 938 if (!ASN1_INTEGER_set(p7si->version, 1)) 939 goto cleanup; 940 if (!X509_NAME_set(&p7si->issuer_and_serial->issuer, 941 X509_get_issuer_name(cert))) 942 goto cleanup; 943 /* because ASN1_INTEGER_set is used to set a 'long' we will do 944 * things the ugly way. */ 945 M_ASN1_INTEGER_free(p7si->issuer_and_serial->serial); 946 if (!(p7si->issuer_and_serial->serial = 947 M_ASN1_INTEGER_dup(X509_get_serialNumber(cert)))) 948 goto cleanup; 949 950 /* will not fill-out EVP_PKEY because it's on the smartcard */ 951 952 /* Set digest algs */ 953 p7si->digest_alg->algorithm = OBJ_nid2obj(NID_sha1); 954 955 if (p7si->digest_alg->parameter != NULL) 956 ASN1_TYPE_free(p7si->digest_alg->parameter); 957 if ((p7si->digest_alg->parameter = ASN1_TYPE_new()) == NULL) 958 goto cleanup; 959 p7si->digest_alg->parameter->type = V_ASN1_NULL; 960 961 /* Set sig algs */ 962 if (p7si->digest_enc_alg->parameter != NULL) 963 ASN1_TYPE_free(p7si->digest_enc_alg->parameter); 964 p7si->digest_enc_alg->algorithm = OBJ_nid2obj(NID_sha1WithRSAEncryption); 965 if (!(p7si->digest_enc_alg->parameter = ASN1_TYPE_new())) 966 goto cleanup; 967 p7si->digest_enc_alg->parameter->type = V_ASN1_NULL; 968 969 /* pick the correct oid for the eContentInfo */ 970 oid = pkinit_pkcs7type2oid(plg_cryptoctx, cms_msg_type); 971 if (oid == NULL) 972 goto cleanup; 973 974 if (cms_msg_type == CMS_SIGN_DRAFT9) { 975 /* don't include signed attributes for pa-type 15 request */ 976 abuf = data; 977 alen = data_len; 978 } else { 979 /* add signed attributes */ 980 /* compute sha1 digest over the EncapsulatedContentInfo */ 981 EVP_MD_CTX_init(&ctx); 982 EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL); 983 EVP_DigestUpdate(&ctx, data, data_len); 984 md_tmp = EVP_MD_CTX_md(&ctx); 985 EVP_DigestFinal_ex(&ctx, md_data, &md_len); 986 987 /* create a message digest attr */ 988 digest_attr = ASN1_OCTET_STRING_new(); 989 ASN1_OCTET_STRING_set(digest_attr, md_data, (int)md_len); 990 PKCS7_add_signed_attribute(p7si, NID_pkcs9_messageDigest, 991 V_ASN1_OCTET_STRING, (char *) digest_attr); 992 993 /* create a content-type attr */ 994 PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType, 995 V_ASN1_OBJECT, oid); 996 997 /* create the signature over signed attributes. get DER encoded value */ 998 /* This is the place where smartcard signature needs to be calculated */ 999 sk = p7si->auth_attr; 1000 alen = ASN1_item_i2d((ASN1_VALUE *) sk, &abuf, 1001 ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); 1002 if (abuf == NULL) 1003 goto cleanup2; 1004 } 1005 1006 #ifndef WITHOUT_PKCS11 1007 /* Some tokens can only do RSAEncryption without sha1 hash */ 1008 /* to compute sha1WithRSAEncryption, encode the algorithm ID for the hash 1009 * function and the hash value into an ASN.1 value of type DigestInfo 1010 * DigestInfo::=SEQUENCE { 1011 * digestAlgorithm AlgorithmIdentifier, 1012 * digest OCTET STRING } 1013 */ 1014 if (id_cryptoctx->pkcs11_method == 1 && 1015 id_cryptoctx->mech == CKM_RSA_PKCS) { 1016 pkiDebug("mech = CKM_RSA_PKCS\n"); 1017 EVP_MD_CTX_init(&ctx2); 1018 /* if this is not draft9 request, include digest signed attribute */ 1019 if (cms_msg_type != CMS_SIGN_DRAFT9) 1020 EVP_DigestInit_ex(&ctx2, md_tmp, NULL); 1021 else 1022 EVP_DigestInit_ex(&ctx2, EVP_sha1(), NULL); 1023 EVP_DigestUpdate(&ctx2, abuf, alen); 1024 EVP_DigestFinal_ex(&ctx2, md_data2, &md_len2); 1025 1026 alg = X509_ALGOR_new(); 1027 if (alg == NULL) 1028 goto cleanup2; 1029 alg->algorithm = OBJ_nid2obj(NID_sha1); 1030 alg->parameter = NULL; 1031 alg_len = i2d_X509_ALGOR(alg, NULL); 1032 alg_buf = (unsigned char *)malloc(alg_len); 1033 if (alg_buf == NULL) 1034 goto cleanup2; 1035 1036 digest = ASN1_OCTET_STRING_new(); 1037 if (digest == NULL) 1038 goto cleanup2; 1039 ASN1_OCTET_STRING_set(digest, md_data2, (int)md_len2); 1040 digest_len = i2d_ASN1_OCTET_STRING(digest, NULL); 1041 digest_buf = (unsigned char *)malloc(digest_len); 1042 if (digest_buf == NULL) 1043 goto cleanup2; 1044 1045 digestInfo_len = ASN1_object_size(1, (int)(alg_len + digest_len), 1046 V_ASN1_SEQUENCE); 1047 y = digestInfo_buf = (unsigned char *)malloc(digestInfo_len); 1048 if (digestInfo_buf == NULL) 1049 goto cleanup2; 1050 ASN1_put_object(&y, 1, (int)(alg_len + digest_len), V_ASN1_SEQUENCE, 1051 V_ASN1_UNIVERSAL); 1052 i2d_X509_ALGOR(alg, &y); 1053 i2d_ASN1_OCTET_STRING(digest, &y); 1054 #ifdef DEBUG_SIG 1055 pkiDebug("signing buffer\n"); 1056 print_buffer(digestInfo_buf, digestInfo_len); 1057 print_buffer_bin(digestInfo_buf, digestInfo_len, "/tmp/pkcs7_tosign"); 1058 #endif 1059 retval = pkinit_sign_data(context, id_cryptoctx, digestInfo_buf, 1060 digestInfo_len, &sig, &sig_len); 1061 } else 1062 #endif 1063 { 1064 pkiDebug("mech = %s\n", 1065 id_cryptoctx->pkcs11_method == 1 ? "CKM_SHA1_RSA_PKCS" : "FS"); 1066 retval = pkinit_sign_data(context, id_cryptoctx, abuf, alen, 1067 &sig, &sig_len); 1068 } 1069 #ifdef DEBUG_SIG 1070 print_buffer(sig, sig_len); 1071 #endif 1072 if (cms_msg_type != CMS_SIGN_DRAFT9) 1073 free(abuf); 1074 if (retval) 1075 goto cleanup2; 1076 1077 /* Add signature */ 1078 if (!ASN1_STRING_set(p7si->enc_digest, (unsigned char *) sig, 1079 (int)sig_len)) { 1080 unsigned long err = ERR_peek_error(); 1081 retval = KRB5KDC_ERR_PREAUTH_FAILED; 1082 krb5_set_error_message(context, retval, "%s\n", 1083 ERR_error_string(err, NULL)); 1084 pkiDebug("failed to add a signed digest attribute\n"); 1085 goto cleanup2; 1086 } 1087 /* adder signer_info to pkcs7 signed */ 1088 if (!PKCS7_add_signer(p7, p7si)) 1089 goto cleanup2; 1090 1091 /* start on adding data to the pkcs7 signed */ 1092 if ((inner_p7 = PKCS7_new()) == NULL) 1093 goto cleanup2; 1094 if ((pkinit_data = ASN1_TYPE_new()) == NULL) 1095 goto cleanup2; 1096 pkinit_data->type = V_ASN1_OCTET_STRING; 1097 if ((pkinit_data->value.octet_string = ASN1_OCTET_STRING_new()) == NULL) 1098 goto cleanup2; 1099 if (!ASN1_OCTET_STRING_set(pkinit_data->value.octet_string, data, 1100 (int)data_len)) { 1101 unsigned long err = ERR_peek_error(); 1102 retval = KRB5KDC_ERR_PREAUTH_FAILED; 1103 krb5_set_error_message(context, retval, "%s\n", 1104 ERR_error_string(err, NULL)); 1105 pkiDebug("failed to add pkcs7 data\n"); 1106 goto cleanup2; 1107 } 1108 1109 if (!PKCS7_set0_type_other(inner_p7, OBJ_obj2nid(oid), pkinit_data)) 1110 goto cleanup2; 1111 1112 if (p7s->contents != NULL) 1113 PKCS7_free(p7s->contents); 1114 p7s->contents = inner_p7; 1115 1116 *signed_data_len = i2d_PKCS7(p7, NULL); 1117 if (!(*signed_data_len)) { 1118 unsigned long err = ERR_peek_error(); 1119 retval = KRB5KDC_ERR_PREAUTH_FAILED; 1120 krb5_set_error_message(context, retval, "%s\n", 1121 ERR_error_string(err, NULL)); 1122 pkiDebug("failed to der encode pkcs7\n"); 1123 goto cleanup2; 1124 } 1125 if ((p = *signed_data = 1126 (unsigned char *) malloc((size_t)*signed_data_len)) == NULL) 1127 goto cleanup2; 1128 1129 /* DER encode PKCS7 data */ 1130 retval = i2d_PKCS7(p7, &p); 1131 if (!retval) { 1132 unsigned long err = ERR_peek_error(); 1133 retval = KRB5KDC_ERR_PREAUTH_FAILED; 1134 krb5_set_error_message(context, retval, "%s\n", 1135 ERR_error_string(err, NULL)); 1136 pkiDebug("failed to der encode pkcs7\n"); 1137 goto cleanup2; 1138 } 1139 retval = 0; 1140 1141 #ifdef DEBUG_ASN1 1142 if (cms_msg_type == CMS_SIGN_CLIENT) { 1143 print_buffer_bin(*signed_data, *signed_data_len, 1144 "/tmp/client_pkcs7_signeddata"); 1145 } else { 1146 if (cms_msg_type == CMS_SIGN_SERVER) { 1147 print_buffer_bin(*signed_data, *signed_data_len, 1148 "/tmp/kdc_pkcs7_signeddata"); 1149 } else { 1150 print_buffer_bin(*signed_data, *signed_data_len, 1151 "/tmp/draft9_pkcs7_signeddata"); 1152 } 1153 } 1154 #endif 1155 1156 cleanup2: 1157 if (cms_msg_type != CMS_SIGN_DRAFT9) 1158 EVP_MD_CTX_cleanup(&ctx); 1159 #ifndef WITHOUT_PKCS11 1160 if (id_cryptoctx->pkcs11_method == 1 && 1161 id_cryptoctx->mech == CKM_RSA_PKCS) { 1162 EVP_MD_CTX_cleanup(&ctx2); 1163 if (digest_buf != NULL) 1164 free(digest_buf); 1165 if (digestInfo_buf != NULL) 1166 free(digestInfo_buf); 1167 if (alg_buf != NULL) 1168 free(alg_buf); 1169 if (digest != NULL) 1170 ASN1_OCTET_STRING_free(digest); 1171 } 1172 #endif 1173 if (alg != NULL) 1174 X509_ALGOR_free(alg); 1175 cleanup: 1176 if (p7 != NULL) 1177 PKCS7_free(p7); 1178 if (sig != NULL) 1179 free(sig); 1180 1181 return retval; 1182 } 1183 1184 krb5_error_code 1185 cms_signeddata_verify(krb5_context context, 1186 pkinit_plg_crypto_context plgctx, 1187 pkinit_req_crypto_context reqctx, 1188 pkinit_identity_crypto_context idctx, 1189 int cms_msg_type, 1190 int require_crl_checking, 1191 unsigned char *signed_data, 1192 unsigned int signed_data_len, 1193 unsigned char **data, 1194 unsigned int *data_len, 1195 unsigned char **authz_data, 1196 unsigned int *authz_data_len) 1197 { 1198 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED; 1199 PKCS7 *p7 = NULL; 1200 BIO *out = NULL; 1201 int flags = PKCS7_NOVERIFY, i = 0; 1202 unsigned int vflags = 0, size = 0; 1203 const unsigned char *p = signed_data; 1204 STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL; 1205 PKCS7_SIGNER_INFO *si = NULL; 1206 X509 *x = NULL; 1207 X509_STORE *store = NULL; 1208 X509_STORE_CTX cert_ctx; 1209 STACK_OF(X509) *intermediateCAs = NULL; 1210 STACK_OF(X509_CRL) *revoked = NULL; 1211 STACK_OF(X509) *verified_chain = NULL; 1212 ASN1_OBJECT *oid = NULL; 1213 krb5_external_principal_identifier **krb5_verified_chain = NULL; 1214 krb5_data *authz = NULL; 1215 char buf[DN_BUF_LEN]; 1216 1217 #ifdef DEBUG_ASN1 1218 print_buffer_bin(signed_data, signed_data_len, 1219 "/tmp/client_received_pkcs7_signeddata"); 1220 #endif 1221 1222 /* Do this early enough to create the shadow OID for pkcs7-data if needed */ 1223 oid = pkinit_pkcs7type2oid(plgctx, cms_msg_type); 1224 if (oid == NULL) 1225 goto cleanup; 1226 1227 /* decode received PKCS7 message */ 1228 if ((p7 = d2i_PKCS7(NULL, &p, (int)signed_data_len)) == NULL) { 1229 unsigned long err = ERR_peek_error(); 1230 krb5_set_error_message(context, retval, "%s\n", 1231 ERR_error_string(err, NULL)); 1232 pkiDebug("%s: failed to decode message: %s\n", 1233 __FUNCTION__, ERR_error_string(err, NULL)); 1234 goto cleanup; 1235 } 1236 1237 /* verify that the received message is PKCS7 SignedData message */ 1238 if (OBJ_obj2nid(p7->type) != NID_pkcs7_signed) { 1239 pkiDebug("Expected id-signedData PKCS7 msg (received type = %d)\n", 1240 OBJ_obj2nid(p7->type)); 1241 krb5_set_error_message(context, retval, "wrong oid\n"); 1242 goto cleanup; 1243 } 1244 1245 /* setup to verify X509 certificate used to sign PKCS7 message */ 1246 if (!(store = X509_STORE_new())) 1247 goto cleanup; 1248 1249 /* check if we are inforcing CRL checking */ 1250 vflags = X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL; 1251 if (require_crl_checking) 1252 X509_STORE_set_verify_cb_func(store, openssl_callback); 1253 else 1254 X509_STORE_set_verify_cb_func(store, openssl_callback_ignore_crls); 1255 X509_STORE_set_flags(store, vflags); 1256 1257 /* get the signer's information from the PKCS7 message */ 1258 if ((si_sk = PKCS7_get_signer_info(p7)) == NULL) 1259 goto cleanup; 1260 if ((si = sk_PKCS7_SIGNER_INFO_value(si_sk, 0)) == NULL) 1261 goto cleanup; 1262 if ((x = PKCS7_cert_from_signer_info(p7, si)) == NULL) 1263 goto cleanup; 1264 1265 /* create available CRL information (get local CRLs and include CRLs 1266 * received in the PKCS7 message 1267 */ 1268 if (idctx->revoked == NULL) 1269 revoked = p7->d.sign->crl; 1270 else if (p7->d.sign->crl == NULL) 1271 revoked = idctx->revoked; 1272 else { 1273 size = sk_X509_CRL_num(idctx->revoked); 1274 revoked = sk_X509_CRL_new_null(); 1275 for (i = 0; i < size; i++) 1276 sk_X509_CRL_push(revoked, sk_X509_CRL_value(idctx->revoked, i)); 1277 size = sk_X509_num(p7->d.sign->crl); 1278 for (i = 0; i < size; i++) 1279 sk_X509_CRL_push(revoked, sk_X509_CRL_value(p7->d.sign->crl, i)); 1280 } 1281 1282 /* create available intermediate CAs chains (get local intermediateCAs and 1283 * include the CA chain received in the PKCS7 message 1284 */ 1285 if (idctx->intermediateCAs == NULL) 1286 intermediateCAs = p7->d.sign->cert; 1287 else if (p7->d.sign->cert == NULL) 1288 intermediateCAs = idctx->intermediateCAs; 1289 else { 1290 size = sk_X509_num(idctx->intermediateCAs); 1291 intermediateCAs = sk_X509_new_null(); 1292 for (i = 0; i < size; i++) { 1293 sk_X509_push(intermediateCAs, 1294 sk_X509_value(idctx->intermediateCAs, i)); 1295 } 1296 size = sk_X509_num(p7->d.sign->cert); 1297 for (i = 0; i < size; i++) { 1298 sk_X509_push(intermediateCAs, sk_X509_value(p7->d.sign->cert, i)); 1299 } 1300 } 1301 1302 /* initialize x509 context with the received certificate and 1303 * trusted and intermediate CA chains and CRLs 1304 */ 1305 if (!X509_STORE_CTX_init(&cert_ctx, store, x, intermediateCAs)) 1306 goto cleanup; 1307 1308 X509_STORE_CTX_set0_crls(&cert_ctx, revoked); 1309 1310 /* add trusted CAs certificates for cert verification */ 1311 if (idctx->trustedCAs != NULL) 1312 X509_STORE_CTX_trusted_stack(&cert_ctx, idctx->trustedCAs); 1313 else { 1314 pkiDebug("unable to find any trusted CAs\n"); 1315 goto cleanup; 1316 } 1317 #ifdef DEBUG_CERTCHAIN 1318 if (intermediateCAs != NULL) { 1319 size = sk_X509_num(intermediateCAs); 1320 pkiDebug("untrusted cert chain of size %d\n", size); 1321 for (i = 0; i < size; i++) { 1322 X509_NAME_oneline(X509_get_subject_name( 1323 sk_X509_value(intermediateCAs, i)), buf, sizeof(buf)); 1324 pkiDebug("cert #%d: %s\n", i, buf); 1325 } 1326 } 1327 if (idctx->trustedCAs != NULL) { 1328 size = sk_X509_num(idctx->trustedCAs); 1329 pkiDebug("trusted cert chain of size %d\n", size); 1330 for (i = 0; i < size; i++) { 1331 X509_NAME_oneline(X509_get_subject_name( 1332 sk_X509_value(idctx->trustedCAs, i)), buf, sizeof(buf)); 1333 pkiDebug("cert #%d: %s\n", i, buf); 1334 } 1335 } 1336 if (revoked != NULL) { 1337 size = sk_X509_CRL_num(revoked); 1338 pkiDebug("CRL chain of size %d\n", size); 1339 for (i = 0; i < size; i++) { 1340 X509_CRL *crl = sk_X509_CRL_value(revoked, i); 1341 X509_NAME_oneline(X509_CRL_get_issuer(crl), buf, sizeof(buf)); 1342 pkiDebug("crls by CA #%d: %s\n", i , buf); 1343 } 1344 } 1345 #endif 1346 1347 i = X509_verify_cert(&cert_ctx); 1348 if (i <= 0) { 1349 int j = X509_STORE_CTX_get_error(&cert_ctx); 1350 1351 reqctx->received_cert = X509_dup(cert_ctx.current_cert); 1352 switch(j) { 1353 case X509_V_ERR_CERT_REVOKED: 1354 retval = KRB5KDC_ERR_REVOKED_CERTIFICATE; 1355 break; 1356 case X509_V_ERR_UNABLE_TO_GET_CRL: 1357 retval = KRB5KDC_ERR_REVOCATION_STATUS_UNKNOWN; 1358 break; 1359 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: 1360 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: 1361 retval = KRB5KDC_ERR_CANT_VERIFY_CERTIFICATE; 1362 break; 1363 default: 1364 retval = KRB5KDC_ERR_INVALID_CERTIFICATE; 1365 } 1366 X509_NAME_oneline(X509_get_subject_name( 1367 reqctx->received_cert), buf, sizeof(buf)); 1368 pkiDebug("problem with cert DN = %s (error=%d) %s\n", buf, j, 1369 X509_verify_cert_error_string(j)); 1370 krb5_set_error_message(context, retval, "%s\n", 1371 X509_verify_cert_error_string(j)); 1372 #ifdef DEBUG_CERTCHAIN 1373 size = sk_X509_num(p7->d.sign->cert); 1374 pkiDebug("received cert chain of size %d\n", size); 1375 for (j = 0; j < size; j++) { 1376 X509 *tmp_cert = sk_X509_value(p7->d.sign->cert, j); 1377 X509_NAME_oneline(X509_get_subject_name(tmp_cert), buf, sizeof(buf)); 1378 pkiDebug("cert #%d: %s\n", j, buf); 1379 } 1380 #endif 1381 } else { 1382 /* retrieve verified certificate chain */ 1383 if (cms_msg_type == CMS_SIGN_CLIENT || cms_msg_type == CMS_SIGN_DRAFT9) 1384 verified_chain = X509_STORE_CTX_get1_chain(&cert_ctx); 1385 } 1386 X509_STORE_CTX_cleanup(&cert_ctx); 1387 if (i <= 0) 1388 goto cleanup; 1389 1390 out = BIO_new(BIO_s_mem()); 1391 if (cms_msg_type == CMS_SIGN_DRAFT9) 1392 flags |= PKCS7_NOATTR; 1393 if (PKCS7_verify(p7, NULL, store, NULL, out, flags)) { 1394 int valid_oid = 0; 1395 1396 if (!OBJ_cmp(p7->d.sign->contents->type, oid)) 1397 valid_oid = 1; 1398 else if (cms_msg_type == CMS_SIGN_DRAFT9) { 1399 /* 1400 * Various implementations of the pa-type 15 request use 1401 * different OIDS. We check that the returned object 1402 * has any of the acceptable OIDs 1403 */ 1404 ASN1_OBJECT *client_oid = NULL, *server_oid = NULL, *rsa_oid = NULL; 1405 client_oid = pkinit_pkcs7type2oid(plgctx, CMS_SIGN_CLIENT); 1406 server_oid = pkinit_pkcs7type2oid(plgctx, CMS_SIGN_SERVER); 1407 rsa_oid = pkinit_pkcs7type2oid(plgctx, CMS_ENVEL_SERVER); 1408 if (!OBJ_cmp(p7->d.sign->contents->type, client_oid) || 1409 !OBJ_cmp(p7->d.sign->contents->type, server_oid) || 1410 !OBJ_cmp(p7->d.sign->contents->type, rsa_oid)) 1411 valid_oid = 1; 1412 } 1413 1414 if (valid_oid) 1415 pkiDebug("PKCS7 Verification successful\n"); 1416 else { 1417 pkiDebug("wrong oid in eContentType\n"); 1418 print_buffer(p7->d.sign->contents->type->data, 1419 (unsigned int)p7->d.sign->contents->type->length); 1420 retval = KRB5KDC_ERR_PREAUTH_FAILED; 1421 krb5_set_error_message(context, retval, "wrong oid\n"); 1422 goto cleanup; 1423 } 1424 } 1425 else { 1426 unsigned long err = ERR_peek_error(); 1427 switch(ERR_GET_REASON(err)) { 1428 case PKCS7_R_DIGEST_FAILURE: 1429 retval = KRB5KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED; 1430 break; 1431 case PKCS7_R_SIGNATURE_FAILURE: 1432 default: 1433 retval = KRB5KDC_ERR_INVALID_SIG; 1434 } 1435 pkiDebug("PKCS7 Verification failure\n"); 1436 krb5_set_error_message(context, retval, "%s\n", 1437 ERR_error_string(err, NULL)); 1438 goto cleanup; 1439 } 1440 1441 /* transfer the data from PKCS7 message into return buffer */ 1442 for (size = 0;;) { 1443 if ((*data = realloc(*data, size + 1024 * 10)) == NULL) 1444 goto cleanup; 1445 i = BIO_read(out, &((*data)[size]), 1024 * 10); 1446 if (i <= 0) 1447 break; 1448 else 1449 size += i; 1450 } 1451 *data_len = size; 1452 1453 reqctx->received_cert = X509_dup(x); 1454 1455 /* generate authorization data */ 1456 if (cms_msg_type == CMS_SIGN_CLIENT || cms_msg_type == CMS_SIGN_DRAFT9) { 1457 1458 if (authz_data == NULL || authz_data_len == NULL) 1459 goto out; 1460 1461 *authz_data = NULL; 1462 retval = create_identifiers_from_stack(verified_chain, 1463 &krb5_verified_chain); 1464 if (retval) { 1465 pkiDebug("create_identifiers_from_stack failed\n"); 1466 goto cleanup; 1467 } 1468 1469 retval = k5int_encode_krb5_td_trusted_certifiers((const krb5_external_principal_identifier **)krb5_verified_chain, &authz); 1470 if (retval) { 1471 pkiDebug("encode_krb5_td_trusted_certifiers failed\n"); 1472 goto cleanup; 1473 } 1474 #ifdef DEBUG_ASN1 1475 print_buffer_bin((unsigned char *)authz->data, authz->length, 1476 "/tmp/kdc_ad_initial_verified_cas"); 1477 #endif 1478 *authz_data = (unsigned char *)malloc(authz->length); 1479 if (*authz_data == NULL) { 1480 retval = ENOMEM; 1481 goto cleanup; 1482 } 1483 (void) memcpy(*authz_data, authz->data, authz->length); 1484 *authz_data_len = authz->length; 1485 } 1486 out: 1487 retval = 0; 1488 1489 cleanup: 1490 if (out != NULL) 1491 BIO_free(out); 1492 if (store != NULL) 1493 X509_STORE_free(store); 1494 if (p7 != NULL) { 1495 if (idctx->intermediateCAs != NULL && p7->d.sign->cert) 1496 sk_X509_free(intermediateCAs); 1497 if (idctx->revoked != NULL && p7->d.sign->crl) 1498 sk_X509_CRL_free(revoked); 1499 PKCS7_free(p7); 1500 } 1501 if (verified_chain != NULL) 1502 sk_X509_pop_free(verified_chain, X509_free); 1503 if (krb5_verified_chain != NULL) 1504 free_krb5_external_principal_identifier(&krb5_verified_chain); 1505 if (authz != NULL) 1506 krb5_free_data(context, authz); 1507 1508 return retval; 1509 } 1510 1511 krb5_error_code 1512 cms_envelopeddata_create(krb5_context context, 1513 pkinit_plg_crypto_context plgctx, 1514 pkinit_req_crypto_context reqctx, 1515 pkinit_identity_crypto_context idctx, 1516 krb5_preauthtype pa_type, 1517 int include_certchain, 1518 unsigned char *key_pack, 1519 unsigned int key_pack_len, 1520 unsigned char **out, 1521 unsigned int *out_len) 1522 { 1523 1524 /* Solaris Kerberos */ 1525 krb5_error_code retval = KRB5KRB_ERR_GENERIC; 1526 PKCS7 *p7 = NULL; 1527 BIO *in = NULL; 1528 unsigned char *p = NULL, *signed_data = NULL, *enc_data = NULL; 1529 int signed_data_len = 0, enc_data_len = 0, flags = PKCS7_BINARY; 1530 STACK_OF(X509) *encerts = NULL; 1531 const EVP_CIPHER *cipher = NULL; 1532 int cms_msg_type; 1533 1534 /* create the PKCS7 SignedData portion of the PKCS7 EnvelopedData */ 1535 switch ((int)pa_type) { 1536 case KRB5_PADATA_PK_AS_REQ_OLD: 1537 case KRB5_PADATA_PK_AS_REP_OLD: 1538 cms_msg_type = CMS_SIGN_DRAFT9; 1539 break; 1540 case KRB5_PADATA_PK_AS_REQ: 1541 cms_msg_type = CMS_ENVEL_SERVER; 1542 break; 1543 default: 1544 /* Solaris Kerberos */ 1545 retval = EINVAL; 1546 goto cleanup; 1547 } 1548 1549 retval = cms_signeddata_create(context, plgctx, reqctx, idctx, 1550 cms_msg_type, include_certchain, key_pack, key_pack_len, 1551 &signed_data, (unsigned int *)&signed_data_len); 1552 if (retval) { 1553 pkiDebug("failed to create pkcs7 signed data\n"); 1554 goto cleanup; 1555 } 1556 1557 /* check we have client's certificate */ 1558 if (reqctx->received_cert == NULL) { 1559 retval = KRB5KDC_ERR_PREAUTH_FAILED; 1560 goto cleanup; 1561 } 1562 encerts = sk_X509_new_null(); 1563 sk_X509_push(encerts, reqctx->received_cert); 1564 1565 cipher = EVP_des_ede3_cbc(); 1566 in = BIO_new(BIO_s_mem()); 1567 switch (pa_type) { 1568 case KRB5_PADATA_PK_AS_REQ: 1569 prepare_enc_data(signed_data, signed_data_len, &enc_data, 1570 &enc_data_len); 1571 retval = BIO_write(in, enc_data, enc_data_len); 1572 if (retval != enc_data_len) { 1573 pkiDebug("BIO_write only wrote %d\n", retval); 1574 goto cleanup; 1575 } 1576 break; 1577 case KRB5_PADATA_PK_AS_REP_OLD: 1578 case KRB5_PADATA_PK_AS_REQ_OLD: 1579 retval = BIO_write(in, signed_data, signed_data_len); 1580 if (retval != signed_data_len) { 1581 pkiDebug("BIO_write only wrote %d\n", retval); 1582 /* Solaris Kerberos */ 1583 retval = KRB5KRB_ERR_GENERIC; 1584 goto cleanup; 1585 } 1586 break; 1587 default: 1588 retval = -1; 1589 goto cleanup; 1590 } 1591 1592 p7 = PKCS7_encrypt(encerts, in, cipher, flags); 1593 if (p7 == NULL) { 1594 pkiDebug("failed to encrypt PKCS7 object\n"); 1595 retval = -1; 1596 goto cleanup; 1597 } 1598 switch (pa_type) { 1599 case KRB5_PADATA_PK_AS_REQ: 1600 p7->d.enveloped->enc_data->content_type = 1601 OBJ_nid2obj(NID_pkcs7_signed); 1602 break; 1603 case KRB5_PADATA_PK_AS_REP_OLD: 1604 case KRB5_PADATA_PK_AS_REQ_OLD: 1605 p7->d.enveloped->enc_data->content_type = 1606 OBJ_nid2obj(NID_pkcs7_data); 1607 break; 1608 } 1609 1610 *out_len = i2d_PKCS7(p7, NULL); 1611 if (!*out_len || (p = *out = (unsigned char *)malloc(*out_len)) == NULL) { 1612 retval = ENOMEM; 1613 goto cleanup; 1614 } 1615 retval = i2d_PKCS7(p7, &p); 1616 if (!retval) { 1617 pkiDebug("unable to write pkcs7 object\n"); 1618 goto cleanup; 1619 } 1620 retval = 0; 1621 1622 #ifdef DEBUG_ASN1 1623 print_buffer_bin(*out, *out_len, "/tmp/kdc_enveloped_data"); 1624 #endif 1625 1626 cleanup: 1627 if (p7 != NULL) 1628 PKCS7_free(p7); 1629 if (in != NULL) 1630 BIO_free(in); 1631 if (signed_data != NULL) 1632 free(signed_data); 1633 if (enc_data != NULL) 1634 free(enc_data); 1635 if (encerts != NULL) 1636 sk_X509_free(encerts); 1637 1638 return retval; 1639 } 1640 1641 krb5_error_code 1642 cms_envelopeddata_verify(krb5_context context, 1643 pkinit_plg_crypto_context plg_cryptoctx, 1644 pkinit_req_crypto_context req_cryptoctx, 1645 pkinit_identity_crypto_context id_cryptoctx, 1646 krb5_preauthtype pa_type, 1647 int require_crl_checking, 1648 unsigned char *enveloped_data, 1649 unsigned int enveloped_data_len, 1650 unsigned char **data, 1651 unsigned int *data_len) 1652 { 1653 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED; 1654 PKCS7 *p7 = NULL; 1655 BIO *out = NULL; 1656 int i = 0; 1657 unsigned int size = 0; 1658 const unsigned char *p = enveloped_data; 1659 unsigned int tmp_buf_len = 0, tmp_buf2_len = 0, vfy_buf_len = 0; 1660 unsigned char *tmp_buf = NULL, *tmp_buf2 = NULL, *vfy_buf = NULL; 1661 int msg_type = 0; 1662 1663 #ifdef DEBUG_ASN1 1664 print_buffer_bin(enveloped_data, enveloped_data_len, 1665 "/tmp/client_envelopeddata"); 1666 #endif 1667 /* decode received PKCS7 message */ 1668 if ((p7 = d2i_PKCS7(NULL, &p, (int)enveloped_data_len)) == NULL) { 1669 unsigned long err = ERR_peek_error(); 1670 pkiDebug("failed to decode pkcs7\n"); 1671 krb5_set_error_message(context, retval, "%s\n", 1672 ERR_error_string(err, NULL)); 1673 goto cleanup; 1674 } 1675 1676 /* verify that the received message is PKCS7 EnvelopedData message */ 1677 if (OBJ_obj2nid(p7->type) != NID_pkcs7_enveloped) { 1678 pkiDebug("Expected id-enveloped PKCS7 msg (received type = %d)\n", 1679 OBJ_obj2nid(p7->type)); 1680 krb5_set_error_message(context, retval, "wrong oid\n"); 1681 goto cleanup; 1682 } 1683 1684 /* decrypt received PKCS7 message */ 1685 out = BIO_new(BIO_s_mem()); 1686 if (pkcs7_decrypt(context, id_cryptoctx, p7, out)) { 1687 pkiDebug("PKCS7 decryption successful\n"); 1688 } else { 1689 unsigned long err = ERR_peek_error(); 1690 if (err != 0) 1691 krb5_set_error_message(context, retval, "%s\n", 1692 ERR_error_string(err, NULL)); 1693 pkiDebug("PKCS7 decryption failed\n"); 1694 goto cleanup; 1695 } 1696 1697 /* transfer the decoded PKCS7 SignedData message into a separate buffer */ 1698 for (;;) { 1699 if ((tmp_buf = realloc(tmp_buf, size + 1024 * 10)) == NULL) 1700 goto cleanup; 1701 i = BIO_read(out, &(tmp_buf[size]), 1024 * 10); 1702 if (i <= 0) 1703 break; 1704 else 1705 size += i; 1706 } 1707 tmp_buf_len = size; 1708 1709 #ifdef DEBUG_ASN1 1710 print_buffer_bin(tmp_buf, tmp_buf_len, "/tmp/client_enc_keypack"); 1711 #endif 1712 /* verify PKCS7 SignedData message */ 1713 switch (pa_type) { 1714 case KRB5_PADATA_PK_AS_REP: 1715 msg_type = CMS_ENVEL_SERVER; 1716 1717 break; 1718 case KRB5_PADATA_PK_AS_REP_OLD: 1719 msg_type = CMS_SIGN_DRAFT9; 1720 break; 1721 default: 1722 pkiDebug("%s: unrecognized pa_type = %d\n", __FUNCTION__, pa_type); 1723 retval = KRB5KDC_ERR_PREAUTH_FAILED; 1724 goto cleanup; 1725 } 1726 /* 1727 * If this is the RFC style, wrap the signed data to make 1728 * decoding easier in the verify routine. 1729 * For draft9-compatible, we don't do anything because it 1730 * is already wrapped. 1731 */ 1732 #ifdef LONGHORN_BETA_COMPAT 1733 /* 1734 * The Longhorn server returns the expected RFC-style data, but 1735 * it is missing the sequence tag and length, so it requires 1736 * special processing when wrapping. 1737 * This will hopefully be fixed before the final release and 1738 * this can all be removed. 1739 */ 1740 if (msg_type == CMS_ENVEL_SERVER || longhorn == 1) { 1741 retval = wrap_signeddata(tmp_buf, tmp_buf_len, 1742 &tmp_buf2, &tmp_buf2_len, longhorn); 1743 if (retval) { 1744 pkiDebug("failed to encode signeddata\n"); 1745 goto cleanup; 1746 } 1747 vfy_buf = tmp_buf2; 1748 vfy_buf_len = tmp_buf2_len; 1749 1750 } else { 1751 vfy_buf = tmp_buf; 1752 vfy_buf_len = tmp_buf_len; 1753 } 1754 #else 1755 if (msg_type == CMS_ENVEL_SERVER) { 1756 retval = wrap_signeddata(tmp_buf, tmp_buf_len, 1757 &tmp_buf2, &tmp_buf2_len); 1758 if (retval) { 1759 pkiDebug("failed to encode signeddata\n"); 1760 goto cleanup; 1761 } 1762 vfy_buf = tmp_buf2; 1763 vfy_buf_len = tmp_buf2_len; 1764 1765 } else { 1766 vfy_buf = tmp_buf; 1767 vfy_buf_len = tmp_buf_len; 1768 } 1769 #endif 1770 1771 #ifdef DEBUG_ASN1 1772 print_buffer_bin(vfy_buf, vfy_buf_len, "/tmp/client_enc_keypack2"); 1773 #endif 1774 1775 retval = cms_signeddata_verify(context, plg_cryptoctx, req_cryptoctx, 1776 id_cryptoctx, msg_type, 1777 require_crl_checking, 1778 vfy_buf, vfy_buf_len, 1779 data, data_len, NULL, NULL); 1780 1781 if (!retval) 1782 pkiDebug("PKCS7 Verification Success\n"); 1783 else { 1784 pkiDebug("PKCS7 Verification Failure\n"); 1785 goto cleanup; 1786 } 1787 1788 retval = 0; 1789 1790 cleanup: 1791 1792 if (p7 != NULL) 1793 PKCS7_free(p7); 1794 if (out != NULL) 1795 BIO_free(out); 1796 if (tmp_buf != NULL) 1797 free(tmp_buf); 1798 if (tmp_buf2 != NULL) 1799 free(tmp_buf2); 1800 1801 return retval; 1802 } 1803 1804 /* ARGSUSED */ 1805 static krb5_error_code 1806 crypto_retrieve_X509_sans(krb5_context context, 1807 pkinit_plg_crypto_context plgctx, 1808 pkinit_req_crypto_context reqctx, 1809 X509 *cert, 1810 krb5_principal **princs_ret, 1811 krb5_principal **upn_ret, 1812 unsigned char ***dns_ret) 1813 { 1814 krb5_error_code retval = EINVAL; 1815 char buf[DN_BUF_LEN]; 1816 int p = 0, u = 0, d = 0; 1817 krb5_principal *princs = NULL; 1818 krb5_principal *upns = NULL; 1819 unsigned char **dnss = NULL; 1820 int i, num_found = 0; 1821 1822 if (princs_ret == NULL && upn_ret == NULL && dns_ret == NULL) { 1823 pkiDebug("%s: nowhere to return any values!\n", __FUNCTION__); 1824 return retval; 1825 } 1826 1827 if (cert == NULL) { 1828 pkiDebug("%s: no certificate!\n", __FUNCTION__); 1829 return retval; 1830 } 1831 1832 X509_NAME_oneline(X509_get_subject_name(cert), 1833 buf, sizeof(buf)); 1834 pkiDebug("%s: looking for SANs in cert = %s\n", __FUNCTION__, buf); 1835 1836 if ((i = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1)) >= 0) { 1837 X509_EXTENSION *ext = NULL; 1838 GENERAL_NAMES *ialt = NULL; 1839 GENERAL_NAME *gen = NULL; 1840 int ret = 0; 1841 unsigned int num_sans = 0; 1842 1843 if (!(ext = X509_get_ext(cert, i)) || !(ialt = X509V3_EXT_d2i(ext))) { 1844 pkiDebug("%s: found no subject alt name extensions\n", 1845 __FUNCTION__); 1846 goto cleanup; 1847 } 1848 num_sans = sk_GENERAL_NAME_num(ialt); 1849 1850 pkiDebug("%s: found %d subject alt name extension(s)\n", 1851 __FUNCTION__, num_sans); 1852 1853 /* OK, we're likely returning something. Allocate return values */ 1854 if (princs_ret != NULL) { 1855 princs = calloc(num_sans + 1, sizeof(krb5_principal)); 1856 if (princs == NULL) { 1857 retval = ENOMEM; 1858 goto cleanup; 1859 } 1860 } 1861 if (upn_ret != NULL) { 1862 upns = calloc(num_sans + 1, sizeof(krb5_principal)); 1863 if (upns == NULL) { 1864 retval = ENOMEM; 1865 goto cleanup; 1866 } 1867 } 1868 if (dns_ret != NULL) { 1869 dnss = calloc(num_sans + 1, sizeof(*dnss)); 1870 if (dnss == NULL) { 1871 retval = ENOMEM; 1872 goto cleanup; 1873 } 1874 } 1875 1876 for (i = 0; i < num_sans; i++) { 1877 krb5_data name = { 0, 0, NULL }; 1878 1879 gen = sk_GENERAL_NAME_value(ialt, i); 1880 switch (gen->type) { 1881 case GEN_OTHERNAME: 1882 name.length = gen->d.otherName->value->value.sequence->length; 1883 name.data = (char *)gen->d.otherName->value->value.sequence->data; 1884 if (princs != NULL 1885 && OBJ_cmp(plgctx->id_pkinit_san, 1886 gen->d.otherName->type_id) == 0) { 1887 #ifdef DEBUG_ASN1 1888 print_buffer_bin((unsigned char *)name.data, name.length, 1889 "/tmp/pkinit_san"); 1890 #endif 1891 ret = k5int_decode_krb5_principal_name(&name, &princs[p]); 1892 if (ret) { 1893 pkiDebug("%s: failed decoding pkinit san value\n", 1894 __FUNCTION__); 1895 } else { 1896 p++; 1897 num_found++; 1898 } 1899 } else if (upns != NULL 1900 && OBJ_cmp(plgctx->id_ms_san_upn, 1901 gen->d.otherName->type_id) == 0) { 1902 ret = krb5_parse_name(context, name.data, &upns[u]); 1903 if (ret) { 1904 pkiDebug("%s: failed parsing ms-upn san value\n", 1905 __FUNCTION__); 1906 } else { 1907 u++; 1908 num_found++; 1909 } 1910 } else { 1911 pkiDebug("%s: unrecognized othername oid in SAN\n", 1912 __FUNCTION__); 1913 continue; 1914 } 1915 1916 break; 1917 case GEN_DNS: 1918 if (dnss != NULL) { 1919 pkiDebug("%s: found dns name = %s\n", 1920 __FUNCTION__, gen->d.dNSName->data); 1921 dnss[d] = (unsigned char *) 1922 strdup((char *)gen->d.dNSName->data); 1923 if (dnss[d] == NULL) { 1924 pkiDebug("%s: failed to duplicate dns name\n", 1925 __FUNCTION__); 1926 } else { 1927 d++; 1928 num_found++; 1929 } 1930 } 1931 break; 1932 default: 1933 pkiDebug("%s: SAN type = %d expecting %d\n", 1934 __FUNCTION__, gen->type, GEN_OTHERNAME); 1935 } 1936 } 1937 sk_GENERAL_NAME_pop_free(ialt, GENERAL_NAME_free); 1938 } 1939 1940 retval = 0; 1941 if (princs) 1942 *princs_ret = princs; 1943 if (upns) 1944 *upn_ret = upns; 1945 if (dnss) 1946 *dns_ret = dnss; 1947 1948 cleanup: 1949 if (retval) { 1950 if (princs != NULL) { 1951 for (i = 0; princs[i] != NULL; i++) 1952 krb5_free_principal(context, princs[i]); 1953 free(princs); 1954 } 1955 if (upns != NULL) { 1956 for (i = 0; upns[i] != NULL; i++) 1957 krb5_free_principal(context, upns[i]); 1958 free(upns); 1959 } 1960 if (dnss != NULL) { 1961 for (i = 0; dnss[i] != NULL; i++) 1962 free(dnss[i]); 1963 free(dnss); 1964 } 1965 } 1966 return retval; 1967 } 1968 1969 /* ARGSUSED */ 1970 krb5_error_code 1971 crypto_retrieve_cert_sans(krb5_context context, 1972 pkinit_plg_crypto_context plgctx, 1973 pkinit_req_crypto_context reqctx, 1974 pkinit_identity_crypto_context idctx, 1975 krb5_principal **princs_ret, 1976 krb5_principal **upn_ret, 1977 unsigned char ***dns_ret) 1978 { 1979 krb5_error_code retval = EINVAL; 1980 1981 if (reqctx->received_cert == NULL) { 1982 pkiDebug("%s: No certificate!\n", __FUNCTION__); 1983 return retval; 1984 } 1985 1986 return crypto_retrieve_X509_sans(context, plgctx, reqctx, 1987 reqctx->received_cert, princs_ret, 1988 upn_ret, dns_ret); 1989 } 1990 1991 /* ARGSUSED */ 1992 krb5_error_code 1993 crypto_check_cert_eku(krb5_context context, 1994 pkinit_plg_crypto_context plgctx, 1995 pkinit_req_crypto_context reqctx, 1996 pkinit_identity_crypto_context idctx, 1997 int checking_kdc_cert, 1998 int allow_secondary_usage, 1999 int *valid_eku) 2000 { 2001 char buf[DN_BUF_LEN]; 2002 int found_eku = 0; 2003 krb5_error_code retval = EINVAL; 2004 int i; 2005 2006 /* Solaris Kerberos */ 2007 if (valid_eku == NULL) 2008 return retval; 2009 2010 *valid_eku = 0; 2011 if (reqctx->received_cert == NULL) 2012 goto cleanup; 2013 2014 X509_NAME_oneline(X509_get_subject_name(reqctx->received_cert), 2015 buf, sizeof(buf)); 2016 pkiDebug("%s: looking for EKUs in cert = %s\n", __FUNCTION__, buf); 2017 2018 if ((i = X509_get_ext_by_NID(reqctx->received_cert, 2019 NID_ext_key_usage, -1)) >= 0) { 2020 EXTENDED_KEY_USAGE *extusage; 2021 2022 extusage = X509_get_ext_d2i(reqctx->received_cert, NID_ext_key_usage, 2023 NULL, NULL); 2024 if (extusage) { 2025 pkiDebug("%s: found eku info in the cert\n", __FUNCTION__); 2026 for (i = 0; found_eku == 0 && i < sk_ASN1_OBJECT_num(extusage); i++) { 2027 ASN1_OBJECT *tmp_oid; 2028 2029 tmp_oid = sk_ASN1_OBJECT_value(extusage, i); 2030 pkiDebug("%s: checking eku %d of %d, allow_secondary = %d\n", 2031 __FUNCTION__, i+1, sk_ASN1_OBJECT_num(extusage), 2032 allow_secondary_usage); 2033 if (checking_kdc_cert) { 2034 if ((OBJ_cmp(tmp_oid, plgctx->id_pkinit_KPKdc) == 0) 2035 || (allow_secondary_usage 2036 && OBJ_cmp(tmp_oid, plgctx->id_kp_serverAuth) == 0)) 2037 found_eku = 1; 2038 } else { 2039 if ((OBJ_cmp(tmp_oid, plgctx->id_pkinit_KPClientAuth) == 0) 2040 || (allow_secondary_usage 2041 && OBJ_cmp(tmp_oid, plgctx->id_ms_kp_sc_logon) == 0)) 2042 found_eku = 1; 2043 } 2044 } 2045 } 2046 EXTENDED_KEY_USAGE_free(extusage); 2047 2048 if (found_eku) { 2049 ASN1_BIT_STRING *usage = NULL; 2050 pkiDebug("%s: found acceptable EKU, checking for digitalSignature\n", __FUNCTION__); 2051 2052 /* check that digitalSignature KeyUsage is present */ 2053 if ((usage = X509_get_ext_d2i(reqctx->received_cert, 2054 NID_key_usage, NULL, NULL))) { 2055 2056 if (!ku_reject(reqctx->received_cert, 2057 X509v3_KU_DIGITAL_SIGNATURE)) { 2058 pkiDebug("%s: found digitalSignature KU\n", 2059 __FUNCTION__); 2060 *valid_eku = 1; 2061 } else 2062 pkiDebug("%s: didn't find digitalSignature KU\n", 2063 __FUNCTION__); 2064 } 2065 ASN1_BIT_STRING_free(usage); 2066 } 2067 } 2068 retval = 0; 2069 cleanup: 2070 pkiDebug("%s: returning retval %d, valid_eku %d\n", 2071 __FUNCTION__, retval, *valid_eku); 2072 return retval; 2073 } 2074 2075 krb5_error_code 2076 pkinit_octetstring2key(krb5_context context, 2077 krb5_enctype etype, 2078 unsigned char *key, 2079 unsigned int dh_key_len, 2080 krb5_keyblock * key_block) 2081 { 2082 krb5_error_code retval; 2083 unsigned char *buf = NULL; 2084 unsigned char md[SHA_DIGEST_LENGTH]; 2085 unsigned char counter; 2086 size_t keybytes, keylength, offset; 2087 krb5_data random_data; 2088 2089 2090 if ((buf = (unsigned char *) malloc(dh_key_len)) == NULL) { 2091 retval = ENOMEM; 2092 goto cleanup; 2093 } 2094 (void) memset(buf, 0, dh_key_len); 2095 2096 counter = 0; 2097 offset = 0; 2098 do { 2099 SHA_CTX c; 2100 2101 SHA1_Init(&c); 2102 SHA1_Update(&c, &counter, 1); 2103 SHA1_Update(&c, key, dh_key_len); 2104 SHA1_Final(md, &c); 2105 2106 if (dh_key_len - offset < sizeof(md)) 2107 (void) memcpy(buf + offset, md, dh_key_len - offset); 2108 else 2109 (void) memcpy(buf + offset, md, sizeof(md)); 2110 2111 offset += sizeof(md); 2112 counter++; 2113 } while (offset < dh_key_len); 2114 2115 /* Solaris Kerberos */ 2116 key_block->magic = KV5M_KEYBLOCK; 2117 key_block->enctype = etype; 2118 2119 retval = krb5_c_keylengths(context, etype, &keybytes, &keylength); 2120 if (retval) 2121 goto cleanup; 2122 2123 key_block->length = keylength; 2124 key_block->contents = calloc(keylength, sizeof(unsigned char *)); 2125 if (key_block->contents == NULL) { 2126 retval = ENOMEM; 2127 goto cleanup; 2128 } 2129 2130 random_data.length = keybytes; 2131 random_data.data = (char *)buf; 2132 2133 retval = krb5_c_random_to_key(context, etype, &random_data, key_block); 2134 2135 cleanup: 2136 if (buf != NULL) 2137 free(buf); 2138 if (retval && key_block->contents != NULL && key_block->length != 0) { 2139 (void) memset(key_block->contents, 0, key_block->length); 2140 key_block->length = 0; 2141 } 2142 2143 return retval; 2144 } 2145 2146 /* ARGSUSED */ 2147 krb5_error_code 2148 client_create_dh(krb5_context context, 2149 pkinit_plg_crypto_context plg_cryptoctx, 2150 pkinit_req_crypto_context cryptoctx, 2151 pkinit_identity_crypto_context id_cryptoctx, 2152 int dh_size, 2153 unsigned char **dh_params, 2154 unsigned int *dh_params_len, 2155 unsigned char **dh_pubkey, 2156 unsigned int *dh_pubkey_len) 2157 { 2158 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED; 2159 unsigned char *buf = NULL; 2160 int dh_err = 0; 2161 ASN1_INTEGER *pub_key = NULL; 2162 2163 if (cryptoctx->dh == NULL) { 2164 if ((cryptoctx->dh = DH_new()) == NULL) 2165 goto cleanup; 2166 if ((cryptoctx->dh->g = BN_new()) == NULL || 2167 (cryptoctx->dh->q = BN_new()) == NULL) 2168 goto cleanup; 2169 2170 switch(dh_size) { 2171 case 1024: 2172 pkiDebug("client uses 1024 DH keys\n"); 2173 cryptoctx->dh->p = get_rfc2409_prime_1024(NULL); 2174 break; 2175 case 2048: 2176 pkiDebug("client uses 2048 DH keys\n"); 2177 cryptoctx->dh->p = BN_bin2bn(pkinit_2048_dhprime, 2178 sizeof(pkinit_2048_dhprime), NULL); 2179 break; 2180 case 4096: 2181 pkiDebug("client uses 4096 DH keys\n"); 2182 cryptoctx->dh->p = BN_bin2bn(pkinit_4096_dhprime, 2183 sizeof(pkinit_4096_dhprime), NULL); 2184 break; 2185 default: 2186 goto cleanup; 2187 } 2188 2189 BN_set_word((cryptoctx->dh->g), DH_GENERATOR_2); 2190 BN_rshift1(cryptoctx->dh->q, cryptoctx->dh->p); 2191 } 2192 2193 DH_generate_key(cryptoctx->dh); 2194 /* Solaris Kerberos */ 2195 #ifdef DEBUG 2196 DH_check(cryptoctx->dh, &dh_err); 2197 if (dh_err != 0) { 2198 pkiDebug("Warning: dh_check failed with %d\n", dh_err); 2199 if (dh_err & DH_CHECK_P_NOT_PRIME) 2200 pkiDebug("p value is not prime\n"); 2201 if (dh_err & DH_CHECK_P_NOT_SAFE_PRIME) 2202 pkiDebug("p value is not a safe prime\n"); 2203 if (dh_err & DH_UNABLE_TO_CHECK_GENERATOR) 2204 pkiDebug("unable to check the generator value\n"); 2205 if (dh_err & DH_NOT_SUITABLE_GENERATOR) 2206 pkiDebug("the g value is not a generator\n"); 2207 } 2208 #endif 2209 #ifdef DEBUG_DH 2210 print_dh(cryptoctx->dh, "client's DH params\n"); 2211 print_pubkey(cryptoctx->dh->pub_key, "client's pub_key="); 2212 #endif 2213 2214 DH_check_pub_key(cryptoctx->dh, cryptoctx->dh->pub_key, &dh_err); 2215 if (dh_err != 0) { 2216 pkiDebug("dh_check_pub_key failed with %d\n", dh_err); 2217 goto cleanup; 2218 } 2219 2220 /* pack DHparams */ 2221 /* aglo: usually we could just call i2d_DHparams to encode DH params 2222 * however, PKINIT requires RFC3279 encoding and openssl does pkcs#3. 2223 */ 2224 retval = pkinit_encode_dh_params(cryptoctx->dh->p, cryptoctx->dh->g, 2225 cryptoctx->dh->q, dh_params, dh_params_len); 2226 if (retval) 2227 goto cleanup; 2228 2229 /* pack DH public key */ 2230 /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this 2231 * encoding shall be used as the contents (the value) of the 2232 * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo 2233 * data element 2234 */ 2235 if ((pub_key = BN_to_ASN1_INTEGER(cryptoctx->dh->pub_key, NULL)) == NULL) 2236 goto cleanup; 2237 *dh_pubkey_len = i2d_ASN1_INTEGER(pub_key, NULL); 2238 if ((buf = *dh_pubkey = (unsigned char *) 2239 malloc((size_t) *dh_pubkey_len)) == NULL) { 2240 retval = ENOMEM; 2241 goto cleanup; 2242 } 2243 i2d_ASN1_INTEGER(pub_key, &buf); 2244 2245 if (pub_key != NULL) 2246 ASN1_INTEGER_free(pub_key); 2247 2248 retval = 0; 2249 return retval; 2250 2251 cleanup: 2252 if (cryptoctx->dh != NULL) 2253 DH_free(cryptoctx->dh); 2254 cryptoctx->dh = NULL; 2255 if (*dh_params != NULL) 2256 free(*dh_params); 2257 *dh_params = NULL; 2258 if (*dh_pubkey != NULL) 2259 free(*dh_pubkey); 2260 *dh_pubkey = NULL; 2261 if (pub_key != NULL) 2262 ASN1_INTEGER_free(pub_key); 2263 2264 return retval; 2265 } 2266 2267 /* ARGSUSED */ 2268 krb5_error_code 2269 client_process_dh(krb5_context context, 2270 pkinit_plg_crypto_context plg_cryptoctx, 2271 pkinit_req_crypto_context cryptoctx, 2272 pkinit_identity_crypto_context id_cryptoctx, 2273 unsigned char *subjectPublicKey_data, 2274 unsigned int subjectPublicKey_length, 2275 unsigned char **client_key, 2276 unsigned int *client_key_len) 2277 { 2278 /* Solaris Kerberos */ 2279 krb5_error_code retval = KRB5_PREAUTH_FAILED; 2280 BIGNUM *server_pub_key = NULL; 2281 ASN1_INTEGER *pub_key = NULL; 2282 const unsigned char *p = NULL; 2283 unsigned char *data = NULL; 2284 long data_len; 2285 2286 /* decode subjectPublicKey (retrieve INTEGER from OCTET_STRING) */ 2287 2288 if (der_decode_data(subjectPublicKey_data, (long)subjectPublicKey_length, 2289 &data, &data_len) != 0) { 2290 pkiDebug("failed to decode subjectPublicKey\n"); 2291 /* Solaris Kerberos */ 2292 retval = KRB5_PREAUTH_FAILED; 2293 goto cleanup; 2294 } 2295 2296 *client_key_len = DH_size(cryptoctx->dh); 2297 if ((*client_key = (unsigned char *) 2298 malloc((size_t) *client_key_len)) == NULL) { 2299 retval = ENOMEM; 2300 goto cleanup; 2301 } 2302 p = data; 2303 if ((pub_key = d2i_ASN1_INTEGER(NULL, &p, data_len)) == NULL) 2304 goto cleanup; 2305 if ((server_pub_key = ASN1_INTEGER_to_BN(pub_key, NULL)) == NULL) 2306 goto cleanup; 2307 2308 DH_compute_key(*client_key, server_pub_key, cryptoctx->dh); 2309 #ifdef DEBUG_DH 2310 print_pubkey(server_pub_key, "server's pub_key="); 2311 pkiDebug("client secret key (%d)= ", *client_key_len); 2312 print_buffer(*client_key, *client_key_len); 2313 #endif 2314 2315 retval = 0; 2316 if (server_pub_key != NULL) 2317 BN_free(server_pub_key); 2318 if (pub_key != NULL) 2319 ASN1_INTEGER_free(pub_key); 2320 if (data != NULL) 2321 free (data); 2322 2323 return retval; 2324 2325 cleanup: 2326 if (*client_key != NULL) 2327 free(*client_key); 2328 *client_key = NULL; 2329 if (pub_key != NULL) 2330 ASN1_INTEGER_free(pub_key); 2331 if (data != NULL) 2332 free (data); 2333 2334 return retval; 2335 } 2336 2337 /* ARGSUSED */ 2338 krb5_error_code 2339 server_check_dh(krb5_context context, 2340 pkinit_plg_crypto_context cryptoctx, 2341 pkinit_req_crypto_context req_cryptoctx, 2342 pkinit_identity_crypto_context id_cryptoctx, 2343 krb5_octet_data *dh_params, 2344 int minbits) 2345 { 2346 DH *dh = NULL; 2347 unsigned char *tmp = NULL; 2348 int dh_prime_bits; 2349 krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED; 2350 2351 tmp = dh_params->data; 2352 dh = DH_new(); 2353 dh = pkinit_decode_dh_params(&dh, &tmp, dh_params->length); 2354 if (dh == NULL) { 2355 pkiDebug("failed to decode dhparams\n"); 2356 goto cleanup; 2357 } 2358 2359 /* KDC SHOULD check to see if the key parameters satisfy its policy */ 2360 dh_prime_bits = BN_num_bits(dh->p); 2361 if (minbits && dh_prime_bits < minbits) { 2362 pkiDebug("client sent dh params with %d bits, we require %d\n", 2363 dh_prime_bits, minbits); 2364 goto cleanup; 2365 } 2366 2367 /* check dhparams is group 2 */ 2368 if (pkinit_check_dh_params(cryptoctx->dh_1024->p, 2369 dh->p, dh->g, dh->q) == 0) { 2370 retval = 0; 2371 goto cleanup; 2372 } 2373 2374 /* check dhparams is group 14 */ 2375 if (pkinit_check_dh_params(cryptoctx->dh_2048->p, 2376 dh->p, dh->g, dh->q) == 0) { 2377 retval = 0; 2378 goto cleanup; 2379 } 2380 2381 /* check dhparams is group 16 */ 2382 if (pkinit_check_dh_params(cryptoctx->dh_4096->p, 2383 dh->p, dh->g, dh->q) == 0) { 2384 retval = 0; 2385 goto cleanup; 2386 } 2387 2388 cleanup: 2389 if (retval == 0) 2390 req_cryptoctx->dh = dh; 2391 else 2392 DH_free(dh); 2393 2394 return retval; 2395 } 2396 2397 /* kdc's dh function */ 2398 /* ARGSUSED */ 2399 krb5_error_code 2400 server_process_dh(krb5_context context, 2401 pkinit_plg_crypto_context plg_cryptoctx, 2402 pkinit_req_crypto_context cryptoctx, 2403 pkinit_identity_crypto_context id_cryptoctx, 2404 unsigned char *data, 2405 unsigned int data_len, 2406 unsigned char **dh_pubkey, 2407 unsigned int *dh_pubkey_len, 2408 unsigned char **server_key, 2409 unsigned int *server_key_len) 2410 { 2411 /* Solaris Kerberos */ 2412 krb5_error_code retval = KRB5KRB_ERR_GENERIC; 2413 DH *dh = NULL, *dh_server = NULL; 2414 unsigned char *p = NULL; 2415 ASN1_INTEGER *pub_key = NULL; 2416 2417 /* get client's received DH parameters that we saved in server_check_dh */ 2418 dh = cryptoctx->dh; 2419 2420 dh_server = DH_new(); 2421 if (dh_server == NULL) 2422 goto cleanup; 2423 dh_server->p = BN_dup(dh->p); 2424 dh_server->g = BN_dup(dh->g); 2425 dh_server->q = BN_dup(dh->q); 2426 2427 /* decode client's public key */ 2428 p = data; 2429 pub_key = d2i_ASN1_INTEGER(NULL, (const unsigned char **)&p, (int)data_len); 2430 if (pub_key == NULL) 2431 goto cleanup; 2432 dh->pub_key = ASN1_INTEGER_to_BN(pub_key, NULL); 2433 if (dh->pub_key == NULL) 2434 goto cleanup; 2435 ASN1_INTEGER_free(pub_key); 2436 2437 if (!DH_generate_key(dh_server)) 2438 goto cleanup; 2439 2440 /* generate DH session key */ 2441 *server_key_len = DH_size(dh_server); 2442 if ((*server_key = (unsigned char *) malloc((size_t)*server_key_len)) == NULL) 2443 goto cleanup; 2444 DH_compute_key(*server_key, dh->pub_key, dh_server); 2445 2446 #ifdef DEBUG_DH 2447 print_dh(dh_server, "client&server's DH params\n"); 2448 print_pubkey(dh->pub_key, "client's pub_key="); 2449 print_pubkey(dh_server->pub_key, "server's pub_key="); 2450 pkiDebug("server secret key="); 2451 print_buffer(*server_key, *server_key_len); 2452 #endif 2453 2454 /* KDC reply */ 2455 /* pack DH public key */ 2456 /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this 2457 * encoding shall be used as the contents (the value) of the 2458 * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo 2459 * data element 2460 */ 2461 if ((pub_key = BN_to_ASN1_INTEGER(dh_server->pub_key, NULL)) == NULL) 2462 goto cleanup; 2463 *dh_pubkey_len = i2d_ASN1_INTEGER(pub_key, NULL); 2464 if ((p = *dh_pubkey = (unsigned char *) malloc((size_t)*dh_pubkey_len)) == NULL) 2465 goto cleanup; 2466 i2d_ASN1_INTEGER(pub_key, &p); 2467 if (pub_key != NULL) 2468 ASN1_INTEGER_free(pub_key); 2469 2470 retval = 0; 2471 2472 if (dh_server != NULL) 2473 DH_free(dh_server); 2474 return retval; 2475 2476 cleanup: 2477 if (dh_server != NULL) 2478 DH_free(dh_server); 2479 if (*dh_pubkey != NULL) 2480 free(*dh_pubkey); 2481 if (*server_key != NULL) 2482 free(*server_key); 2483 2484 return retval; 2485 } 2486 2487 /* 2488 * Solaris Kerberos: 2489 * Add locking around did_init to make it MT-safe. 2490 */ 2491 static krb5_error_code 2492 openssl_init() 2493 { 2494 krb5_error_code ret = 0; 2495 static int did_init = 0; 2496 static k5_mutex_t init_mutex = K5_MUTEX_PARTIAL_INITIALIZER; 2497 2498 ret = k5_mutex_lock(&init_mutex); 2499 if (ret == 0) { 2500 if (!did_init) { 2501 /* initialize openssl routines */ 2502 CRYPTO_malloc_init(); 2503 ERR_load_crypto_strings(); 2504 OpenSSL_add_all_algorithms(); 2505 did_init++; 2506 } 2507 k5_mutex_unlock(&init_mutex); 2508 } 2509 return (ret); 2510 } 2511 2512 static krb5_error_code 2513 pkinit_encode_dh_params(BIGNUM *p, BIGNUM *g, BIGNUM *q, 2514 unsigned char **buf, unsigned int *buf_len) 2515 { 2516 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED; 2517 int bufsize = 0, r = 0; 2518 unsigned char *tmp = NULL; 2519 ASN1_INTEGER *ap = NULL, *ag = NULL, *aq = NULL; 2520 2521 if ((ap = BN_to_ASN1_INTEGER(p, NULL)) == NULL) 2522 goto cleanup; 2523 if ((ag = BN_to_ASN1_INTEGER(g, NULL)) == NULL) 2524 goto cleanup; 2525 if ((aq = BN_to_ASN1_INTEGER(q, NULL)) == NULL) 2526 goto cleanup; 2527 bufsize = i2d_ASN1_INTEGER(ap, NULL); 2528 bufsize += i2d_ASN1_INTEGER(ag, NULL); 2529 bufsize += i2d_ASN1_INTEGER(aq, NULL); 2530 2531 r = ASN1_object_size(1, bufsize, V_ASN1_SEQUENCE); 2532 2533 tmp = *buf = (unsigned char *)malloc((size_t) r); 2534 if (tmp == NULL) 2535 goto cleanup; 2536 2537 ASN1_put_object(&tmp, 1, bufsize, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); 2538 2539 i2d_ASN1_INTEGER(ap, &tmp); 2540 i2d_ASN1_INTEGER(ag, &tmp); 2541 i2d_ASN1_INTEGER(aq, &tmp); 2542 2543 *buf_len = r; 2544 2545 retval = 0; 2546 2547 cleanup: 2548 if (ap != NULL) 2549 ASN1_INTEGER_free(ap); 2550 if (ag != NULL) 2551 ASN1_INTEGER_free(ag); 2552 if (aq != NULL) 2553 ASN1_INTEGER_free(aq); 2554 2555 return retval; 2556 } 2557 2558 static DH * 2559 pkinit_decode_dh_params(DH ** a, unsigned char **pp, unsigned int len) 2560 { 2561 ASN1_INTEGER ai, *aip = NULL; 2562 long length = (long) len; 2563 2564 M_ASN1_D2I_vars(a, DH *, DH_new); 2565 2566 M_ASN1_D2I_Init(); 2567 M_ASN1_D2I_start_sequence(); 2568 aip = &ai; 2569 ai.data = NULL; 2570 ai.length = 0; 2571 M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER); 2572 if (aip == NULL) 2573 return NULL; 2574 else { 2575 (*a)->p = ASN1_INTEGER_to_BN(aip, NULL); 2576 if ((*a)->p == NULL) 2577 return NULL; 2578 if (ai.data != NULL) { 2579 OPENSSL_free(ai.data); 2580 ai.data = NULL; 2581 ai.length = 0; 2582 } 2583 } 2584 M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER); 2585 if (aip == NULL) 2586 return NULL; 2587 else { 2588 (*a)->g = ASN1_INTEGER_to_BN(aip, NULL); 2589 if ((*a)->g == NULL) 2590 return NULL; 2591 if (ai.data != NULL) { 2592 OPENSSL_free(ai.data); 2593 ai.data = NULL; 2594 ai.length = 0; 2595 } 2596 2597 } 2598 M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER); 2599 if (aip == NULL) 2600 return NULL; 2601 else { 2602 (*a)->q = ASN1_INTEGER_to_BN(aip, NULL); 2603 if ((*a)->q == NULL) 2604 return NULL; 2605 if (ai.data != NULL) { 2606 OPENSSL_free(ai.data); 2607 ai.data = NULL; 2608 ai.length = 0; 2609 } 2610 2611 } 2612 M_ASN1_D2I_end_sequence(); 2613 M_ASN1_D2I_Finish(a, DH_free, 0); 2614 2615 } 2616 2617 static krb5_error_code 2618 pkinit_create_sequence_of_principal_identifiers( 2619 krb5_context context, 2620 pkinit_plg_crypto_context plg_cryptoctx, 2621 pkinit_req_crypto_context req_cryptoctx, 2622 pkinit_identity_crypto_context id_cryptoctx, 2623 int type, 2624 krb5_data **out_data) 2625 { 2626 krb5_error_code retval = KRB5KRB_ERR_GENERIC; 2627 krb5_external_principal_identifier **krb5_trusted_certifiers = NULL; 2628 krb5_data *td_certifiers = NULL, *data = NULL; 2629 krb5_typed_data **typed_data = NULL; 2630 2631 switch(type) { 2632 case TD_TRUSTED_CERTIFIERS: 2633 retval = create_krb5_trustedCertifiers(context, plg_cryptoctx, 2634 req_cryptoctx, id_cryptoctx, &krb5_trusted_certifiers); 2635 if (retval) { 2636 pkiDebug("create_krb5_trustedCertifiers failed\n"); 2637 goto cleanup; 2638 } 2639 break; 2640 case TD_INVALID_CERTIFICATES: 2641 retval = create_krb5_invalidCertificates(context, plg_cryptoctx, 2642 req_cryptoctx, id_cryptoctx, &krb5_trusted_certifiers); 2643 if (retval) { 2644 pkiDebug("create_krb5_invalidCertificates failed\n"); 2645 goto cleanup; 2646 } 2647 break; 2648 default: 2649 retval = -1; 2650 goto cleanup; 2651 } 2652 2653 retval = k5int_encode_krb5_td_trusted_certifiers((const krb5_external_principal_identifier **)krb5_trusted_certifiers, &td_certifiers); 2654 if (retval) { 2655 pkiDebug("encode_krb5_td_trusted_certifiers failed\n"); 2656 goto cleanup; 2657 } 2658 #ifdef DEBUG_ASN1 2659 print_buffer_bin((unsigned char *)td_certifiers->data, 2660 td_certifiers->length, "/tmp/kdc_td_certifiers"); 2661 #endif 2662 typed_data = malloc (2 * sizeof(krb5_typed_data *)); 2663 if (typed_data == NULL) { 2664 retval = ENOMEM; 2665 goto cleanup; 2666 } 2667 typed_data[1] = NULL; 2668 init_krb5_typed_data(&typed_data[0]); 2669 if (typed_data[0] == NULL) { 2670 retval = ENOMEM; 2671 goto cleanup; 2672 } 2673 typed_data[0]->type = type; 2674 typed_data[0]->length = td_certifiers->length; 2675 typed_data[0]->data = (unsigned char *)td_certifiers->data; 2676 retval = k5int_encode_krb5_typed_data((const krb5_typed_data **)typed_data, 2677 &data); 2678 if (retval) { 2679 pkiDebug("encode_krb5_typed_data failed\n"); 2680 goto cleanup; 2681 } 2682 #ifdef DEBUG_ASN1 2683 print_buffer_bin((unsigned char *)data->data, data->length, 2684 "/tmp/kdc_edata"); 2685 #endif 2686 *out_data = (krb5_data *)malloc(sizeof(krb5_data)); 2687 (*out_data)->length = data->length; 2688 (*out_data)->data = (char *)malloc(data->length); 2689 (void) memcpy((*out_data)->data, data->data, data->length); 2690 2691 retval = 0; 2692 2693 cleanup: 2694 if (krb5_trusted_certifiers != NULL) 2695 free_krb5_external_principal_identifier(&krb5_trusted_certifiers); 2696 2697 if (data != NULL) { 2698 if (data->data != NULL) 2699 free(data->data); 2700 free(data); 2701 } 2702 2703 if (td_certifiers != NULL) 2704 free(td_certifiers); 2705 2706 if (typed_data != NULL) 2707 free_krb5_typed_data(&typed_data); 2708 2709 return retval; 2710 } 2711 2712 krb5_error_code 2713 pkinit_create_td_trusted_certifiers(krb5_context context, 2714 pkinit_plg_crypto_context plg_cryptoctx, 2715 pkinit_req_crypto_context req_cryptoctx, 2716 pkinit_identity_crypto_context id_cryptoctx, 2717 krb5_data **out_data) 2718 { 2719 krb5_error_code retval = KRB5KRB_ERR_GENERIC; 2720 2721 retval = pkinit_create_sequence_of_principal_identifiers(context, 2722 plg_cryptoctx, req_cryptoctx, id_cryptoctx, 2723 TD_TRUSTED_CERTIFIERS, out_data); 2724 2725 return retval; 2726 } 2727 2728 krb5_error_code 2729 pkinit_create_td_invalid_certificate( 2730 krb5_context context, 2731 pkinit_plg_crypto_context plg_cryptoctx, 2732 pkinit_req_crypto_context req_cryptoctx, 2733 pkinit_identity_crypto_context id_cryptoctx, 2734 krb5_data **out_data) 2735 { 2736 krb5_error_code retval = KRB5KRB_ERR_GENERIC; 2737 2738 retval = pkinit_create_sequence_of_principal_identifiers(context, 2739 plg_cryptoctx, req_cryptoctx, id_cryptoctx, 2740 TD_INVALID_CERTIFICATES, out_data); 2741 2742 return retval; 2743 } 2744 2745 /* ARGSUSED */ 2746 krb5_error_code 2747 pkinit_create_td_dh_parameters(krb5_context context, 2748 pkinit_plg_crypto_context plg_cryptoctx, 2749 pkinit_req_crypto_context req_cryptoctx, 2750 pkinit_identity_crypto_context id_cryptoctx, 2751 pkinit_plg_opts *opts, 2752 krb5_data **out_data) 2753 { 2754 /* Solaris Kerberos */ 2755 krb5_error_code retval = KRB5KRB_ERR_GENERIC; 2756 unsigned int buf1_len = 0, buf2_len = 0, buf3_len = 0, i = 0; 2757 unsigned char *buf1 = NULL, *buf2 = NULL, *buf3 = NULL; 2758 krb5_typed_data **typed_data = NULL; 2759 krb5_data *data = NULL, *encoded_algId = NULL; 2760 krb5_algorithm_identifier **algId = NULL; 2761 2762 /* Solaris Kerberos */ 2763 if (opts->dh_min_bits > 4096) { 2764 retval = EINVAL; 2765 goto cleanup; 2766 } 2767 2768 if (opts->dh_min_bits <= 1024) { 2769 retval = pkinit_encode_dh_params(plg_cryptoctx->dh_1024->p, 2770 plg_cryptoctx->dh_1024->g, plg_cryptoctx->dh_1024->q, 2771 &buf1, &buf1_len); 2772 if (retval) 2773 goto cleanup; 2774 } 2775 if (opts->dh_min_bits <= 2048) { 2776 retval = pkinit_encode_dh_params(plg_cryptoctx->dh_2048->p, 2777 plg_cryptoctx->dh_2048->g, plg_cryptoctx->dh_2048->q, 2778 &buf2, &buf2_len); 2779 if (retval) 2780 goto cleanup; 2781 } 2782 retval = pkinit_encode_dh_params(plg_cryptoctx->dh_4096->p, 2783 plg_cryptoctx->dh_4096->g, plg_cryptoctx->dh_4096->q, 2784 &buf3, &buf3_len); 2785 if (retval) 2786 goto cleanup; 2787 2788 if (opts->dh_min_bits <= 1024) { 2789 algId = malloc(4 * sizeof(krb5_algorithm_identifier *)); 2790 if (algId == NULL) 2791 goto cleanup; 2792 algId[3] = NULL; 2793 algId[0] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier)); 2794 if (algId[0] == NULL) 2795 goto cleanup; 2796 algId[0]->parameters.data = (unsigned char *)malloc(buf2_len); 2797 if (algId[0]->parameters.data == NULL) 2798 goto cleanup; 2799 (void) memcpy(algId[0]->parameters.data, buf2, buf2_len); 2800 algId[0]->parameters.length = buf2_len; 2801 algId[0]->algorithm = dh_oid; 2802 2803 algId[1] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier)); 2804 if (algId[1] == NULL) 2805 goto cleanup; 2806 algId[1]->parameters.data = (unsigned char *)malloc(buf3_len); 2807 if (algId[1]->parameters.data == NULL) 2808 goto cleanup; 2809 (void) memcpy(algId[1]->parameters.data, buf3, buf3_len); 2810 algId[1]->parameters.length = buf3_len; 2811 algId[1]->algorithm = dh_oid; 2812 2813 algId[2] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier)); 2814 if (algId[2] == NULL) 2815 goto cleanup; 2816 algId[2]->parameters.data = (unsigned char *)malloc(buf1_len); 2817 if (algId[2]->parameters.data == NULL) 2818 goto cleanup; 2819 (void) memcpy(algId[2]->parameters.data, buf1, buf1_len); 2820 algId[2]->parameters.length = buf1_len; 2821 algId[2]->algorithm = dh_oid; 2822 2823 } else if (opts->dh_min_bits <= 2048) { 2824 algId = malloc(3 * sizeof(krb5_algorithm_identifier *)); 2825 if (algId == NULL) 2826 goto cleanup; 2827 algId[2] = NULL; 2828 algId[0] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier)); 2829 if (algId[0] == NULL) 2830 goto cleanup; 2831 algId[0]->parameters.data = (unsigned char *)malloc(buf2_len); 2832 if (algId[0]->parameters.data == NULL) 2833 goto cleanup; 2834 (void) memcpy(algId[0]->parameters.data, buf2, buf2_len); 2835 algId[0]->parameters.length = buf2_len; 2836 algId[0]->algorithm = dh_oid; 2837 2838 algId[1] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier)); 2839 if (algId[1] == NULL) 2840 goto cleanup; 2841 algId[1]->parameters.data = (unsigned char *)malloc(buf3_len); 2842 if (algId[1]->parameters.data == NULL) 2843 goto cleanup; 2844 (void) memcpy(algId[1]->parameters.data, buf3, buf3_len); 2845 algId[1]->parameters.length = buf3_len; 2846 algId[1]->algorithm = dh_oid; 2847 2848 } else if (opts->dh_min_bits <= 4096) { 2849 algId = malloc(2 * sizeof(krb5_algorithm_identifier *)); 2850 if (algId == NULL) 2851 goto cleanup; 2852 algId[1] = NULL; 2853 algId[0] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier)); 2854 if (algId[0] == NULL) 2855 goto cleanup; 2856 algId[0]->parameters.data = (unsigned char *)malloc(buf3_len); 2857 if (algId[0]->parameters.data == NULL) 2858 goto cleanup; 2859 (void) memcpy(algId[0]->parameters.data, buf3, buf3_len); 2860 algId[0]->parameters.length = buf3_len; 2861 algId[0]->algorithm = dh_oid; 2862 2863 } 2864 retval = k5int_encode_krb5_td_dh_parameters((const krb5_algorithm_identifier **)algId, &encoded_algId); 2865 if (retval) 2866 goto cleanup; 2867 #ifdef DEBUG_ASN1 2868 print_buffer_bin((unsigned char *)encoded_algId->data, 2869 encoded_algId->length, "/tmp/kdc_td_dh_params"); 2870 #endif 2871 typed_data = malloc (2 * sizeof(krb5_typed_data *)); 2872 if (typed_data == NULL) { 2873 retval = ENOMEM; 2874 goto cleanup; 2875 } 2876 typed_data[1] = NULL; 2877 init_krb5_typed_data(&typed_data[0]); 2878 if (typed_data == NULL) { 2879 retval = ENOMEM; 2880 goto cleanup; 2881 } 2882 typed_data[0]->type = TD_DH_PARAMETERS; 2883 typed_data[0]->length = encoded_algId->length; 2884 typed_data[0]->data = (unsigned char *)encoded_algId->data; 2885 retval = k5int_encode_krb5_typed_data((const krb5_typed_data**)typed_data, 2886 &data); 2887 if (retval) { 2888 pkiDebug("encode_krb5_typed_data failed\n"); 2889 goto cleanup; 2890 } 2891 #ifdef DEBUG_ASN1 2892 print_buffer_bin((unsigned char *)data->data, data->length, 2893 "/tmp/kdc_edata"); 2894 #endif 2895 *out_data = (krb5_data *)malloc(sizeof(krb5_data)); 2896 if (*out_data == NULL) 2897 goto cleanup; 2898 (*out_data)->length = data->length; 2899 (*out_data)->data = (char *)malloc(data->length); 2900 if ((*out_data)->data == NULL) { 2901 free(*out_data); 2902 *out_data = NULL; 2903 goto cleanup; 2904 } 2905 (void) memcpy((*out_data)->data, data->data, data->length); 2906 2907 retval = 0; 2908 cleanup: 2909 2910 if (buf1 != NULL) 2911 free(buf1); 2912 if (buf2 != NULL) 2913 free(buf2); 2914 if (buf3 != NULL) 2915 free(buf3); 2916 if (data != NULL) { 2917 if (data->data != NULL) 2918 free(data->data); 2919 free(data); 2920 } 2921 if (typed_data != NULL) 2922 free_krb5_typed_data(&typed_data); 2923 if (encoded_algId != NULL) 2924 free(encoded_algId); 2925 2926 if (algId != NULL) { 2927 while(algId[i] != NULL) { 2928 if (algId[i]->parameters.data != NULL) 2929 free(algId[i]->parameters.data); 2930 free(algId[i]); 2931 i++; 2932 } 2933 free(algId); 2934 } 2935 2936 return retval; 2937 } 2938 2939 /* ARGSUSED */ 2940 krb5_error_code 2941 pkinit_check_kdc_pkid(krb5_context context, 2942 pkinit_plg_crypto_context plg_cryptoctx, 2943 pkinit_req_crypto_context req_cryptoctx, 2944 pkinit_identity_crypto_context id_cryptoctx, 2945 unsigned char *pdid_buf, 2946 unsigned int pkid_len, 2947 int *valid_kdcPkId) 2948 { 2949 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED; 2950 PKCS7_ISSUER_AND_SERIAL *is = NULL; 2951 const unsigned char *p = pdid_buf; 2952 int status = 1; 2953 X509 *kdc_cert = sk_X509_value(id_cryptoctx->my_certs, id_cryptoctx->cert_index); 2954 2955 *valid_kdcPkId = 0; 2956 pkiDebug("found kdcPkId in AS REQ\n"); 2957 is = d2i_PKCS7_ISSUER_AND_SERIAL(NULL, &p, (int)pkid_len); 2958 if (is == NULL) 2959 goto cleanup; 2960 2961 status = X509_NAME_cmp(X509_get_issuer_name(kdc_cert), is->issuer); 2962 if (!status) { 2963 status = ASN1_INTEGER_cmp(X509_get_serialNumber(kdc_cert), is->serial); 2964 if (!status) 2965 *valid_kdcPkId = 1; 2966 } 2967 2968 retval = 0; 2969 cleanup: 2970 X509_NAME_free(is->issuer); 2971 ASN1_INTEGER_free(is->serial); 2972 free(is); 2973 2974 return retval; 2975 } 2976 2977 static int 2978 pkinit_check_dh_params(BIGNUM * p1, BIGNUM * p2, BIGNUM * g1, BIGNUM * q1) 2979 { 2980 BIGNUM *g2 = NULL, *q2 = NULL; 2981 /* Solaris Kerberos */ 2982 int retval = EINVAL; 2983 2984 if (!BN_cmp(p1, p2)) { 2985 g2 = BN_new(); 2986 BN_set_word(g2, DH_GENERATOR_2); 2987 if (!BN_cmp(g1, g2)) { 2988 q2 = BN_new(); 2989 BN_rshift1(q2, p1); 2990 if (!BN_cmp(q1, q2)) { 2991 pkiDebug("good %d dhparams\n", BN_num_bits(p1)); 2992 retval = 0; 2993 } else 2994 pkiDebug("bad group 2 q dhparameter\n"); 2995 BN_free(q2); 2996 } else 2997 pkiDebug("bad g dhparameter\n"); 2998 BN_free(g2); 2999 } else 3000 pkiDebug("p is not well-known group 2 dhparameter\n"); 3001 3002 return retval; 3003 } 3004 3005 /* ARGSUSED */ 3006 krb5_error_code 3007 pkinit_process_td_dh_params(krb5_context context, 3008 pkinit_plg_crypto_context cryptoctx, 3009 pkinit_req_crypto_context req_cryptoctx, 3010 pkinit_identity_crypto_context id_cryptoctx, 3011 krb5_algorithm_identifier **algId, 3012 int *new_dh_size) 3013 { 3014 krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED; 3015 int i = 0, use_sent_dh = 0, ok = 0; 3016 3017 pkiDebug("dh parameters\n"); 3018 3019 while (algId[i] != NULL) { 3020 DH *dh = NULL; 3021 unsigned char *tmp = NULL; 3022 int dh_prime_bits = 0; 3023 3024 if (algId[i]->algorithm.length != dh_oid.length || 3025 memcmp(algId[i]->algorithm.data, dh_oid.data, dh_oid.length)) 3026 goto cleanup; 3027 3028 tmp = algId[i]->parameters.data; 3029 dh = DH_new(); 3030 dh = pkinit_decode_dh_params(&dh, &tmp, algId[i]->parameters.length); 3031 dh_prime_bits = BN_num_bits(dh->p); 3032 pkiDebug("client sent %d DH bits server prefers %d DH bits\n", 3033 *new_dh_size, dh_prime_bits); 3034 switch(dh_prime_bits) { 3035 case 1024: 3036 if (pkinit_check_dh_params(cryptoctx->dh_1024->p, dh->p, 3037 dh->g, dh->q) == 0) { 3038 *new_dh_size = 1024; 3039 ok = 1; 3040 } 3041 break; 3042 case 2048: 3043 if (pkinit_check_dh_params(cryptoctx->dh_2048->p, dh->p, 3044 dh->g, dh->q) == 0) { 3045 *new_dh_size = 2048; 3046 ok = 1; 3047 } 3048 break; 3049 case 4096: 3050 if (pkinit_check_dh_params(cryptoctx->dh_4096->p, dh->p, 3051 dh->g, dh->q) == 0) { 3052 *new_dh_size = 4096; 3053 ok = 1; 3054 } 3055 break; 3056 default: 3057 break; 3058 } 3059 if (!ok) { 3060 DH_check(dh, &retval); 3061 if (retval != 0) { 3062 pkiDebug("DH parameters provided by server are unacceptable\n"); 3063 retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED; 3064 } 3065 else { 3066 use_sent_dh = 1; 3067 ok = 1; 3068 } 3069 } 3070 if (!use_sent_dh) 3071 DH_free(dh); 3072 if (ok) { 3073 if (req_cryptoctx->dh != NULL) { 3074