1 /* 2 * ==================================================================== 3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * 17 * 3. All advertising materials mentioning features or use of this 18 * software must display the following acknowledgment: 19 * "This product includes software developed by the OpenSSL Project 20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 21 * 22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23 * endorse or promote products derived from this software without 24 * prior written permission. For written permission, please contact 25 * licensing@OpenSSL.org. 26 * 27 * 5. Products derived from this software may not be called "OpenSSL" 28 * nor may "OpenSSL" appear in their names without prior written 29 * permission of the OpenSSL Project. 30 * 31 * 6. Redistributions of any form whatsoever must retain the following 32 * acknowledgment: 33 * "This product includes software developed by the OpenSSL Project 34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 35 * 36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47 * OF THE POSSIBILITY OF SUCH DAMAGE. 48 * ==================================================================== 49 * 50 * This product includes cryptographic software written by Eric Young 51 * (eay@cryptsoft.com). This product includes software written by Tim 52 * Hudson (tjh@cryptsoft.com). 53 * 54 */ 55 56 /* 57 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 58 * Use is subject to license terms. 59 */ 60 61 /* 62 * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved. 63 */ 64 65 66 #include <strings.h> 67 #include <stdlib.h> 68 #include <assert.h> 69 70 #include <openssl/crypto.h> 71 #include <openssl/err.h> 72 #include <openssl/x509.h> 73 #include <openssl/pem.h> 74 75 #include <openssl/pkcs12.h> 76 #include "p12lib.h" 77 78 /* 79 * OpenSSL provides a framework for pushing error codes onto a stack. 80 * When an error occurs, the consumer may use the framework to 81 * pop the errors off the stack and provide a trace of where the 82 * errors occurred. 83 * 84 * Our PKCS12 code plugs into this framework by calling 85 * ERR_load_SUNW_strings(). To push an error (which by the way, consists 86 * of a function code and an error code) onto the stack our PKCS12 code 87 * calls SUNWerr(). 88 * 89 * Consumers of our PKCS12 code can then call the OpenSSL error routines 90 * when an error occurs and retrieve the stack of errors. 91 */ 92 93 #ifndef OPENSSL_NO_ERR 94 95 /* Function codes and their matching strings */ 96 static ERR_STRING_DATA SUNW_str_functs[] = { 97 { ERR_PACK(0, SUNW_F_USE_X509CERT, 0), "sunw_use_x509cert" }, 98 { ERR_PACK(0, SUNW_F_USE_PKEY, 0), "sunw_use_pkey" }, 99 { ERR_PACK(0, SUNW_F_USE_TASTORE, 0), "sunw_use_tastore" }, 100 { ERR_PACK(0, SUNW_F_USE_CERTFILE, 0), "sunw_p12_use_certfile" }, 101 { ERR_PACK(0, SUNW_F_USE_KEYFILE, 0), "sunw_p12_use_keyfile" }, 102 { ERR_PACK(0, SUNW_F_USE_TRUSTFILE, 0), "sunw_p12_use_trustfile" }, 103 { ERR_PACK(0, SUNW_F_READ_FILE, 0), "p12_read_file" }, 104 { ERR_PACK(0, SUNW_F_DOPARSE, 0), "p12_doparse" }, 105 { ERR_PACK(0, SUNW_F_PKCS12_PARSE, 0), "sunw_PKCS12_parse" }, 106 { ERR_PACK(0, SUNW_F_PKCS12_CONTENTS, 0), "sunw_PKCS12_contents" }, 107 { ERR_PACK(0, SUNW_F_PARSE_ONE_BAG, 0), "parse_one_bag" }, 108 { ERR_PACK(0, SUNW_F_PKCS12_CREATE, 0), "sunw_PKCS12_create" }, 109 { ERR_PACK(0, SUNW_F_SPLIT_CERTS, 0), "sunw_split_certs" }, 110 { ERR_PACK(0, SUNW_F_FIND_LOCALKEYID, 0), "sunw_find_localkeyid" }, 111 { ERR_PACK(0, SUNW_F_SET_LOCALKEYID, 0), "sunw_set_localkeyid" }, 112 { ERR_PACK(0, SUNW_F_GET_LOCALKEYID, 0), "sunw_get_localkeyid" }, 113 { ERR_PACK(0, SUNW_F_SET_FNAME, 0), "sunw_set_fname" }, 114 { ERR_PACK(0, SUNW_F_GET_PKEY_FNAME, 0), "sunw_get_pkey_fname" }, 115 { ERR_PACK(0, SUNW_F_APPEND_KEYS, 0), "sunw_append_keys" }, 116 { ERR_PACK(0, SUNW_F_PEM_CONTENTS, 0), "sunw_PEM_contents" }, 117 { ERR_PACK(0, SUNW_F_PEM_INFO, 0), "pem_info" }, 118 { ERR_PACK(0, SUNW_F_ASC2BMPSTRING, 0), "asc2bmpstring" }, 119 { ERR_PACK(0, SUNW_F_UTF82ASCSTR, 0), "utf82ascstr" }, 120 { ERR_PACK(0, SUNW_F_FINDATTR, 0), "findattr" }, 121 { ERR_PACK(0, SUNW_F_TYPE2ATTRIB, 0), "type2attrib" }, 122 { ERR_PACK(0, SUNW_F_MOVE_CERTS, 0), "move_certs" }, 123 { ERR_PACK(0, SUNW_F_FIND_FNAME, 0), "sunw_find_fname" }, 124 { ERR_PACK(0, SUNW_F_PARSE_OUTER, 0), "parse_outer" }, 125 { ERR_PACK(0, SUNW_F_CHECKFILE, 0), "checkfile" }, 126 { 0, NULL } 127 }; 128 129 /* Error codes and their matching strings */ 130 static ERR_STRING_DATA SUNW_str_reasons[] = { 131 { SUNW_R_INVALID_ARG, "invalid argument" }, 132 { SUNW_R_MEMORY_FAILURE, "memory failure" }, 133 { SUNW_R_MAC_VERIFY_FAILURE, "mac verify failure" }, 134 { SUNW_R_MAC_CREATE_FAILURE, "mac create failure" }, 135 { SUNW_R_BAD_FILETYPE, "bad file type" }, 136 { SUNW_R_BAD_PKEY, "bad or missing private key" }, 137 { SUNW_R_BAD_PKEYTYPE, "unsupported key type" }, 138 { SUNW_R_PKEY_READ_ERR, "unable to read private key" }, 139 { SUNW_R_NO_TRUST_ANCHOR, "no trust anchors found" }, 140 { SUNW_R_READ_TRUST_ERR, "unable to read trust anchor" }, 141 { SUNW_R_ADD_TRUST_ERR, "unable to add trust anchor" }, 142 { SUNW_R_PKCS12_PARSE_ERR, "PKCS12 parse error" }, 143 { SUNW_R_PKCS12_CREATE_ERR, "PKCS12 create error" }, 144 { SUNW_R_BAD_CERTTYPE, "unsupported certificate type" }, 145 { SUNW_R_PARSE_CERT_ERR, "error parsing PKCS12 certificate" }, 146 { SUNW_R_PARSE_BAG_ERR, "error parsing PKCS12 bag" }, 147 { SUNW_R_MAKE_BAG_ERR, "error making PKCS12 bag" }, 148 { SUNW_R_BAD_LKID, "bad localKeyID format" }, 149 { SUNW_R_SET_LKID_ERR, "error setting localKeyID" }, 150 { SUNW_R_BAD_FNAME, "bad friendlyName format" }, 151 { SUNW_R_SET_FNAME_ERR, "error setting friendlyName" }, 152 { SUNW_R_BAD_TRUST, "bad or missing trust anchor" }, 153 { SUNW_R_BAD_BAGTYPE, "unsupported bag type" }, 154 { SUNW_R_CERT_ERR, "certificate error" }, 155 { SUNW_R_PKEY_ERR, "private key error" }, 156 { SUNW_R_READ_ERR, "error reading file" }, 157 { SUNW_R_ADD_ATTR_ERR, "error adding attribute" }, 158 { SUNW_R_STR_CONVERT_ERR, "error converting string" }, 159 { SUNW_R_PKCS12_EMPTY_ERR, "empty PKCS12 structure" }, 160 { SUNW_R_PASSWORD_ERR, "bad password" }, 161 { 0, NULL } 162 }; 163 164 /* 165 * The library name that our module will be known as. This name 166 * may be retrieved via OpenSSLs error APIs. 167 */ 168 static ERR_STRING_DATA SUNW_lib_name[] = { 169 { 0, SUNW_LIB_NAME }, 170 { 0, NULL } 171 }; 172 #endif 173 174 /* 175 * The value of this variable (initialized by a call to 176 * ERR_load_SUNW_strings()) is what identifies our errors 177 * to OpenSSL as being ours. 178 */ 179 static int SUNW_lib_error_code = 0; 180 181 /* local routines */ 182 static int parse_pkcs12(PKCS12 *, const char *, int, char *, int, char *, 183 EVP_PKEY **, X509 **, STACK_OF(X509) **); 184 static int pem_info(FILE *, pem_password_cb, void *, 185 STACK_OF(EVP_PKEY) **, STACK_OF(X509) **); 186 187 static int parse_outer(PKCS12 *, const char *, STACK_OF(EVP_PKEY) *, 188 STACK_OF(X509) *); 189 190 static int parse_all_bags(STACK_OF(PKCS12_SAFEBAG) *, const char *, 191 STACK_OF(EVP_PKEY) *, STACK_OF(X509) *); 192 193 static int parse_one_bag(PKCS12_SAFEBAG *, const char *, 194 STACK_OF(EVP_PKEY) *, STACK_OF(X509) *); 195 196 static X509_ATTRIBUTE *type2attrib(ASN1_TYPE *, int); 197 static ASN1_TYPE *attrib2type(X509_ATTRIBUTE *); 198 static uchar_t *utf82ascstr(ASN1_UTF8STRING *); 199 static ASN1_BMPSTRING *asc2bmpstring(const char *, int); 200 static int find_attr_by_nid(STACK_OF(X509_ATTRIBUTE) *, int); 201 static int find_attr(int, ASN1_STRING *, STACK_OF(EVP_PKEY) *, 202 EVP_PKEY **, STACK_OF(X509) *, X509 **); 203 204 static chk_errs_t check_time(chk_actions_t, X509 *); 205 static int get_key_cert(int, STACK_OF(EVP_PKEY) *, EVP_PKEY **, 206 STACK_OF(X509) *, X509 **cert); 207 static int move_certs(STACK_OF(X509) *, STACK_OF(X509) *); 208 static int sunw_append_keys(STACK_OF(EVP_PKEY) *, 209 STACK_OF(EVP_PKEY) *); 210 static int set_results(STACK_OF(EVP_PKEY) **, 211 STACK_OF(EVP_PKEY) **, STACK_OF(X509) **, STACK_OF(X509) **, 212 STACK_OF(X509) **, STACK_OF(X509) **, 213 STACK_OF(EVP_PKEY) **, STACK_OF(EVP_PKEY) **); 214 215 /* 216 * ---------------------------------------------------------------------------- 217 * Public routines 218 * ---------------------------------------------------------------------------- 219 */ 220 221 /* 222 * sunw_PKCS12_parse - Parse a PKCS12 structure and break it into its parts. 223 * 224 * Parse and decrypt a PKCS#12 structure returning user key, user cert and/or 225 * other (CA) certs. Note either ca should be NULL, *ca should be NULL, 226 * or it should point to a valid STACK_OF(X509) structure. pkey and cert can 227 * be passed uninitialized. 228 * 229 * Arguments: 230 * p12 - Structure with pkcs12 info to be parsed 231 * pass - Pass phrase for the private key (possibly empty) or NULL if 232 * there is none. 233 * matchty - Info about which certs/keys to return if many are in the file. 234 * keyid - If private key localkeyids friendlynames are to match a 235 * predetermined value, the value to match. This value should 236 * be an octet string. 237 * keyid_len- Length of the keyid byte string. 238 * name_str - If friendlynames are to match a predetermined value, the value 239 * to match. This value should be a NULL terminated string. 240 * pkey - Points to location pointing to the private key returned. 241 * cert - Points to locaiton which points to the client cert returned 242 * ca - Points to location that points to a stack of 'certificate 243 * authority' certs/trust anchors. 244 * 245 * Match based on the value of 'matchty' and the contents of 'keyid' 246 * and/or 'name_str', as appropriate. Go through the lists of certs and 247 * private keys which were taken from the pkcs12 structure, looking for 248 * matches of the requested type. This function only searches the lists of 249 * matching private keys and client certificates. Kinds of matches allowed, 250 * and the order in which they will be checked, are: 251 * 252 * 1) Find the key and/or cert whose localkeyid attributes matches 253 * 'keyid'. 254 * 2) Find the key and/or cert whose friendlyname attributes matches 255 * 'name_str' 256 * 3) Return the first matching key/cert pair found. 257 * 4) Return the last matching key/cert pair found. 258 * 5) Return whatever cert and/or key are available, even unmatching. 259 * 260 * Append to the CA list, the certs which do not have matching private 261 * keys and which were not selected. 262 * 263 * If none of the bits are set, no client certs or private keys will be 264 * returned. CA (aka trust anchor) certs can be. 265 * 266 * Notes: If #3 is selected, then #4 will never occur. CA certs will be 267 * selected after a cert/key pairs are isolated. 268 * 269 * Returns: 270 * < 0 - An error returned. Call ERR_get_error() to get errors information. 271 * Where possible, memory has been freed. 272 * >= 0 - Objects were found and returned. Which objects are indicated by 273 * which bits are set (FOUND_PKEY, FOUND_CERT, FOUND_CA_CERTS). 274 */ 275 int 276 sunw_PKCS12_parse(PKCS12 *p12, const char *pass, int matchty, char *keyid, 277 int keyid_len, char *name_str, EVP_PKEY **pkey, X509 **cert, 278 STACK_OF(X509) **ca) 279 { 280 boolean_t ca_supplied; 281 int retval = -1; 282 283 /* If NULL PKCS12 structure, this is an error */ 284 if (p12 == NULL) { 285 SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_INVALID_ARG); 286 return (-1); 287 } 288 289 /* Set up arguments.... These will be allocated if needed */ 290 if (pkey) 291 *pkey = NULL; 292 if (cert) 293 *cert = NULL; 294 295 /* 296 * If there is already a ca list, use it. Otherwise, allocate one 297 * and free is later if an error occurs or whatever.) 298 */ 299 ca_supplied = (ca != NULL && *ca != NULL); 300 if (ca != NULL && *ca == NULL) { 301 if ((*ca = sk_X509_new_null()) == NULL) { 302 SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_MEMORY_FAILURE); 303 return (-1); 304 } 305 } 306 307 /* 308 * If password is zero length or NULL then try verifying both cases 309 * to determine which password is correct. The reason for this is that 310 * under PKCS#12 password based encryption no password and a zero 311 * length password are two different things. If the password has a 312 * non-zero length and is not NULL then call PKCS12_verify_mac() with 313 * a length of '-1' and let it use strlen() to figure out the length 314 * of the password. 315 */ 316 /* Check the mac */ 317 if (pass == NULL || *pass == '\0') { 318 if (PKCS12_verify_mac(p12, NULL, 0)) 319 pass = NULL; 320 else if (PKCS12_verify_mac(p12, "", 0)) 321 pass = ""; 322 else { 323 SUNWerr(SUNW_F_PKCS12_PARSE, 324 SUNW_R_MAC_VERIFY_FAILURE); 325 goto err; 326 } 327 } else if (PKCS12_verify_mac(p12, pass, -1) == 0) { 328 SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_MAC_VERIFY_FAILURE); 329 goto err; 330 } 331 332 retval = parse_pkcs12(p12, pass, matchty, keyid, keyid_len, 333 name_str, pkey, cert, ca); 334 if (retval < 0) { 335 SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_PKCS12_PARSE_ERR); 336 goto err; 337 } 338 return (retval); 339 340 err: 341 if (pkey && *pkey) { 342 sunw_evp_pkey_free(*pkey); 343 } 344 if (cert && *cert) 345 X509_free(*cert); 346 if (ca_supplied == B_FALSE && ca != NULL) 347 sk_X509_pop_free(*ca, X509_free); 348 349 return (-1); 350 351 } 352 353 354 /* 355 * sunw_PEM_contents() parses a PEM file and returns component parts found 356 * 357 * Parse and decrypt a PEM file, returning any user keys and certs. 358 * 359 * There are some limits to this function. It will ignore the following: 360 * - certificates identified by "TRUSTED CERTIFICATE" 361 * - CERTIFICATE REQUEST and NEW CERTIFICATE REQUEST records. 362 * - X509 CRL 363 * - DH PARAMETERS 364 * - DSA PARAMETERS 365 * - Any PUBLIC KEY 366 * - PKCS7 367 * - PRIVATE KEY or ENCRYPTED PRIVATE KEY (PKCS 8) 368 * 369 * Arguments: 370 * fp - File pointer for file containing PEM data. 371 * pass - Pass phrase for the private key or NULL if there is none. 372 * pkeys - Points to address of a stack of private keys to return. 373 * certs - Points to address of a stack of client certs to return. 374 * 375 * The pointers to stacks should either be NULL or their contents should 376 * either be NULL or should point to a valid STACK_OF(X509) structure. 377 * If the stacks contain information, corresponding information from the 378 * file will be appended to the original contents. 379 * 380 * Note: Client certs and and their matching private keys will be in any 381 * order. 382 * 383 * Certs which have no matching private key are assumed to be ca certs. 384 * 385 * Returns: 386 * < 0 - An error returned. Call ERR_get_error() to get errors information. 387 * Where possible, memory has been freed. 388 * >= 0 - Objects were found and returned. Which objects are indicated by 389 * which bits are set (FOUND_PKEY, FOUND_CERT) 390 */ 391 int sunw_PEM_contents(FILE *fp, pem_password_cb *cb, void *userdata, 392 STACK_OF(EVP_PKEY) **pkey, STACK_OF(X509) **certs) 393 { 394 STACK_OF(EVP_PKEY) *work_kl = NULL; 395 STACK_OF(X509) *work_ca = NULL; 396 int retval = -1; 397 398 /* 399 * Allocate the working stacks for private key and for the 400 * ca certs. 401 */ 402 if ((work_kl = sk_EVP_PKEY_new_null()) == NULL) { 403 SUNWerr(SUNW_F_PEM_CONTENTS, SUNW_R_MEMORY_FAILURE); 404 goto cleanup; 405 } 406 407 if ((work_ca = sk_X509_new_null()) == NULL) { 408 SUNWerr(SUNW_F_PEM_CONTENTS, SUNW_R_MEMORY_FAILURE); 409 goto cleanup; 410 } 411 412 /* Error strings are set within the following. */ 413 if (pem_info(fp, cb, userdata, &work_kl, &work_ca) <= 0) { 414 goto cleanup; 415 } 416 417 /* on error, set_results() returns an error on the stack */ 418 retval = set_results(pkey, &work_kl, certs, &work_ca, NULL, NULL, NULL, 419 NULL); 420 cleanup: 421 if (work_kl != NULL) { 422 sk_EVP_PKEY_pop_free(work_kl, sunw_evp_pkey_free); 423 } 424 if (work_ca != NULL) 425 sk_X509_pop_free(work_ca, X509_free); 426 427 return (retval); 428 } 429 430 431 /* 432 * sunw_PKCS12_contents() parses a pkcs#12 structure and returns component 433 * parts found, without evaluation. 434 * 435 * Parse and decrypt a PKCS#12 structure returning any user keys and/or 436 * various certs. Note these should either be NULL, *whatever should 437 * be NULL, or it should point to a valid STACK_OF(X509) structure. 438 * 439 * Arguments: 440 * p12 - Structure with pkcs12 info to be parsed 441 * pass - Pass phrase for the private key and entire pkcs12 wad (possibly 442 * empty) or NULL if there is none. 443 * pkeys - Points to address of a stack of private keys to return. 444 * certs - Points to address of a stack of client certs return. 445 * 446 * Note: The certs and keys being returned are in random order. 447 * 448 * Returns: 449 * < 0 - An error returned. Call ERR_get_error() to get errors information. 450 * Where possible, memory has been freed. 451 * >= 0 - Objects were found and returned. Which objects are indicated by 452 * which bits are set (FOUND_PKEY or FOUND_CERT) 453 */ 454 int 455 sunw_PKCS12_contents(PKCS12 *p12, const char *pass, STACK_OF(EVP_PKEY) **pkey, 456 STACK_OF(X509) **certs) 457 { 458 STACK_OF(EVP_PKEY) *work_kl = NULL; 459 STACK_OF(X509) *work_ca = NULL; 460 int retval = -1; 461 462 /* 463 * Allocate the working stacks for private key and for the 464 * ca certs. 465 */ 466 if ((work_kl = sk_EVP_PKEY_new_null()) == NULL) { 467 SUNWerr(SUNW_F_PKCS12_CONTENTS, SUNW_R_MEMORY_FAILURE); 468 goto cleanup; 469 } 470 471 if ((work_ca = sk_X509_new_null()) == NULL) { 472 SUNWerr(SUNW_F_PKCS12_CONTENTS, SUNW_R_MEMORY_FAILURE); 473 goto cleanup; 474 } 475 476 if (parse_outer(p12, pass, work_kl, work_ca) == 0) { 477 /* 478 * Error already on stack 479 */ 480 goto cleanup; 481 } 482 483 /* on error, set_results() returns an error on the stack */ 484 retval = set_results(pkey, &work_kl, certs, &work_ca, NULL, 485 NULL, NULL, NULL); 486 487 cleanup: 488 if (work_kl != NULL) { 489 sk_EVP_PKEY_pop_free(work_kl, sunw_evp_pkey_free); 490 } 491 492 return (retval); 493 } 494 495 496 497 /* 498 * sunw_split_certs() - Given a list of certs and a list of private keys, 499 * moves certs which match one of the keys to a different stack. 500 * 501 * Arguments: 502 * allkeys - Points to a stack of private keys to search. 503 * allcerts - Points to a stack of certs to be searched. 504 * keycerts - Points to address of a stack of certs with matching private 505 * keys. They are moved from 'allcerts'. This may not be NULL 506 * when called. If *keycerts is NULL upon entry, a new stack will 507 * be allocated. Otherwise, it must be a valid STACK_OF(509). 508 * nocerts - Points to address of a stack for keys which have no matching 509 * certs. Keys are moved from 'allkeys' here when they have no 510 * matching certs. If this is NULL, matchless keys will be 511 * discarded. 512 * 513 * Notes: If an error occurs while moving certs, the cert being move may be 514 * lost. 'keycerts' may only contain part of the matching certs. The number 515 * of certs successfully moved can be found by checking sk_X509_num(keycerts). 516 * 517 * If there is a key which does not have a matching cert, it is moved to 518 * the list nocerts. 519 * 520 * If all certs are removed from 'certs' and/or 'pkeys', it will be the 521 * caller's responsibility to free the empty stacks. 522 * 523 * Returns: 524 * < 0 - An error returned. Call ERR_get_error() to get errors information. 525 * Where possible, memory has been freed. 526 * >= 0 - The number of certs moved from 'cert' to 'pkcerts'. 527 */ 528 int 529 sunw_split_certs(STACK_OF(EVP_PKEY) *allkeys, STACK_OF(X509) *allcerts, 530 STACK_OF(X509) **keycerts, STACK_OF(EVP_PKEY) **nocerts) 531 { 532 STACK_OF(X509) *matching; 533 STACK_OF(EVP_PKEY) *nomatch; 534 EVP_PKEY *tmpkey; 535 X509 *tmpcert; 536 int count = 0; 537 int found; 538 int res; 539 int i; 540 int k; 541 542 *keycerts = NULL; 543 if (nocerts != NULL) 544 *nocerts = NULL; 545 nomatch = NULL; 546 547 if ((matching = sk_X509_new_null()) == NULL) { 548 SUNWerr(SUNW_F_SPLIT_CERTS, SUNW_R_MEMORY_FAILURE); 549 return (-1); 550 } 551 *keycerts = matching; 552 553 k = 0; 554 while (k < sk_EVP_PKEY_num(allkeys)) { 555 found = 0; 556 tmpkey = sk_EVP_PKEY_value(allkeys, k); 557 558 for (i = 0; i < sk_X509_num(allcerts); i++) { 559 tmpcert = sk_X509_value(allcerts, i); 560 res = X509_check_private_key(tmpcert, tmpkey); 561 if (res != 0) { 562 count++; 563 found = 1; 564 tmpcert = sk_X509_delete(allcerts, i); 565 if (sk_X509_push(matching, tmpcert) == 0) { 566 X509_free(tmpcert); 567 SUNWerr(SUNW_F_SPLIT_CERTS, 568 SUNW_R_MEMORY_FAILURE); 569 return (-1); 570 } 571 break; 572 } 573 } 574 if (found != 0) { 575 /* 576 * Found a match - keep the key & check out the next 577 * one. 578 */ 579 k++; 580 } else { 581 /* 582 * No cert matching this key. Move the key if 583 * possible or discard it. Don't increment the 584 * index. 585 */ 586 if (nocerts == NULL) { 587 tmpkey = sk_EVP_PKEY_delete(allkeys, k); 588 sunw_evp_pkey_free(tmpkey); 589 } else { 590 if (*nocerts == NULL) { 591 nomatch = sk_EVP_PKEY_new_null(); 592 if (nomatch == NULL) { 593 SUNWerr(SUNW_F_SPLIT_CERTS, 594 SUNW_R_MEMORY_FAILURE); 595 return (-1); 596 } 597 *nocerts = nomatch; 598 } 599 tmpkey = sk_EVP_PKEY_delete(allkeys, k); 600 if (sk_EVP_PKEY_push(nomatch, tmpkey) == 0) { 601 sunw_evp_pkey_free(tmpkey); 602 SUNWerr(SUNW_F_SPLIT_CERTS, 603 SUNW_R_MEMORY_FAILURE); 604 return (-1); 605 } 606 } 607 } 608 } 609 610 return (count); 611 } 612 613 /* 614 * sunw_PKCS12_create() creates a pkcs#12 structure and given component parts. 615 * 616 * Given one or more of user private key, user cert and/or other (CA) certs, 617 * return an encrypted PKCS12 structure containing them. 618 * 619 * Arguments: 620 * pass - Pass phrase for the pkcs12 structure and private key (possibly 621 * empty) or NULL if there is none. It will be used to encrypt 622 * both the private key(s) and as the pass phrase for the whole 623 * pkcs12 wad. 624 * pkeys - Points to stack of private keys. 625 * certs - Points to stack of client (public ke) certs 626 * cacerts - Points to stack of 'certificate authority' certs (or trust 627 * anchors). 628 * 629 * Note that any of these may be NULL. 630 * 631 * Returns: 632 * NULL - An error occurred. 633 * != NULL - Address of PKCS12 structure. The user is responsible for 634 * freeing the memory when done. 635 */ 636 PKCS12 * 637 sunw_PKCS12_create(const char *pass, STACK_OF(EVP_PKEY) *pkeys, 638 STACK_OF(X509) *certs, STACK_OF(X509) *cacerts) 639 { 640 int nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC; 641 int nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; 642 STACK_OF(PKCS12_SAFEBAG) *bags = NULL; 643 STACK_OF(PKCS7) *safes = NULL; 644 PKCS12_SAFEBAG *bag = NULL; 645 PKCS8_PRIV_KEY_INFO *p8 = NULL; 646 EVP_PKEY *pkey = NULL; 647 PKCS12 *ret_p12 = NULL; 648 PKCS12 *p12 = NULL; 649 PKCS7 *authsafe = NULL; 650 X509 *cert = NULL; 651 uchar_t *str = NULL; 652 int certs_there = 0; 653 int keys_there = 0; 654 int len; 655 int i; 656 657 if ((safes = sk_PKCS7_new_null()) == NULL) { 658 SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_MEMORY_FAILURE); 659 return (NULL); 660 } 661 662 if ((bags = sk_PKCS12_SAFEBAG_new_null()) == NULL) { 663 SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_MEMORY_FAILURE); 664 goto err_ret; 665 } 666 667 if (certs != NULL && sk_X509_num(certs) > 0) { 668 669 for (i = 0; i < sk_X509_num(certs); i++) { 670 cert = sk_X509_value(certs, i); 671 672 /* Add user certificate */ 673 if ((bag = M_PKCS12_x5092certbag(cert)) == NULL) { 674 SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_CERT_ERR); 675 goto err_ret; 676 } 677 if (cert->aux != NULL && cert->aux->alias != NULL && 678 cert->aux->alias->type == V_ASN1_UTF8STRING) { 679 str = utf82ascstr(cert->aux->alias); 680 if (str == NULL) { 681 /* 682 * Error already on stack 683 */ 684 goto err_ret; 685 } 686 if (PKCS12_add_friendlyname_asc(bag, 687 (char const *) str, 688 strlen((char const *) str)) == 0) { 689 SUNWerr(SUNW_F_PKCS12_CREATE, 690 SUNW_R_ADD_ATTR_ERR); 691 goto err_ret; 692 } 693 } 694 if (cert->aux != NULL && cert->aux->keyid != NULL && 695 cert->aux->keyid->type == V_ASN1_OCTET_STRING) { 696 str = cert->aux->keyid->data; 697 len = cert->aux->keyid->length; 698 699 if (str != NULL && 700 PKCS12_add_localkeyid(bag, str, len) == 0) { 701 SUNWerr(SUNW_F_PKCS12_CREATE, 702 SUNW_R_ADD_ATTR_ERR); 703 goto err_ret; 704 } 705 } 706 if (sk_PKCS12_SAFEBAG_push(bags, bag) == 0) { 707 SUNWerr(SUNW_F_PKCS12_CREATE, 708 SUNW_R_MEMORY_FAILURE); 709 goto err_ret; 710 } 711 certs_there++; 712 bag = NULL; 713 } 714 } 715 716 if (cacerts != NULL && sk_X509_num(cacerts) > 0) { 717 718 /* Put all certs in structure */ 719 for (i = 0; i < sk_X509_num(cacerts); i++) { 720 cert = sk_X509_value(cacerts, i); 721 if ((bag = M_PKCS12_x5092certbag(cert)) == NULL) { 722 SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_CERT_ERR); 723 goto err_ret; 724 } 725 726 if (cert->aux != NULL && cert->aux->alias != NULL && 727 cert->aux->alias->type == V_ASN1_UTF8STRING) { 728 str = utf82ascstr(cert->aux->alias); 729 if (str == NULL) { 730 /* 731 * Error already on stack 732 */ 733 goto err_ret; 734 } 735 if (PKCS12_add_friendlyname_asc( 736 bag, (char const *) str, 737 strlen((char const *) str)) == 0) { 738 SUNWerr(SUNW_F_PKCS12_CREATE, 739 SUNW_R_ADD_ATTR_ERR); 740 goto err_ret; 741 } 742 } 743 if (cert->aux != NULL && cert->aux->keyid != NULL && 744 cert->aux->keyid->type == V_ASN1_OCTET_STRING) { 745 str = cert->aux->keyid->data; 746 len = cert->aux->keyid->length; 747 748 if (str != NULL && 749 PKCS12_add_localkeyid(bag, str, len) == 0) { 750 SUNWerr(SUNW_F_PKCS12_CREATE, 751 SUNW_R_ADD_ATTR_ERR); 752 goto err_ret; 753 } 754 } 755 if (sk_PKCS12_SAFEBAG_push(bags, bag) == 0) { 756 SUNWerr(SUNW_F_PKCS12_CREATE, 757 SUNW_R_MEMORY_FAILURE); 758 goto err_ret; 759 } 760 certs_there++; 761 bag = NULL; 762 } 763 } 764 765 if (certs != NULL || cacerts != NULL && certs_there) { 766 /* Turn certbags into encrypted authsafe */ 767 authsafe = PKCS12_pack_p7encdata(nid_cert, pass, -1, 768 NULL, 0, PKCS12_DEFAULT_ITER, bags); 769 if (authsafe == NULL) { 770 SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_CERT_ERR); 771 goto err_ret; 772 } 773 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 774 bags = NULL; 775 776 if (sk_PKCS7_push(safes, authsafe) == 0) { 777 SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_MEMORY_FAILURE); 778 goto err_ret; 779 } 780 authsafe = NULL; 781 } 782 783 if (pkeys != NULL && sk_EVP_PKEY_num(pkeys) > 0) { 784 785 if (bags == NULL && 786 (bags = sk_PKCS12_SAFEBAG_new_null()) == NULL) { 787 SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_MEMORY_FAILURE); 788 goto err_ret; 789 } 790 791 for (i = 0; i < sk_EVP_PKEY_num(pkeys); i++) { 792 793 pkey = sk_EVP_PKEY_value(pkeys, i); 794 795 /* Make a shrouded key bag */ 796 if ((p8 = EVP_PKEY2PKCS8(pkey)) == NULL) { 797 SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_PKEY_ERR); 798 goto err_ret; 799 } 800 801 bag = PKCS12_MAKE_SHKEYBAG(nid_key, pass, -1, NULL, 0, 802 PKCS12_DEFAULT_ITER, p8); 803 if (bag == NULL) { 804 SUNWerr(SUNW_F_PKCS12_CREATE, 805 SUNW_R_MAKE_BAG_ERR); 806 goto err_ret; 807 } 808 PKCS8_PRIV_KEY_INFO_free(p8); 809 p8 = NULL; 810 811 len = sunw_get_pkey_fname(GETDO_COPY, pkey, 812 (char **)&str); 813 if (str != NULL) { 814 if (PKCS12_add_friendlyname_asc(bag, 815 (const char *)str, len) == 0) { 816 SUNWerr(SUNW_F_PKCS12_CREATE, 817 SUNW_R_ADD_ATTR_ERR); 818 goto err_ret; 819 } 820 } 821 str = NULL; 822 823 len = sunw_get_pkey_localkeyid(GETDO_COPY, pkey, 824 (char **)&str, &len); 825 if (str != NULL) { 826 if (PKCS12_add_localkeyid(bag, str, len) == 0) { 827 SUNWerr(SUNW_F_PKCS12_CREATE, 828 SUNW_R_ADD_ATTR_ERR); 829 goto err_ret; 830 } 831 } 832 str = NULL; 833 834 if (sk_PKCS12_SAFEBAG_push(bags, bag) == 0) { 835 SUNWerr(SUNW_F_PKCS12_CREATE, 836 SUNW_R_MEMORY_FAILURE); 837 goto err_ret; 838 } 839 keys_there++; 840 bag = NULL; 841 } 842 843 if (keys_there) { 844 /* Turn into unencrypted authsafe */ 845 authsafe = PKCS12_pack_p7data(bags); 846 if (authsafe == NULL) { 847 SUNWerr(SUNW_F_PKCS12_CREATE, 848 SUNW_R_PKCS12_CREATE_ERR); 849 goto err_ret; 850 } 851 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 852 bags = NULL; 853 854 if (sk_PKCS7_push(safes, authsafe) == 0) { 855 SUNWerr(SUNW_F_PKCS12_CREATE, 856 SUNW_R_MEMORY_FAILURE); 857 } 858 authsafe = NULL; 859 } 860 } 861 862 if (certs_there == 0 && keys_there == 0) { 863 SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_PKCS12_EMPTY_ERR); 864 goto err_ret; 865 } 866 867 if ((p12 = PKCS12_init(NID_pkcs7_data)) == NULL) { 868 SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_PKCS12_CREATE_ERR); 869 goto err_ret; 870 } 871 872 /* 873 * Note that safes is copied by the following. Therefore, it needs 874 * to be freed whether or not the following succeeds. 875 */ 876 if (M_PKCS12_pack_authsafes(p12, safes) == 0) { 877 SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_PKCS12_CREATE_ERR); 878 goto err_ret; 879 } 880 if (PKCS12_set_mac(p12, pass, -1, NULL, 0, 2048, NULL) == 0) { 881 SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_MAC_CREATE_FAILURE); 882 goto err_ret; 883 } 884 885 ret_p12 = p12; 886 p12 = NULL; 887 888 /* Fallthrough is intentional */ 889 890 err_ret: 891 892 if (str != NULL) 893 free(str); 894 895 if (p8 != NULL) 896 PKCS8_PRIV_KEY_INFO_free(p8); 897 898 if (bag != NULL) 899 PKCS12_SAFEBAG_free(bag); 900 if (bags != NULL) 901 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 902 if (authsafe != NULL) 903 PKCS7_free(authsafe); 904 if (safes != NULL) 905 sk_PKCS7_pop_free(safes, PKCS7_free); 906 if (p12 != NULL) 907 PKCS12_free(p12); 908 909 return (ret_p12); 910 } 911 912 /* 913 * sunw_evp_pkey_free() Given an EVP_PKEY structure, free any attributes 914 * that are attached. Then free the EVP_PKEY itself. 915 * 916 * This is a replacement for EVP_PKEY_free() for the sunw stuff. 917 * It should be used in places where EVP_PKEY_free would be used, 918 * including calls to sk_EVP_PKEY_pop_free(). 919 * 920 * Arguments: 921 * pkey - Entry which potentially has attributes to be freed. 922 * 923 * Returns: 924 * None. 925 */ 926 void 927 sunw_evp_pkey_free(EVP_PKEY *pkey) 928 { 929 if (pkey != NULL) { 930 if (pkey->attributes != NULL) { 931 sk_X509_ATTRIBUTE_pop_free(pkey->attributes, 932 X509_ATTRIBUTE_free); 933 pkey->attributes = NULL; 934 } 935 EVP_PKEY_free(pkey); 936 } 937 } 938 939 /* 940 * sunw_set_localkeyid() sets the localkeyid in a cert, a private key or 941 * both. Any existing localkeyid will be discarded. 942 * 943 * Arguments: 944 * keyid_str- A byte string with the localkeyid to set 945 * keyid_len- Length of the keyid byte string. 946 * pkey - Points to a private key to set the keyidstr in. 947 * cert - Points to a cert to set the keyidstr in. 948 * 949 * Note that setting a keyid into a cert which will not be written out as 950 * a PKCS12 cert is pointless since it will be lost. 951 * 952 * Returns: 953 * 0 - Success. 954 * < 0 - An error occurred. It was probably an error in allocating 955 * memory. The error will be set in the error stack. Call 956 * ERR_get_error() to get specific information. 957 */ 958 int 959 sunw_set_localkeyid(const char *keyid_str, int keyid_len, EVP_PKEY *pkey, 960 X509 *cert) 961 { 962 X509_ATTRIBUTE *attr = NULL; 963 ASN1_STRING *str = NULL; 964 ASN1_TYPE *keyid = NULL; 965 int retval = -1; 966 int i; 967 968 if (cert != NULL) { 969 if (X509_keyid_set1(cert, (uchar_t *)keyid_str, keyid_len) 970 == 0) { 971 SUNWerr(SUNW_F_SET_LOCALKEYID, SUNW_R_SET_LKID_ERR); 972 goto cleanup; 973 } 974 } 975 if (pkey != NULL) { 976 str = (ASN1_STRING *)M_ASN1_OCTET_STRING_new(); 977 if (str == NULL || 978 M_ASN1_OCTET_STRING_set(str, keyid_str, keyid_len) == 0 || 979 (keyid = ASN1_TYPE_new()) == NULL) { 980 SUNWerr(SUNW_F_SET_LOCALKEYID, SUNW_R_MEMORY_FAILURE); 981 goto cleanup; 982 } 983 984 ASN1_TYPE_set(keyid, V_ASN1_OCTET_STRING, str); 985 str = NULL; 986 987 attr = type2attrib(keyid, NID_localKeyID); 988 if (attr == NULL) { 989 /* 990 * Error already on stack 991 */ 992 goto cleanup; 993 } 994 keyid = NULL; 995 996 if (pkey->attributes == NULL) { 997 pkey->attributes = sk_X509_ATTRIBUTE_new_null(); 998 if (pkey->attributes == NULL) { 999 SUNWerr(SUNW_F_SET_LOCALKEYID, 1000 SUNW_R_MEMORY_FAILURE); 1001 goto cleanup; 1002 } 1003 } else { 1004 i = find_attr_by_nid(pkey->attributes, NID_localKeyID); 1005 if (i >= 0) 1006 sk_X509_ATTRIBUTE_delete(pkey->attributes, i); 1007 } 1008 if (sk_X509_ATTRIBUTE_push(pkey->attributes, attr) == 0) { 1009 SUNWerr(SUNW_F_SET_LOCALKEYID, SUNW_R_MEMORY_FAILURE); 1010 goto cleanup; 1011 } 1012 attr = NULL; 1013 } 1014 retval = 0; 1015 1016 cleanup: 1017 if (str != NULL) 1018 ASN1_STRING_free(str); 1019 if (keyid != NULL) 1020 ASN1_TYPE_free(keyid); 1021 if (attr != NULL) 1022 X509_ATTRIBUTE_free(attr); 1023 1024 return (retval); 1025 } 1026 1027 /* 1028 * sunw_get_pkey_localkeyid() gets the localkeyid from a private key. It can 1029 * optionally remove the value found. 1030 * 1031 * Arguments: 1032 * dowhat - What to do with the attributes (remove them or copy them). 1033 * pkey - Points to a private key to set the keyidstr in. 1034 * keyid_str- Points to a location which will receive the pointer to 1035 * a byte string containing the binary localkeyid. Note that 1036 * this is a copy, and the caller must free it. 1037 * keyid_len- Length of keyid_str. 1038 * 1039 * Returns: 1040 * >= 0 - The number of characters in the keyid returned. 1041 * < 0 - An error occurred. It was probably an error in allocating 1042 * memory. The error will be set in the error stack. Call 1043 * ERR_get_error() to get specific information. 1044 */ 1045 int 1046 sunw_get_pkey_localkeyid(getdo_actions_t dowhat, EVP_PKEY *pkey, 1047 char **keyid_str, int *keyid_len) 1048 { 1049 X509_ATTRIBUTE *attr = NULL; 1050 ASN1_OCTET_STRING *str = NULL; 1051 ASN1_TYPE *ty = NULL; 1052 int len = 0; 1053 int i; 1054 1055 if (keyid_str != NULL) 1056 *keyid_str = NULL; 1057 if (keyid_len != NULL) 1058 *keyid_len = 0; 1059 1060 if (pkey == NULL || pkey->attributes == NULL) { 1061 return (0); 1062 } 1063 1064 if ((i = find_attr_by_nid(pkey->attributes, NID_localKeyID)) < 0) { 1065 return (0); 1066 } 1067 attr = sk_X509_ATTRIBUTE_value(pkey->attributes, i); 1068 1069 if ((ty = attrib2type(attr)) == NULL || 1070 ty->type != V_ASN1_OCTET_STRING) { 1071 return (0); 1072 } 1073 1074 if (dowhat == GETDO_DEL) { 1075 attr = sk_X509_ATTRIBUTE_delete(pkey->attributes, i); 1076 if (attr != NULL) 1077 X509_ATTRIBUTE_free(attr); 1078 return (0); 1079 } 1080 1081 str = ty->value.octet_string; 1082 len = str->length; 1083 if ((*keyid_str = malloc(len)) == NULL) { 1084 SUNWerr(SUNW_F_GET_LOCALKEYID, SUNW_R_MEMORY_FAILURE); 1085 return (-1); 1086 } 1087 1088 (void) memcpy(*keyid_str, str->data, len); 1089 *keyid_len = len; 1090 1091 return (len); 1092 } 1093 1094 /* 1095 * sunw_get_pkey_fname() gets the friendlyName from a private key. It can 1096 * optionally remove the value found. 1097 * 1098 * Arguments: 1099 * dowhat - What to do with the attributes (remove them or copy them). 1100 * pkey - Points to a private key to get the frientlyname from 1101 * fname - Points to a location which will receive the pointer to a 1102 * byte string with the ASCII friendlyname 1103 * 1104 * Returns: 1105 * >= 0 - The number of characters in the frienlyname returned. 1106 * < 0 - An error occurred. It was probably an error in allocating 1107 * memory. The error will be set in the error stack. Call 1108 * ERR_get_error() to get specific information. 1109 */ 1110 int 1111 sunw_get_pkey_fname(getdo_actions_t dowhat, EVP_PKEY *pkey, char **fname) 1112 { 1113 X509_ATTRIBUTE *attr = NULL; 1114 ASN1_BMPSTRING *str = NULL; 1115 ASN1_TYPE *ty = NULL; 1116 int len = 0; 1117 int i; 1118 1119 if (fname != NULL) 1120 *fname = NULL; 1121 1122 if (pkey == NULL || pkey->attributes == NULL) { 1123 return (0); 1124 } 1125 1126 if ((i = find_attr_by_nid(pkey->attributes, NID_friendlyName)) < 0) { 1127 return (0); 1128 } 1129 attr = sk_X509_ATTRIBUTE_value(pkey->attributes, i); 1130 1131 if ((ty = attrib2type(attr)) == NULL || 1132 ty->type != V_ASN1_BMPSTRING) { 1133 return (0); 1134 } 1135 1136 if (dowhat == GETDO_DEL) { 1137 attr = sk_X509_ATTRIBUTE_delete(pkey->attributes, i); 1138 if (attr != NULL) 1139 X509_ATTRIBUTE_free(attr); 1140 return (0); 1141 } 1142 1143 str = ty->value.bmpstring; 1144 #if OPENSSL_VERSION_NUMBER < 0x10000000L 1145 *fname = uni2asc(str->data, str->length); 1146 #else 1147 *fname = OPENSSL_uni2asc(str->data, str->length); 1148 #endif 1149 if (*fname == NULL) { 1150 SUNWerr(SUNW_F_GET_PKEY_FNAME, SUNW_R_MEMORY_FAILURE); 1151 return (-1); 1152 } 1153 1154 len = strlen(*fname); 1155 1156 return (len); 1157 } 1158 1159 /* 1160 * sunw_find_localkeyid() searches stacks of certs and private keys, 1161 * and returns the first matching cert/private key found. 1162 * 1163 * Look for a keyid in a stack of certs. if 'certs' is NULL and 'pkeys' is 1164 * not NULL, search the list of private keys. Move the matching cert to 1165 * 'matching_cert' and its matching private key to 'matching_pkey'. If no 1166 * cert or keys match, no match occurred. 1167 * 1168 * Arguments: 1169 * keyid_str- A byte string with the localkeyid to match 1170 * keyid_len- Length of the keyid byte string. 1171 * pkeys - Points to a stack of private keys which match the certs. 1172 * This may be NULL, in which case no keys are returned. 1173 * certs - Points to a stack of certs to search. If NULL, search the 1174 * stack of keys instead. 1175 * matching_pkey 1176 * - Pointer to receive address of first matching pkey found. 1177 * 'matching_pkey' must not be NULL; '*matching_pkey' will be 1178 * reset. 1179 * matching_cert 1180 * - Pointer to receive address of first matching cert found. 1181 * 'matching_cert' must not be NULL; '*matching_cert' will be 1182 * reset. 1183 * 1184 * Returns: 1185 * < 0 - An error returned. Call ERR_get_error() to get errors information. 1186 * Where possible, memory has been freed. 1187 * >= 0 - Objects were found and returned. Which objects are indicated by 1188 * which bits are set (FOUND_PKEY and/or FOUND_CERT). 1189 */ 1190 int 1191 sunw_find_localkeyid(char *keyid_str, int len, STACK_OF(EVP_PKEY) *pkeys, 1192 STACK_OF(X509) *certs, EVP_PKEY **matching_pkey, X509 **matching_cert) 1193 { 1194 ASN1_STRING *cmpstr = NULL; 1195 EVP_PKEY *tmp_pkey = NULL; 1196 X509 *tmp_cert = NULL; 1197 int retval = 0; 1198 1199 /* If NULL arguments, this is an error */ 1200 if (keyid_str == NULL || 1201 (pkeys == NULL || certs == NULL) || 1202 (pkeys != NULL && matching_pkey == NULL) || 1203 (certs != NULL && matching_cert == NULL)) { 1204 SUNWerr(SUNW_F_FIND_LOCALKEYID, SUNW_R_INVALID_ARG); 1205 return (-1); 1206 } 1207 1208 if (matching_pkey != NULL) 1209 *matching_pkey = NULL; 1210 if (matching_cert != NULL) 1211 *matching_cert = NULL; 1212 1213 cmpstr = (ASN1_STRING *)M_ASN1_OCTET_STRING_new(); 1214 if (cmpstr == NULL || 1215 M_ASN1_OCTET_STRING_set(cmpstr, keyid_str, len) == 0) { 1216 SUNWerr(SUNW_F_FIND_LOCALKEYID, SUNW_R_MEMORY_FAILURE); 1217 return (-1); 1218 } 1219 1220 retval = find_attr(NID_localKeyID, cmpstr, pkeys, &tmp_pkey, certs, 1221 &tmp_cert); 1222 if (retval == 0) { 1223 ASN1_STRING_free(cmpstr); 1224 return (retval); 1225 } 1226 1227 if (matching_pkey != NULL) 1228 *matching_pkey = tmp_pkey; 1229 if (matching_cert != NULL) 1230 *matching_cert = tmp_cert; 1231 1232 return (retval); 1233 } 1234 1235 /* 1236 * sunw_find_fname() searches stacks of certs and private keys for one with 1237 * a matching friendlyname and returns the first matching cert/private 1238 * key found. 1239 * 1240 * Look for a friendlyname in a stack of certs. if 'certs' is NULL and 'pkeys' 1241 * is not NULL, search the list of private keys. Move the matching cert to 1242 * 'matching_cert' and its matching private key to 'matching_pkey'. If no 1243 * cert or keys match, no match occurred. 1244 * 1245 * Arguments: 1246 * fname - Friendlyname to find (NULL-terminated ASCII string). 1247 * pkeys - Points to a stack of private keys which match the certs. 1248 * This may be NULL, in which case no keys are returned. 1249 * certs - Points to a stack of certs to search. If NULL, search the 1250 * stack of keys instead. 1251 * matching_pkey 1252 * - Pointer to receive address of first matching pkey found. 1253 * matching_cert 1254 * - Pointer to receive address of first matching cert found. 1255 * 1256 * Returns: 1257 * < 0 - An error returned. Call ERR_get_error() to get errors information. 1258 * Where possible, memory has been freed. 1259 * >= 0 - Objects were found and returned. Which objects are indicated by 1260 * which bits are set (FOUND_PKEY and/or FOUND_CERT). 1261 */ 1262 int 1263 sunw_find_fname(char *fname, STACK_OF(EVP_PKEY) *pkeys, STACK_OF(X509) *certs, 1264 EVP_PKEY **matching_pkey, X509 ** matching_cert) 1265 { 1266 ASN1_STRING *cmpstr = NULL; 1267 EVP_PKEY *tmp_pkey = NULL; 1268 X509 *tmp_cert = NULL; 1269 int retval = 0; 1270 1271 /* If NULL arguments, this is an error */ 1272 if (fname == NULL || 1273 (pkeys == NULL && certs == NULL) || 1274 (pkeys != NULL && matching_pkey == NULL) || 1275 (certs != NULL && matching_cert == NULL)) { 1276 SUNWerr(SUNW_F_FIND_FNAME, SUNW_R_INVALID_ARG); 1277 return (-1); 1278 } 1279 1280 if (matching_pkey != NULL) 1281 *matching_pkey = NULL; 1282 if (matching_cert != NULL) 1283 *matching_cert = NULL; 1284 1285 cmpstr = (ASN1_STRING *)asc2bmpstring(fname, strlen(fname)); 1286 if (cmpstr == NULL) { 1287 /* 1288 * Error already on stack 1289 */ 1290 return (-1); 1291 } 1292 1293 retval = find_attr(NID_friendlyName, cmpstr, pkeys, &tmp_pkey, certs, 1294 &tmp_cert); 1295 if (retval == 0) { 1296 ASN1_STRING_free(cmpstr); 1297 return (retval); 1298 } 1299 1300 if (matching_pkey != NULL) 1301 *matching_pkey = tmp_pkey; 1302 if (matching_cert != NULL) 1303 *matching_cert = tmp_cert; 1304 1305 return (retval); 1306 } 1307 1308 /* 1309 * sunw_get_cert_fname() gets the fiendlyname from a cert. It can 1310 * optionally remove the value found. 1311 * 1312 * Arguments: 1313 * dowhat - What to do with the attributes (remove them or copy them). 1314 * cert - Points to a cert to get the friendlyName from. 1315 * fname - Points to a location which will receive the pointer to a 1316 * byte string with the ASCII friendlyname 1317 * 1318 * Returns: 1319 * >= 0 - The number of characters in the friendlyname returned. 1320 * < 0 - An error occurred. It was probably an error in allocating 1321 * memory. The error will be set in the error stack. Call 1322 * ERR_get_error() to get specific information. 1323 */ 1324 int 1325 sunw_get_cert_fname(getdo_actions_t dowhat, X509 *cert, char **fname) 1326 { 1327 int len; 1328 1329 if (fname != NULL) 1330 *fname = NULL; 1331 1332 if (cert == NULL || cert->aux == NULL || cert->aux->alias == NULL) { 1333 return (0); 1334 } 1335 1336 if (dowhat == GETDO_DEL) { 1337 /* Delete the entry */ 1338 ASN1_UTF8STRING_free(cert->aux->alias); 1339 cert->aux->alias = NULL; 1340 return (0); 1341 } 1342 1343 *((uchar_t **)fname) = utf82ascstr(cert->aux->alias); 1344 if (*fname == NULL) { 1345 /* 1346 * Error already on stack 1347 */ 1348 return (-1); 1349 } 1350 1351 len = strlen(*fname); 1352 1353 return (len); 1354 } 1355 1356 /* 1357 * sunw_set_fname() sets the friendlyName in a cert, a private key or 1358 * both. Any existing friendlyname will be discarded. 1359 * 1360 * Arguments: 1361 * ascname - An ASCII string with the friendlyName to set 1362 * pkey - Points to a private key to set the fname in. 1363 * cert - Points to a cert to set the fname in. 1364 * 1365 * Note that setting a friendlyName into a cert which will not be written out 1366 * as a PKCS12 cert is pointless since it will be lost. 1367 * 1368 * Returns: 1369 * 0 - Success. 1370 * <0 - An error occurred. It was probably an error in allocating 1371 * memory. The error will be set in the error stack. Call 1372 * ERR_get_error() to get specific information. 1373 */ 1374 int 1375 sunw_set_fname(const char *ascname, EVP_PKEY *pkey, X509 *cert) 1376 { 1377 X509_ATTRIBUTE *attr = NULL; 1378 ASN1_BMPSTRING *str = NULL; 1379 ASN1_TYPE *fname = NULL; 1380 unsigned char *data = NULL; 1381 int retval = -1; 1382 int len; 1383 int i; 1384 1385 str = asc2bmpstring(ascname, strlen(ascname)); 1386 if (str == NULL) { 1387 /* 1388 * Error already on stack 1389 */ 1390 return (-1); 1391 } 1392 1393 if (cert != NULL) { 1394 if (cert->aux != NULL && cert->aux->alias != NULL) { 1395 ASN1_UTF8STRING_free(cert->aux->alias); 1396 } 1397 1398 len = ASN1_STRING_to_UTF8(&data, str); 1399 i = -23; 1400 if (len <= 0 || (i = X509_alias_set1(cert, data, len)) == 0) { 1401 SUNWerr(SUNW_F_SET_FNAME, SUNW_R_SET_FNAME_ERR); 1402 goto cleanup; 1403 } 1404 } 1405 if (pkey != NULL) { 1406 if ((fname = ASN1_TYPE_new()) == NULL) { 1407 SUNWerr(SUNW_F_SET_FNAME, SUNW_R_MEMORY_FAILURE); 1408 goto cleanup; 1409 } 1410 1411 ASN1_TYPE_set(fname, V_ASN1_BMPSTRING, str); 1412 str = NULL; 1413 1414 attr = type2attrib(fname, NID_friendlyName); 1415 if (attr == NULL) { 1416 /* 1417 * Error already on stack 1418 */ 1419 goto cleanup; 1420 } 1421 fname = NULL; 1422 1423 if (pkey->attributes == NULL) { 1424 pkey->attributes = sk_X509_ATTRIBUTE_new_null(); 1425 if (pkey->attributes == NULL) { 1426 SUNWerr(SUNW_F_SET_FNAME, 1427 SUNW_R_MEMORY_FAILURE); 1428 goto cleanup; 1429 } 1430 } else if ((i = find_attr_by_nid(pkey->attributes, 1431 NID_friendlyName)) >= 0) { 1432 (void) sk_X509_ATTRIBUTE_delete(pkey->attributes, i); 1433 } 1434 1435 if (sk_X509_ATTRIBUTE_push(pkey->attributes, attr) == 0) { 1436 SUNWerr(SUNW_F_SET_FNAME, SUNW_R_MEMORY_FAILURE); 1437 goto cleanup; 1438 } 1439 1440 attr = NULL; 1441 } 1442 retval = 0; 1443 1444 cleanup: 1445 if (data != NULL) 1446 OPENSSL_free(data); 1447 if (str != NULL) 1448 ASN1_BMPSTRING_free(str); 1449 if (fname != NULL) 1450 ASN1_TYPE_free(fname); 1451 if (attr != NULL) 1452 X509_ATTRIBUTE_free(attr); 1453 1454 return (retval); 1455 } 1456 1457 /* 1458 * sunw_check_keys() compares the public key in the certificate and a 1459 * private key to ensure that they match. 1460 * 1461 * Arguments: 1462 * cert - Points to a certificate. 1463 * pkey - Points to a private key. 1464 * 1465 * Returns: 1466 * == 0 - These do not match. 1467 * != 0 - The cert's public key and the private key match. 1468 */ 1469 int 1470 sunw_check_keys(X509 *cert, EVP_PKEY *pkey) 1471 { 1472 int retval = 0; 1473 1474 if (pkey != NULL && cert != NULL) 1475 retval = X509_check_private_key(cert, pkey); 1476 1477 return (retval); 1478 } 1479 1480 /* 1481 * sunw_check_cert_times() compares the time fields in a certificate 1482 * 1483 * Compare the 'not before' and the 'not after' times in the cert 1484 * to the current time. Return the results of the comparison (bad time formats, 1485 * cert not yet in force, cert expired or in range) 1486 * 1487 * Arguments: 1488 * dowhat - what field(s) to check. 1489 * cert - Points to a cert to check 1490 * 1491 * Returns: 1492 * Results of the comparison. 1493 */ 1494 chk_errs_t 1495 sunw_check_cert_times(chk_actions_t chkwhat, X509 *cert) 1496 { 1497 return (check_time(chkwhat, cert)); 1498 } 1499 1500 /* 1501 * ---------------------------------------------------------------------------- 1502 * Local routines 1503 * ---------------------------------------------------------------------------- 1504 */ 1505 1506 1507 /* 1508 * parse_pkcs12 - Oversee parsing of the pkcs12 structure. Get it 1509 * parsed. After that either return what's found directly, or 1510 * do any required matching. 1511 * 1512 * Arguments: 1513 * p12 - Structure with pkcs12 info to be parsed 1514 * pass - Pass phrase for the private key (possibly empty) or NULL if 1515 * there is none. 1516 * matchty - Info about which certs/keys to return if many are in the file. 1517 * keyid - If private key localkeyids friendlynames are to match a 1518 * predetermined value, the value to match. This value should 1519 * be an octet string. 1520 * keyid_len- Length of the keyid byte string. 1521 * name_str - If friendlynames are to match a predetermined value, the value 1522 * to match. This value should be a NULL terminated string. 1523 * pkey - Points to location pointing to the private key returned. 1524 * cert - Points to locaiton which points to the client cert returned 1525 * ca - Points to location that points to a stack of 'certificate 1526 * authority' certs/trust anchors. 1527 * 1528 * Note about error codes: This function is an internal function, and the 1529 * place where it is called sets error codes. Therefore only set an error 1530 * code if it is something that is unique or if the function which detected 1531 * the error doesn't set one. 1532 * 1533 * Returns: 1534 * == -1 - An error occurred. Call ERR_get_error() to get error information. 1535 * Where possible, memory has been freed. 1536 * == 0 - No matching returns were found. 1537 * > 0 - This is the aithmetic 'or' of the FOUND_* bits that indicate which 1538 * of the requested entries were found. 1539 */ 1540 static int 1541 parse_pkcs12(PKCS12 *p12, const char *pass, int matchty, char *keyid, 1542 int kstr_len, char *name_str, EVP_PKEY **pkey, X509 **cert, 1543 STACK_OF(X509) **ca) 1544 { 1545 STACK_OF(EVP_PKEY) *work_kl = NULL; /* Head for private key list */ 1546 STACK_OF(EVP_PKEY) *nocerts = NULL; /* Head for alt. key list */ 1547 STACK_OF(X509) *work_ca = NULL; /* Head for cert list */ 1548 STACK_OF(X509) *work_cl = NULL; 1549 int retval = 0; 1550 int n; 1551 1552 retval = sunw_PKCS12_contents(p12, pass, &work_kl, &work_ca); 1553 if (retval < 0) { 1554 goto cleanup; 1555 } else if (retval == 0) { 1556 /* 1557 * Not really an error here - its just that nothing was found. 1558 */ 1559 goto cleanup; 1560 } 1561 1562 if (sk_EVP_PKEY_num(work_kl) > 0) { 1563 1564 if (sunw_split_certs(work_kl, work_ca, &work_cl, &nocerts) 1565 < 0) { 1566 goto cleanup; 1567 } 1568 } 1569 1570 /* 1571 * Go through the lists of certs and private keys which were 1572 * returned, looking for matches of the appropriate type. Do these 1573 * in the order described above. 1574 */ 1575 if ((matchty & DO_FIND_KEYID) != 0) { 1576 1577 if (keyid == NULL) { 1578 SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_INVALID_ARG); 1579 retval = -1; 1580 goto cleanup; 1581 } 1582 1583 /* See if string matches localkeyid's */ 1584 retval = sunw_find_localkeyid(keyid, kstr_len, 1585 work_kl, work_cl, pkey, cert); 1586 if (retval != 0) { 1587 if (retval == -1) 1588 goto cleanup; 1589 else 1590 goto last_part; 1591 } 1592 } 1593 if ((matchty & DO_FIND_FN) != 0) { 1594 1595 if (name_str == NULL) { 1596 SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_INVALID_ARG); 1597 retval = -1; 1598 goto cleanup; 1599 } 1600 1601 /* See if string matches friendly names */ 1602 retval = sunw_find_fname(name_str, work_kl, work_cl, 1603 pkey, cert); 1604 if (retval != 0) { 1605 if (retval == -1) 1606 goto cleanup; 1607 else 1608 goto last_part; 1609 } 1610 } 1611 1612 if (matchty & DO_FIRST_PAIR) { 1613 1614 /* Find the first cert and private key and return them */ 1615 retval = get_key_cert(0, work_kl, pkey, work_cl, cert); 1616 if (retval != 0) { 1617 if (retval == -1) 1618 goto cleanup; 1619 else 1620 goto last_part; 1621 } 1622 } 1623 1624 if (matchty & DO_LAST_PAIR) { 1625 1626 /* 1627 * Find the last matching cert and private key and return 1628 * them. Since keys which don't have matching client certs 1629 * are at the end of the list of keys, use the number of 1630 * client certs to compute the position of the last private 1631 * key which matches a client cert. 1632 */ 1633 n = sk_X509_num(work_cl) - 1; 1634 retval = get_key_cert(n, work_kl, pkey, work_cl, cert); 1635 if (retval != 0) { 1636 if (retval == -1) 1637 goto cleanup; 1638 else 1639 goto last_part; 1640 } 1641 } 1642 1643 if (matchty & DO_UNMATCHING) { 1644 STACK_OF(EVP_PKEY) *tmpk; 1645 STACK_OF(X509) *tmpc; 1646 1647 /* Find the first cert and private key and return them */ 1648 tmpc = work_cl; 1649 if (work_cl == NULL || sk_X509_num(work_cl) == 0) 1650 tmpc = work_ca; 1651 tmpk = work_kl; 1652 if (work_kl == NULL || sk_EVP_PKEY_num(work_kl) == 0) 1653 tmpk = nocerts; 1654 retval = get_key_cert(0, tmpk, pkey, tmpc, cert); 1655 if (retval != 0) { 1656 if (retval == -1) 1657 goto cleanup; 1658 else 1659 goto last_part; 1660 } 1661 } 1662 1663 last_part: 1664 /* If no errors, terminate normally */ 1665 if (retval != -1) 1666 retval |= set_results(NULL, NULL, NULL, NULL, ca, &work_ca, 1667 NULL, NULL); 1668 if (retval >= 0) { 1669 goto clean_part; 1670 } 1671 1672 /* Fallthrough is intentional in error cases. */ 1673 cleanup: 1674 if (pkey != NULL && *pkey != NULL) { 1675 sunw_evp_pkey_free(*pkey); 1676 *pkey = NULL; 1677 } 1678 if (cert != NULL && *cert != NULL) { 1679 X509_free(*cert); 1680 *cert = NULL; 1681 } 1682 1683 clean_part: 1684 1685 if (work_kl != NULL) { 1686 sk_EVP_PKEY_pop_free(work_kl, sunw_evp_pkey_free); 1687 } 1688 if (work_ca != NULL) 1689 sk_X509_pop_free(work_ca, X509_free); 1690 if (work_cl != NULL) 1691 sk_X509_pop_free(work_cl, X509_free); 1692 1693 return (retval); 1694 } 1695 1696 /* 1697 * parse_outer - Unpack the outer PKCS#12 structure and go through the 1698 * individual bags. Return stacks of certs, private keys found and 1699 * CA certs found. 1700 * 1701 * Note about error codes: This function is an internal function, and the 1702 * place where it is called sets error codes. 1703 * 1704 * Returns: 1705 * 0 - An error returned. Call ERR_get_error() to get errors information. 1706 * Where possible, memory has been freed. 1707 * 1 - PKCS12 data object was parsed and lists of certs and private keys 1708 * were returned. 1709 */ 1710 static int 1711 parse_outer(PKCS12 *p12, const char *pass, STACK_OF(EVP_PKEY) *kl, 1712 STACK_OF(X509) *cl) 1713 { 1714 STACK_OF(PKCS12_SAFEBAG) *bags; 1715 STACK_OF(PKCS7) *asafes; 1716 int i, bagnid; 1717 PKCS7 *p7; 1718 1719 if ((asafes = M_PKCS12_unpack_authsafes(p12)) == NULL) 1720 return (0); 1721 1722 for (i = 0; i < sk_PKCS7_num(asafes); i++) { 1723 p7 = sk_PKCS7_value(asafes, i); 1724 bagnid = OBJ_obj2nid(p7->type); 1725 if (bagnid == NID_pkcs7_data) { 1726 bags = M_PKCS12_unpack_p7data(p7); 1727 } else if (bagnid == NID_pkcs7_encrypted) { 1728 /* 1729 * A length of '-1' means strlen() can be used 1730 * to determine the password length. 1731 */ 1732 bags = M_PKCS12_unpack_p7encdata(p7, pass, -1); 1733 } else { 1734 SUNWerr(SUNW_F_PARSE_OUTER, SUNW_R_BAD_BAGTYPE); 1735 return (0); 1736 } 1737 1738 if (bags == NULL) { 1739 SUNWerr(SUNW_F_PARSE_OUTER, SUNW_R_PARSE_BAG_ERR); 1740 sk_PKCS7_pop_free(asafes, PKCS7_free); 1741 return (0); 1742 } 1743 if (parse_all_bags(bags, pass, kl, cl) == 0) { 1744 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 1745 sk_PKCS7_pop_free(asafes, PKCS7_free); 1746 return (0); 1747 } 1748 } 1749 1750 return (1); 1751 } 1752 1753 /* 1754 * parse_all_bags - go through the stack of bags, parsing each. 1755 * 1756 * Note about error codes: This function is an internal function, and the 1757 * place where it is called sets error codes. 1758 * 1759 * Returns: 1760 * 0 - An error returned. Call ERR_get_error() to get errors information. 1761 * Where possible, memory has been freed. 1762 * 1 - Stack of safebags was parsed and lists of certs and private keys 1763 * were returned. 1764 */ 1765 static int 1766 parse_all_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, 1767 STACK_OF(EVP_PKEY) *kl, STACK_OF(X509) *cl) 1768 { 1769 int i; 1770 for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { 1771 if (parse_one_bag(sk_PKCS12_SAFEBAG_value(bags, i), 1772 pass, kl, cl) == 0) 1773 return (0); 1774 } 1775 return (1); 1776 } 1777 1778 /* 1779 * parse_one_bag - Parse an individual bag 1780 * 1781 * i = parse_one_bag(bag, pass, kl, cl); 1782 * 1783 * Arguments: 1784 * bag - pkcs12 safebag to parse. 1785 * pass - password for use in decryption of shrouded keybag 1786 * kl - Stack of private keys found so far. New private keys will 1787 * be added here if found. 1788 * cl - Stack of certs found so far. New certificates will be 1789 * added here if found. 1790 * 1791 * Returns: 1792 * 0 - An error returned. Call ERR_get_error() to get errors information. 1793 * Where possible, memory has been freed. 1794 * 1 - one safebag was parsed. If it contained a cert or private key, it 1795 * was added to the stack of certs or private keys found, respectively. 1796 * localKeyId or friendlyName attributes are returned with the 1797 * private key or certificate. 1798 */ 1799 static int 1800 parse_one_bag(PKCS12_SAFEBAG *bag, const char *pass, STACK_OF(EVP_PKEY) *kl, 1801 STACK_OF(X509) *cl) 1802 { 1803 X509_ATTRIBUTE *attr = NULL; 1804 ASN1_TYPE *keyid = NULL; 1805 ASN1_TYPE *fname = NULL; 1806 PKCS8_PRIV_KEY_INFO *p8; 1807 EVP_PKEY *pkey = NULL; 1808 X509 *x509 = NULL; 1809 uchar_t *data = NULL; 1810 char *str = NULL; 1811 int retval = 1; 1812 1813 keyid = PKCS12_get_attr(bag, NID_localKeyID); 1814 fname = PKCS12_get_attr(bag, NID_friendlyName); 1815 1816 switch (M_PKCS12_bag_type(bag)) { 1817 case NID_keyBag: 1818 if ((pkey = EVP_PKCS82PKEY(bag->value.keybag)) == NULL) { 1819 SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_PARSE_BAG_ERR); 1820 retval = 0; 1821 break; 1822 } 1823 break; 1824 1825 case NID_pkcs8ShroudedKeyBag: 1826 /* 1827 * A length of '-1' means strlen() can be used 1828 * to determine the password length. 1829 */ 1830 if ((p8 = M_PKCS12_decrypt_skey(bag, pass, -1)) == NULL) { 1831 SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_PARSE_BAG_ERR); 1832 retval = 0; 1833 break; 1834 } 1835 pkey = EVP_PKCS82PKEY(p8); 1836 PKCS8_PRIV_KEY_INFO_free(p8); 1837 if (pkey == NULL) { 1838 SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_PARSE_BAG_ERR); 1839 retval = 0; 1840 } 1841 break; 1842 1843 case NID_certBag: 1844 if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) { 1845 SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_BAD_CERTTYPE); 1846 break; 1847 } 1848 if ((x509 = M_PKCS12_certbag2x509(bag)) == NULL) { 1849 SUNWerr(SUNW_F_PARSE_ONE_BAG, 1850 SUNW_R_PARSE_CERT_ERR); 1851 retval = 0; 1852 break; 1853 } 1854 1855 if (keyid != NULL) { 1856 if (keyid->type != V_ASN1_OCTET_STRING) { 1857 SUNWerr(SUNW_F_PARSE_ONE_BAG, 1858 SUNW_R_BAD_LKID); 1859 retval = 0; 1860 break; 1861 } 1862 if (X509_keyid_set1(x509, 1863 keyid->value.octet_string->data, 1864 keyid->value.octet_string->length) == 0) { 1865 SUNWerr(SUNW_F_PARSE_ONE_BAG, 1866 SUNW_R_SET_LKID_ERR); 1867 retval = 0; 1868 break; 1869 } 1870 } 1871 1872 if (fname != NULL) { 1873 ASN1_STRING *tmpstr = NULL; 1874 int len; 1875 1876 if (fname->type != V_ASN1_BMPSTRING) { 1877 SUNWerr(SUNW_F_PARSE_ONE_BAG, 1878 SUNW_R_BAD_FNAME); 1879 retval = 0; 1880 break; 1881 } 1882 1883 tmpstr = fname->value.asn1_string; 1884 len = ASN1_STRING_to_UTF8(&data, tmpstr); 1885 if (len < 0) { 1886 SUNWerr(SUNW_F_PARSE_ONE_BAG, 1887 SUNW_R_SET_FNAME_ERR); 1888 retval = 0; 1889 break; 1890 } 1891 1892 if (X509_alias_set1(x509, data, len) == 0) { 1893 SUNWerr(SUNW_F_PARSE_ONE_BAG, 1894 SUNW_R_SET_FNAME_ERR); 1895 retval = 0; 1896 break; 1897 } 1898 } 1899 1900 if (sk_X509_push(cl, x509) == 0) { 1901 SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_MEMORY_FAILURE); 1902 retval = 0; 1903 break; 1904 } 1905 x509 = NULL; 1906 break; 1907 1908 case NID_safeContentsBag: 1909 if (keyid != NULL) 1910 ASN1_TYPE_free(keyid); 1911 if (fname != NULL) 1912 ASN1_TYPE_free(fname); 1913 if (parse_all_bags(bag->value.safes, pass, kl, cl) == 0) { 1914 /* 1915 * Error already on stack 1916 */ 1917 return (0); 1918 } 1919 return (1); 1920 1921 default: 1922 if (keyid != NULL) 1923 ASN1_TYPE_free(keyid); 1924 if (fname != NULL) 1925 ASN1_TYPE_free(fname); 1926 SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_BAD_BAGTYPE); 1927 return (0); 1928 } 1929 1930 1931 if (pkey != NULL) { 1932 if (retval != 0 && (keyid != NULL || fname != NULL) && 1933 pkey->attributes == NULL) { 1934 pkey->attributes = sk_X509_ATTRIBUTE_new_null(); 1935 if (pkey->attributes == NULL) { 1936 SUNWerr(SUNW_F_PARSE_ONE_BAG, 1937 SUNW_R_MEMORY_FAILURE); 1938 retval = 0; 1939 } 1940 } 1941 1942 if (retval != 0 && keyid != NULL) { 1943 attr = type2attrib(keyid, NID_localKeyID); 1944 if (attr == NULL) 1945 /* 1946 * Error already on stack 1947 */ 1948 retval = 0; 1949 else { 1950 keyid = NULL; 1951 if (sk_X509_ATTRIBUTE_push(pkey->attributes, 1952 attr) == 0) { 1953 SUNWerr(SUNW_F_PARSE_ONE_BAG, 1954 SUNW_R_MEMORY_FAILURE); 1955 retval = 0; 1956 } else { 1957 attr = NULL; 1958 } 1959 } 1960 } 1961 1962 if (retval != 0 && fname != NULL) { 1963 attr = type2attrib(fname, NID_friendlyName); 1964 if (attr == NULL) { 1965 /* 1966 * Error already on stack 1967 */ 1968 retval = 0; 1969 } else { 1970 fname = NULL; 1971 if (sk_X509_ATTRIBUTE_push(pkey->attributes, 1972 attr) == 0) { 1973 SUNWerr(SUNW_F_PARSE_ONE_BAG, 1974 SUNW_R_MEMORY_FAILURE); 1975 retval = 0; 1976 } else { 1977 attr = NULL; 1978 } 1979 } 1980 } 1981 1982 /* Save the private key */ 1983 if (retval != 0) { 1984 if (sk_EVP_PKEY_push(kl, pkey) == 0) { 1985 SUNWerr(SUNW_F_PARSE_ONE_BAG, 1986 SUNW_R_MEMORY_FAILURE); 1987 retval = 0; 1988 } else { 1989 pkey = NULL; 1990 } 1991 } 1992 } 1993 1994 if (pkey != NULL) { 1995 sunw_evp_pkey_free(pkey); 1996 } 1997 1998 if (x509 != NULL) 1999 X509_free(x509); 2000 2001 if (keyid != NULL) 2002 ASN1_TYPE_free(keyid); 2003 2004 if (fname != NULL) 2005 ASN1_TYPE_free(fname); 2006 2007 if (attr != NULL) 2008 X509_ATTRIBUTE_free(attr); 2009 2010 if (data != NULL) 2011 OPENSSL_free(data); 2012 2013 if (str != NULL) 2014 OPENSSL_free(str); 2015 2016 return (retval); 2017 } 2018 2019 /* 2020 * This function uses the only function that reads PEM files, regardless of 2021 * the kinds of information included (private keys, public keys, cert requests, 2022 * certs). Other interfaces that read files require that the application 2023 * specifically know what kinds of things to read next, and call different 2024 * interfaces for the different kinds of entities. 2025 * 2026 * There is only one aspect of this function that's a bit problematic. 2027 * If it finds an encrypted private key, it does not decrypt it. It returns 2028 * the encrypted data and other information needed to decrypt it. The caller 2029 * must do the decryption. This function does the decoding. 2030 */ 2031 static int 2032 pem_info(FILE *fp, pem_password_cb cb, void *userdata, 2033 STACK_OF(EVP_PKEY) **pkeys, STACK_OF(X509) **certs) 2034 { 2035 STACK_OF(X509_INFO) *info; 2036 STACK_OF(EVP_PKEY) *work_kl; 2037 STACK_OF(X509) *work_cl; 2038 X509_INFO *x; 2039 int retval = 0; 2040 int i; 2041 2042 info = PEM_X509_INFO_read(fp, NULL, cb, userdata); 2043 if (info == NULL) { 2044 SUNWerr(SUNW_F_PEM_INFO, SUNW_R_READ_ERR); 2045 return (-1); 2046 } 2047 2048 /* 2049 * Allocate the working stacks for private key(s) and for the cert(s). 2050 */ 2051 if ((work_kl = sk_EVP_PKEY_new_null()) == NULL) { 2052 SUNWerr(SUNW_F_PEM_INFO, SUNW_R_MEMORY_FAILURE); 2053 retval = -1; 2054 goto cleanup; 2055 } 2056 2057 if ((work_cl = sk_X509_new_null()) == NULL) { 2058 SUNWerr(SUNW_F_PEM_INFO, SUNW_R_MEMORY_FAILURE); 2059 retval = -1; 2060 goto cleanup; 2061 } 2062 2063 /* 2064 * Go through the entries in the info structure. 2065 */ 2066 for (i = 0; i < sk_X509_INFO_num(info); i++) { 2067 x = sk_X509_INFO_value(info, i); 2068 if (x->x509) { 2069 if (sk_X509_push(work_cl, x->x509) == 0) { 2070 retval = -1; 2071 break; 2072 } 2073 x->x509 = NULL; 2074 } 2075 if (x->x_pkey != NULL && x->x_pkey->dec_pkey != NULL && 2076 (x->x_pkey->dec_pkey->type == EVP_PKEY_RSA || 2077 x->x_pkey->dec_pkey->type == EVP_PKEY_DSA)) { 2078 const uchar_t *p; 2079 2080 /* 2081 * If the key was encrypted, PEM_X509_INFO_read does 2082 * not decrypt it. If that is the case, the 'enc_pkey' 2083 * field is set to point to the unencrypted key data. 2084 * Go through the additional steps to decode it before 2085 * going on. 2086 */ 2087 if (x->x_pkey->enc_pkey != NULL) { 2088 2089 if (PEM_do_header(&x->enc_cipher, 2090 (uchar_t *)x->enc_data, 2091 (long *)&x->enc_len, 2092 cb, userdata) == 0) { 2093 if (ERR_GET_REASON(ERR_peek_error()) == 2094 PEM_R_BAD_PASSWORD_READ) { 2095 SUNWerr(SUNW_F_PEM_INFO, 2096 SUNW_R_PASSWORD_ERR); 2097 } else { 2098 SUNWerr(SUNW_F_PEM_INFO, 2099 SUNW_R_PKEY_READ_ERR); 2100 } 2101 retval = -1; 2102 break; 2103 } 2104 if (x->x_pkey->dec_pkey->type == EVP_PKEY_RSA) { 2105 RSA **pp; 2106 2107 pp = &(x->x_pkey->dec_pkey->pkey.rsa); 2108 p = (uchar_t *)x->enc_data; 2109 if (d2i_RSAPrivateKey(pp, &p, 2110 x->enc_len) == NULL) { 2111 SUNWerr(SUNW_F_PEM_INFO, 2112 SUNW_R_PKEY_READ_ERR); 2113 retval = -1; 2114 break; 2115 } 2116 } else { 2117 DSA **pp; 2118 2119 pp = &(x->x_pkey->dec_pkey->pkey.dsa); 2120 p = (uchar_t *)x->enc_data; 2121 if (d2i_DSAPrivateKey(pp, &p, 2122 x->enc_len) == NULL) { 2123 SUNWerr(SUNW_F_PEM_INFO, 2124 SUNW_R_PKEY_READ_ERR); 2125 retval = -1; 2126 break; 2127 } 2128 } 2129 } 2130 2131 /* Save the key. */ 2132 retval = sk_EVP_PKEY_push(work_kl, x->x_pkey->dec_pkey); 2133 if (retval == 0) { 2134 retval = -1; 2135 break; 2136 } 2137 x->x_pkey->dec_pkey = NULL; 2138 } else if (x->x_pkey != NULL) { 2139 SUNWerr(SUNW_F_PEM_INFO, SUNW_R_BAD_PKEYTYPE); 2140 retval = -1; 2141 break; 2142 } 2143 } 2144 if (retval == -1) 2145 goto cleanup; 2146 2147 /* If error occurs, then error already on stack */ 2148 retval = set_results(pkeys, &work_kl, certs, &work_cl, NULL, NULL, 2149 NULL, NULL); 2150 2151 cleanup: 2152 if (work_kl != NULL) { 2153 sk_EVP_PKEY_pop_free(work_kl, sunw_evp_pkey_free); 2154 } 2155 if (work_cl != NULL) 2156 sk_X509_pop_free(work_cl, X509_free); 2157 2158 sk_X509_INFO_pop_free(info, X509_INFO_free); 2159 2160 return (retval); 2161 } 2162 2163 /* 2164 * sunw_append_keys - Given two stacks of private keys, remove the keys from 2165 * the second stack and append them to the first. Both stacks must exist 2166 * at time of call. 2167 * 2168 * Arguments: 2169 * dst - the stack to receive the keys from 'src' 2170 * src - the stack whose keys are to be moved. 2171 * 2172 * Returns: 2173 * -1 - An error occurred. The error status is set. 2174 * >= 0 - The number of keys that were copied. 2175 */ 2176 static int 2177 sunw_append_keys(STACK_OF(EVP_PKEY) *dst, STACK_OF(EVP_PKEY) *src) 2178 { 2179 EVP_PKEY *tmpk; 2180 int count = 0; 2181 2182 while (sk_EVP_PKEY_num(src) > 0) { 2183 tmpk = sk_EVP_PKEY_delete(src, 0); 2184 if (sk_EVP_PKEY_push(dst, tmpk) == 0) { 2185 sunw_evp_pkey_free(tmpk); 2186 SUNWerr(SUNW_F_APPEND_KEYS, SUNW_R_MEMORY_FAILURE); 2187 return (-1); 2188 } 2189 count ++; 2190 } 2191 2192 return (count); 2193 } 2194 2195 /* 2196 * move_certs - Given two stacks of certs, remove the certs from 2197 * the second stack and append them to the first. 2198 * 2199 * Arguments: 2200 * dst - the stack to receive the certs from 'src' 2201 * src - the stack whose certs are to be moved. 2202 * 2203 * Returns: 2204 * -1 - An error occurred. The error status is set. 2205 * >= 0 - The number of certs that were copied. 2206 */ 2207 static int 2208 move_certs(STACK_OF(X509) *dst, STACK_OF(X509) *src) 2209 { 2210 X509 *tmpc; 2211 int count = 0; 2212 2213 while (sk_X509_num(src) > 0) { 2214 tmpc = sk_X509_delete(src, 0); 2215 if (sk_X509_push(dst, tmpc) == 0) { 2216 X509_free(tmpc); 2217 SUNWerr(SUNW_F_MOVE_CERTS, SUNW_R_MEMORY_FAILURE); 2218 return (-1); 2219 } 2220 count++; 2221 } 2222 2223 return (count); 2224 } 2225 2226 /* 2227 * get_key_cert - Get a cert and its matching key from the stacks of certs 2228 * and keys. They are removed from the stacks. 2229 * 2230 * Arguments: 2231 * n - Offset of the entries to return. 2232 * kl - Points to a stack of private keys that matches the list of 2233 * certs below. 2234 * pkey - Points at location where the address of the matching private 2235 * key will be stored. 2236 * cl - Points to a stack of client certs with matching private keys. 2237 * cert - Points to locaiton where the address of the matching client cert 2238 * will be returned 2239 * 2240 * The assumption is that the stacks of keys and certs contain key/cert pairs, 2241 * with entries in the same order and hence at the same offset. Provided 2242 * the key and cert selected match, each will be removed from its stack and 2243 * returned. 2244 * 2245 * A stack of certs can be passed in without a stack of private keys, and vise 2246 * versa. In that case, the indicated key/cert will be returned. 2247 * 2248 * Returns: 2249 * 0 - No matches were found. 2250 * > 0 - Bits set based on FOUND_* definitions, indicating what is returned. 2251 * This can be FOUND_PKEY, FOUND_CERT or (FOUND_PKEY | FOUND_CERT). 2252 */ 2253 static int 2254 get_key_cert(int n, STACK_OF(EVP_PKEY) *kl, EVP_PKEY **pkey, STACK_OF(X509) *cl, 2255 X509 **cert) 2256 { 2257 int retval = 0; 2258 int nk; 2259 int nc; 2260 2261 nk = (kl != NULL) ? sk_EVP_PKEY_num(kl) : 0; 2262 nc = (cl != NULL) ? sk_X509_num(cl) : 0; 2263 2264 if (pkey != NULL && *pkey == NULL) { 2265 if (nk > 0 && n >= 0 || n < nk) { 2266 *pkey = sk_EVP_PKEY_delete(kl, n); 2267 if (*pkey != NULL) 2268 retval |= FOUND_PKEY; 2269 } 2270 } 2271 2272 if (cert != NULL && *cert == NULL) { 2273 if (nc > 0 && n >= 0 && n < nc) { 2274 *cert = sk_X509_delete(cl, n); 2275 if (*cert != NULL) 2276 retval |= FOUND_CERT; 2277 } 2278 } 2279 2280 return (retval); 2281 } 2282 2283 2284 /* 2285 * asc2bmpstring - Convert a regular C ASCII string to an ASn1_STRING in 2286 * ASN1_BMPSTRING format. 2287 * 2288 * Arguments: 2289 * str - String to be convered. 2290 * len - Length of the string. 2291 * 2292 * Returns: 2293 * == NULL - An error occurred. Error information (accessible by 2294 * ERR_get_error()) is set. 2295 * != NULL - Points to an ASN1_BMPSTRING structure with the converted 2296 * string as a value. 2297 */ 2298 static ASN1_BMPSTRING * 2299 asc2bmpstring(const char *str, int len) 2300 { 2301 ASN1_BMPSTRING *bmp = NULL; 2302 uchar_t *uni = NULL; 2303 int unilen; 2304 2305 /* Convert the character to the bmp format. */ 2306 #if OPENSSL_VERSION_NUMBER < 0x10000000L 2307 if (asc2uni(str, len, &uni, &unilen) == 0) { 2308 #else 2309 if (OPENSSL_asc2uni(str, len, &uni, &unilen) == 0) { 2310 #endif 2311 SUNWerr(SUNW_F_ASC2BMPSTRING, SUNW_R_MEMORY_FAILURE); 2312 return (NULL); 2313 } 2314 2315 /* 2316 * Adjust for possible pair of NULL bytes at the end because 2317 * asc2uni() returns a doubly null terminated string. 2318 */ 2319 if (uni[unilen - 1] == '\0' && uni[unilen - 2] == '\0') 2320 unilen -= 2; 2321 2322 /* Construct comparison string with correct format */ 2323 bmp = M_ASN1_BMPSTRING_new(); 2324 if (bmp == NULL) { 2325 SUNWerr(SUNW_F_ASC2BMPSTRING, SUNW_R_MEMORY_FAILURE); 2326 OPENSSL_free(uni); 2327 return (NULL); 2328 } 2329 2330 bmp->data = uni; 2331 bmp->length = unilen; 2332 2333 return (bmp); 2334 } 2335 2336 /* 2337 * utf82ascstr - Convert a UTF8STRING string to a regular C ASCII string. 2338 * This goes through an intermediate step with a ASN1_STRING type of 2339 * IA5STRING (International Alphabet 5, which is the same as ASCII). 2340 * 2341 * Arguments: 2342 * str - UTF8STRING to be converted. 2343 * 2344 * Returns: 2345 * == NULL - An error occurred. Error information (accessible by 2346 * ERR_get_error()) is set. 2347 * != NULL - Points to a NULL-termianted ASCII string. The caller must 2348 * free it. 2349 */ 2350 static uchar_t * 2351 utf82ascstr(ASN1_UTF8STRING *ustr) 2352 { 2353 ASN1_STRING tmpstr; 2354 ASN1_STRING *astr = &tmpstr; 2355 uchar_t *retstr = NULL; 2356 int mbflag; 2357 int ret; 2358 2359 if (ustr == NULL || ustr->type != V_ASN1_UTF8STRING) { 2360 SUNWerr(SUNW_F_UTF82ASCSTR, SUNW_R_INVALID_ARG); 2361 return (NULL); 2362 } 2363 2364 mbflag = MBSTRING_ASC; 2365 tmpstr.data = NULL; 2366 tmpstr.length = 0; 2367 2368 ret = ASN1_mbstring_copy(&astr, ustr->data, ustr->length, mbflag, 2369 B_ASN1_IA5STRING); 2370 if (ret < 0) { 2371 SUNWerr(SUNW_F_UTF82ASCSTR, SUNW_R_STR_CONVERT_ERR); 2372 return (NULL); 2373 } 2374 2375 retstr = OPENSSL_malloc(astr->length + 1); 2376 if (retstr == NULL) { 2377 SUNWerr(SUNW_F_UTF82ASCSTR, SUNW_R_MEMORY_FAILURE); 2378 return (NULL); 2379 } 2380 2381 (void) memcpy(retstr, astr->data, astr->length); 2382 retstr[astr->length] = '\0'; 2383 OPENSSL_free(astr->data); 2384 2385 return (retstr); 2386 } 2387 2388 2389 /* 2390 * type2attrib - Given a ASN1_TYPE, return a X509_ATTRIBUTE of the type 2391 * specified by the given NID. 2392 * 2393 * Arguments: 2394 * ty - Type structure to be made into an attribute 2395 * nid - NID of the attribute 2396 * 2397 * Returns: 2398 * NULL An error occurred. 2399 * != NULL An X509_ATTRIBUTE structure. 2400 */ 2401 X509_ATTRIBUTE * 2402 type2attrib(ASN1_TYPE *ty, int nid) 2403 { 2404 X509_ATTRIBUTE *a; 2405 2406 if ((a = X509_ATTRIBUTE_new()) == NULL || 2407 (a->value.set = sk_ASN1_TYPE_new_null()) == NULL || 2408 sk_ASN1_TYPE_push(a->value.set, ty) == 0) { 2409 if (a != NULL) 2410 X509_ATTRIBUTE_free(a); 2411 SUNWerr(SUNW_F_TYPE2ATTRIB, SUNW_R_MEMORY_FAILURE); 2412 return (NULL); 2413 } 2414 a->single = 0; 2415 a->object = OBJ_nid2obj(nid); 2416 2417 return (a); 2418 } 2419 2420 /* 2421 * attrib2type - Given a X509_ATTRIBUTE, return pointer to the ASN1_TYPE 2422 * component 2423 * 2424 * Arguments: 2425 * attr - Attribute structure containing a type. 2426 * 2427 * Returns: 2428 * NULL An error occurred. 2429 * != NULL An ASN1_TYPE structure. 2430 */ 2431 static ASN1_TYPE * 2432 attrib2type(X509_ATTRIBUTE *attr) 2433 { 2434 ASN1_TYPE *ty = NULL; 2435 2436 if (attr == NULL || attr->single == 1) 2437 return (NULL); 2438 2439 if (sk_ASN1_TYPE_num(attr->value.set) > 0) 2440 ty = sk_ASN1_TYPE_value(attr->value.set, 0); 2441 2442 return (ty); 2443 } 2444 2445 /* 2446 * find_attr_by_nid - Given a ASN1_TYPE, return the offset of a X509_ATTRIBUTE 2447 * of the type specified by the given NID. 2448 * 2449 * Arguments: 2450 * attrs - Stack of attributes to search 2451 * nid - NID of the attribute being searched for 2452 * 2453 * Returns: 2454 * -1 None found 2455 * != -1 Offset of the matching attribute. 2456 */ 2457 static int 2458 find_attr_by_nid(STACK_OF(X509_ATTRIBUTE) *attrs, int nid) 2459 { 2460 X509_ATTRIBUTE *a; 2461 int i; 2462 2463 if (attrs == NULL) 2464 return (-1); 2465 2466 for (i = 0; i < sk_X509_ATTRIBUTE_num(attrs); i++) { 2467 a = sk_X509_ATTRIBUTE_value(attrs, i); 2468 if (OBJ_obj2nid(a->object) == nid) 2469 return (i); 2470 } 2471 return (-1); 2472 } 2473 2474 /* 2475 * Called by our PKCS12 code to read our function and error codes 2476 * into memory so that the OpenSSL framework can retrieve them. 2477 */ 2478 void 2479 ERR_load_SUNW_strings(void) 2480 { 2481 assert(SUNW_lib_error_code == 0); 2482 #ifndef OPENSSL_NO_ERR 2483 /* 2484 * Have OpenSSL provide us with a unique ID. 2485 */ 2486 SUNW_lib_error_code = ERR_get_next_error_library(); 2487 2488 ERR_load_strings(SUNW_lib_error_code, SUNW_str_functs); 2489 ERR_load_strings(SUNW_lib_error_code, SUNW_str_reasons); 2490 2491 SUNW_lib_name->error = ERR_PACK(SUNW_lib_error_code, 0, 0); 2492 ERR_load_strings(0, SUNW_lib_name); 2493 #endif 2494 } 2495 2496 /* 2497 * The SUNWerr macro resolves to this routine. So when we need 2498 * to push an error, this routine does it for us. Notice that 2499 * the SUNWerr macro provides a filename and line #. 2500 */ 2501 void 2502 ERR_SUNW_error(int function, int reason, char *file, int line) 2503 { 2504 assert(SUNW_lib_error_code != 0); 2505 #ifndef OPENSSL_NO_ERR 2506 ERR_PUT_error(SUNW_lib_error_code, function, reason, file, line); 2507 #endif 2508 } 2509 2510 /* 2511 * check_time - Given an indication of the which time(s) to check, check 2512 * that time or those times against the current time and return the 2513 * relationship. 2514 * 2515 * Arguments: 2516 * chkwhat - What kind of check to do. 2517 * cert - The cert to check. 2518 * 2519 * Returns: 2520 * CHKERR_* values. 2521 */ 2522 static chk_errs_t 2523 check_time(chk_actions_t chkwhat, X509 *cert) 2524 { 2525 int i; 2526 2527 if (chkwhat == CHK_NOT_BEFORE || chkwhat == CHK_BOTH) { 2528 i = X509_cmp_time(X509_get_notBefore(cert), NULL); 2529 if (i == 0) 2530 return (CHKERR_TIME_BEFORE_BAD); 2531 if (i > 0) 2532 return (CHKERR_TIME_IS_BEFORE); 2533 2534 /* The current time is after the 'not before' time */ 2535 } 2536 2537 if (chkwhat == CHK_NOT_AFTER || chkwhat == CHK_BOTH) { 2538 i = X509_cmp_time(X509_get_notAfter(cert), NULL); 2539 if (i == 0) 2540 return (CHKERR_TIME_AFTER_BAD); 2541 if (i < 0) 2542 return (CHKERR_TIME_HAS_EXPIRED); 2543 } 2544 2545 return (CHKERR_TIME_OK); 2546 } 2547 2548 /* 2549 * find_attr - Look for a given attribute of the type associated with the NID. 2550 * 2551 * Arguments: 2552 * nid - NID for the attribute to be found (either NID_friendlyName or 2553 * NID_locakKeyId) 2554 * str - ASN1_STRING-type structure containing the value to be found, 2555 * FriendlyName expects a ASN1_BMPSTRING and localKeyID uses a 2556 * ASN1_STRING. 2557 * kl - Points to a stack of private keys. 2558 * pkey - Points at a location where the address of the matching private 2559 * key will be stored. 2560 * cl - Points to a stack of client certs with matching private keys. 2561 * cert - Points to locaiton where the address of the matching client cert 2562 * will be returned 2563 * 2564 * This function is designed to process lists of certs and private keys. 2565 * This is made complex because these the attributes are stored differently 2566 * for certs and for keys. For certs, only a few attributes are retained. 2567 * FriendlyName is stored in the aux structure, under the name 'alias'. 2568 * LocalKeyId is also stored in the aux structure, under the name 'keyid'. 2569 * A pkey structure has a stack of attributes. 2570 * 2571 * The basic approach is: 2572 * - If there there is no stack of certs but a stack of private keys exists, 2573 * search the stack of keys for a match. Alternately, if there is a stack 2574 * of certs and no private keys, search the certs. 2575 * 2576 * - If there are both certs and keys, assume that the matching certs and 2577 * keys are in their respective stacks, with matching entries in the same 2578 * order. Search for the name or keyid in the stack of certs. If it is 2579 * not found, then this function returns 0 (nothing found). 2580 * 2581 * - Once a cert is found, verify that the key actually matches by 2582 * comparing the private key with the public key (in the cert). 2583 * If they don't match, return an error. 2584 * 2585 * A pointer to cert and/or pkey which matches the name or keyid is stored 2586 * in the return arguments. 2587 * 2588 * Returns: 2589 * 0 - No matches were found. 2590 * > 0 - Bits set based on FOUND_* definitions, indicating what was found. 2591 * This can be FOUND_PKEY, FOUND_CERT or (FOUND_PKEY | FOUND_CERT). 2592 */ 2593 static int 2594 find_attr(int nid, ASN1_STRING *str, STACK_OF(EVP_PKEY) *kl, EVP_PKEY **pkey, 2595 STACK_OF(X509) *cl, X509 **cert) 2596 { 2597 ASN1_UTF8STRING *ustr = NULL; 2598 ASN1_STRING *s; 2599 ASN1_TYPE *t; 2600 EVP_PKEY *p; 2601 uchar_t *fname = NULL; 2602 X509 *x; 2603 int found = 0; 2604 int chkcerts; 2605 int len; 2606 int res; 2607 int c = -1; 2608 int k = -1; 2609 2610 chkcerts = (cert != NULL || pkey != NULL) && cl != NULL; 2611 if (chkcerts && nid == NID_friendlyName && 2612 str->type == V_ASN1_BMPSTRING) { 2613 ustr = ASN1_UTF8STRING_new(); 2614 if (ustr == NULL) { 2615 SUNWerr(SUNW_F_FINDATTR, SUNW_R_MEMORY_FAILURE); 2616 return (0); 2617 } 2618 len = ASN1_STRING_to_UTF8(&fname, str); 2619 if (fname == NULL) { 2620 ASN1_UTF8STRING_free(ustr); 2621 SUNWerr(SUNW_F_FINDATTR, SUNW_R_STR_CONVERT_ERR); 2622 return (0); 2623 } 2624 2625 if (ASN1_STRING_set(ustr, fname, len) == 0) { 2626 ASN1_UTF8STRING_free(ustr); 2627 OPENSSL_free(fname); 2628 SUNWerr(SUNW_F_FINDATTR, SUNW_R_MEMORY_FAILURE); 2629 return (0); 2630 } 2631 } 2632 2633 if (chkcerts) { 2634 for (c = 0; c < sk_X509_num(cl); c++) { 2635 res = -1; 2636 x = sk_X509_value(cl, c); 2637 if (nid == NID_friendlyName && ustr != NULL) { 2638 if (x->aux == NULL || x->aux->alias == NULL) 2639 continue; 2640 s = x->aux->alias; 2641 if (s != NULL && s->type == ustr->type && 2642 s->data != NULL) { 2643 res = ASN1_STRING_cmp(s, ustr); 2644 } 2645 } else { 2646 if (x->aux == NULL || x->aux->keyid == NULL) 2647 continue; 2648 s = x->aux->keyid; 2649 if (s != NULL && s->type == str->type && 2650 s->data != NULL) { 2651 res = ASN1_STRING_cmp(s, str); 2652 } 2653 } 2654 if (res == 0) { 2655 if (cert != NULL) 2656 *cert = sk_X509_delete(cl, c); 2657 found = FOUND_CERT; 2658 break; 2659 } 2660 } 2661 if (ustr != NULL) { 2662 ASN1_UTF8STRING_free(ustr); 2663 OPENSSL_free(fname); 2664 } 2665 } 2666 2667 if (pkey != NULL && kl != NULL) { 2668 /* 2669 * Looking for pkey to match a cert? If so, assume that 2670 * lists of certs and their matching pkeys are in the same 2671 * order. Call X509_check_private_key() to verify this 2672 * assumption. 2673 */ 2674 if (found != 0 && cert != NULL) { 2675 k = c; 2676 p = sk_EVP_PKEY_value(kl, k); 2677 if (X509_check_private_key(x, p) != 0) { 2678 if (pkey != NULL) 2679 *pkey = sk_EVP_PKEY_delete(kl, k); 2680 found |= FOUND_PKEY; 2681 } 2682 } else if (cert == NULL) { 2683 for (k = 0; k < sk_EVP_PKEY_num(kl); k++) { 2684 p = sk_EVP_PKEY_value(kl, k); 2685 if (p == NULL || p->attributes == NULL) 2686 continue; 2687 2688 t = PKCS12_get_attr_gen(p->attributes, nid); 2689 if (t != NULL || ASN1_STRING_cmp(str, 2690 t->value.asn1_string) == 0) 2691 continue; 2692 2693 found |= FOUND_PKEY; 2694 if (pkey != NULL) 2695 *pkey = sk_EVP_PKEY_delete(kl, k); 2696 break; 2697 } 2698 } 2699 } 2700 2701 return (found); 2702 } 2703 2704 /* 2705 * set_results - Given two pointers to stacks of private keys, certs or CA 2706 * CA certs, either copy the second stack to the first, or append the 2707 * contents of the second to the first. 2708 * 2709 * Arguments: 2710 * pkeys - Points to stack of pkeys 2711 * work_kl - Points to working stack of pkeys 2712 * certs - Points to stack of certs 2713 * work_cl - Points to working stack of certs 2714 * cacerts - Points to stack of CA certs 2715 * work_ca - Points to working stack of CA certs 2716 * xtrakeys - Points to stack of unmatcned pkeys 2717 * work_xl - Points to working stack of unmatcned pkeys 2718 * 2719 * The arguments are in pairs. The first of each pair points to a stack 2720 * of keys or certs. The second of the pair points at a 'working stack' 2721 * of the same type of entities. Actions taken are as follows: 2722 * 2723 * - If either the first or second argument is NULL, or if there are no 2724 * members in the second stack, there is nothing to do. 2725 * - If the first argument points to a pointer which is NULL, then there 2726 * is no existing stack for the first argument. Copy the stack pointer 2727 * from the second argument to the first argument and NULL out the stack 2728 * pointer for the second. 2729 * - Otherwise, go through the elements of the second stack, removing each 2730 * and adding it to the first stack. 2731 * 2732 * Returns: 2733 * == -1 - An error occurred. Call ERR_get_error() to get error information. 2734 * == 0 - No matching returns were found. 2735 * > 0 - This is the arithmetic 'or' of the FOUND_* bits that indicate which 2736 * of the requested entries were manipulated. 2737 */ 2738 static int 2739 set_results(STACK_OF(EVP_PKEY) **pkeys, STACK_OF(EVP_PKEY) **work_kl, 2740 STACK_OF(X509) **certs, STACK_OF(X509) **work_cl, 2741 STACK_OF(X509) **cacerts, STACK_OF(X509) **work_ca, 2742 STACK_OF(EVP_PKEY) **xtrakeys, STACK_OF(EVP_PKEY) **work_xl) 2743 { 2744 int retval = 0; 2745 2746 if (pkeys != NULL && work_kl != NULL && *work_kl != NULL && 2747 sk_EVP_PKEY_num(*work_kl) > 0) { 2748 if (*pkeys == NULL) { 2749 *pkeys = *work_kl; 2750 *work_kl = NULL; 2751 } else { 2752 if (sunw_append_keys(*pkeys, *work_kl) < 0) { 2753 return (-1); 2754 } 2755 } 2756 retval |= FOUND_PKEY; 2757 } 2758 if (certs != NULL && work_cl != NULL && *work_cl != NULL && 2759 sk_X509_num(*work_cl) > 0) { 2760 if (*certs == NULL) { 2761 *certs = *work_cl; 2762 *work_cl = NULL; 2763 } else { 2764 if (move_certs(*certs, *work_cl) < 0) { 2765 return (-1); 2766 } 2767 } 2768 retval |= FOUND_CERT; 2769 } 2770 2771 if (cacerts != NULL && work_ca != NULL && *work_ca != NULL && 2772 sk_X509_num(*work_ca) > 0) { 2773 if (*cacerts == NULL) { 2774 *cacerts = *work_ca; 2775 *work_ca = NULL; 2776 } else { 2777 if (move_certs(*cacerts, *work_ca) < 0) { 2778 return (-1); 2779 } 2780 } 2781 retval |= FOUND_CA_CERTS; 2782 } 2783 2784 if (xtrakeys != NULL && work_xl != NULL && *work_xl != NULL && 2785 sk_EVP_PKEY_num(*work_xl) > 0) { 2786 if (*xtrakeys == NULL) { 2787 *xtrakeys = *work_xl; 2788 *work_xl = NULL; 2789 } else { 2790 if (sunw_append_keys(*xtrakeys, *work_xl) < 0) { 2791 return (-1); 2792 } 2793 } 2794 retval |= FOUND_XPKEY; 2795 } 2796 2797 return (retval); 2798 } 2799