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