8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / common / net / wanboot / p12auxpars.c
blob2ce0836fed89132fb735e4a31b40e273338871df
1 /*
2 * ====================================================================
3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
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.
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/)"
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.
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.
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/)"
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 * ====================================================================
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).
57 * Copyright 2002, 2003 Sun Microsystems, Inc. All rights reserved.
58 * Use is subject to license terms.
61 #pragma ident "%Z%%M% %I% %E% SMI"
63 #include <stdio.h>
64 #include <strings.h>
65 #include <stdlib.h>
67 #include <openssl/crypto.h>
68 #include <openssl/err.h>
69 #include <openssl/x509.h>
71 #include <openssl/pkcs12.h>
72 #include <p12aux.h>
73 #include <auxutil.h>
74 #include <p12err.h>
77 * Briefly, a note on the APIs provided by this module.
79 * The sunw_PKCS_parse, parse_pkcs12 and sunw_PKCS12_contents APIs
80 * replace OpenSSL funcionality provided by PKCS12_parse and its
81 * supporting routines.
83 * The APIs provided here provide more functionality:
85 * - sunw_PKCS12_parse provides:
87 * earlier MAC processing than PKCS12_parse
89 * treats the handling of the difference between CA certs and certs
90 * with matching private keys differently that PKCS12_parse does. In
91 * PKCS12_parse, any cert which is not the one selected is assumed to be
92 * a CA cert. In parse_pkcs12, certs which have matching private keys are
93 * not returned as part of the CA certs.
95 * the matching of private keys and certs is done at this level, rather than
96 * at the lower levels which were used in the openssl implementation. This
97 * is part of the changes introduced so that the parsing functions can
98 * return just a cert, just a private key, the stack of CA certs or any
99 * combination.
101 * added DO_FIRST_PAIR, DO_LAST_PAIR and DO_UNMATCHING matchty support.
103 * do a much better job of cleaning up. Specifically, free the added
104 * attributes on the private key which was done by calling
105 * sunw_evp_pkey_free().
107 * in sunw_PKCS12_contents, handle allocation of the stacks of certificates
108 * and private keys so that a) the original stacks are not changed unless
109 * the parsing was successful; b) it will either extend stacks passed in,
110 * or allocate new ones if none were supplied.
112 * - for parse_outer vs. parse_pk12() (from the openssl source base):
114 * this calls lower levels with stacks of private keys and certs, rather
115 * that a cert, a private key and a stack for CA certs.
117 * - In the case of parse_all_bags vs. parse_bags, there is no real difference,
118 * other than use of stacks of private keys and certificates (as opposed
119 * to one cert, one private key and a stack of CA certificates).
121 * - Finally, for parse_one_bag vs. parse_bag:
123 * got rid of the bugs the openssl matching of keys and certificates.
125 * got rid of the requirement that there is one private key and a matching
126 * cert somewhere in the input. This was done by moving the matching
127 * code to a higher level.
129 * put any localKeyID and/or friendlyName attributes found in the structures
130 * returned, so that they can be used at higher levels for searching, etc.
132 * added some error returns (like an error when there is an unsupported
133 * bag type, an unsupported certificate type or an unsupported key type)
135 * Added cleanup before returning.
138 static int parse_pkcs12(PKCS12 *, const char *, int, char *, int, char *,
139 EVP_PKEY **, X509 **, STACK_OF(X509) **);
141 static int parse_outer(PKCS12 *, const char *, STACK_OF(EVP_PKEY) *,
142 STACK_OF(X509) *);
144 static int parse_all_bags(STACK_OF(PKCS12_SAFEBAG) *, const char *,
145 STACK_OF(EVP_PKEY) *, STACK_OF(X509) *);
147 static int parse_one_bag(PKCS12_SAFEBAG *, const char *, STACK_OF(EVP_PKEY) *,
148 STACK_OF(X509) *);
150 static int sunw_PKCS12_contents(PKCS12 *p12, const char *pass,
151 STACK_OF(EVP_PKEY) **pkey, STACK_OF(X509) **certs);
154 * sunw_PKCS12_parse - Parse a PKCS12 structure and break it into its parts.
156 * Parse and decrypt a PKCS#12 structure returning user key, user cert and/or
157 * other (CA) certs. Note either ca should be NULL, *ca should be NULL,
158 * or it should point to a valid STACK_OF(X509) structure. pkey and cert can
159 * be passed uninitialized.
161 * Arguments:
162 * p12 - Structure with pkcs12 info to be parsed
163 * pass - Pass phrase for the private key (possibly empty) or NULL if
164 * there is none.
165 * matchty - Info about which certs/keys to return if many are in the file.
166 * keyid - If private key localkeyids friendlynames are to match a
167 * predetermined value, the value to match. This value should
168 * be an octet string.
169 * keyid_len- Length of the keyid byte string.
170 * name_str - If friendlynames are to match a predetermined value, the value
171 * to match. This value should be a NULL terminated string.
172 * pkey - Points to location pointing to the private key returned.
173 * cert - Points to locaiton which points to the client cert returned
174 * ca - Points to location that points to a stack of 'certificate
175 * authority' certs/trust anchors.
177 * Match based on the value of 'matchty' and the contents of 'keyid'
178 * and/or 'name_str', as appropriate. Go through the lists of certs and
179 * private keys which were taken from the pkcs12 structure, looking for
180 * matches of the requested type. This function only searches the lists of
181 * matching private keys and client certificates. Kinds of matches allowed,
182 * and the order in which they will be checked, are:
184 * 1) Find the key and/or cert whose localkeyid attributes matches
185 * 'keyid'.
186 * 2) Find the key and/or cert whose friendlyname attributes matches
187 * 'name_str'
188 * 3) Return the first matching key/cert pair found.
189 * 4) Return the last matching key/cert pair found.
190 * 5) Return whatever cert and/or key are available, even unmatching.
192 * Append to the CA list, the certs which do not have matching private
193 * keys and which were not selected.
195 * If none of the bits are set, no client certs or private keys will be
196 * returned. CA (aka trust anchor) certs can be.
198 * Notes: If #3 is selected, then #4 will never occur. CA certs will be
199 * selected after a cert/key pairs are isolated.
201 * Returns:
202 * < 0 - An error returned. Call ERR_get_error() to get errors information.
203 * Where possible, memory has been freed.
204 * >= 0 - Objects were found and returned. Which objects are indicated by
205 * which bits are set (FOUND_PKEY, FOUND_CERT, FOUND_CA_CERTS).
208 sunw_PKCS12_parse(PKCS12 *p12, const char *pass, int matchty, char *keyid,
209 int keyid_len, char *name_str, EVP_PKEY **pkey, X509 **cert,
210 STACK_OF(X509) **ca)
212 boolean_t ca_supplied;
213 int retval = -1;
215 /* If NULL PKCS12 structure, this is an error */
216 if (p12 == NULL) {
217 SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_INVALID_ARG);
218 return (-1);
221 /* Set up arguments.... These will be allocated if needed */
222 if (pkey)
223 *pkey = NULL;
224 if (cert)
225 *cert = NULL;
228 * If there is already a ca list, use it. Otherwise, allocate one
229 * and free is later if an error occurs or whatever.)
231 ca_supplied = (ca != NULL && *ca != NULL);
232 if (ca != NULL && *ca == NULL) {
233 if ((*ca = sk_X509_new_null()) == NULL) {
234 SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_MEMORY_FAILURE);
235 return (-1);
240 * If password is zero length or NULL then try verifying both cases
241 * to determine which password is correct. The reason for this is that
242 * under PKCS#12 password based encryption no password and a zero
243 * length password are two different things. If the password has a
244 * non-zero length and is not NULL then call PKCS12_verify_mac() with
245 * a length of '-1' and let it use strlen() to figure out the length
246 * of the password.
248 /* Check the mac */
249 if (pass == NULL || *pass == '\0') {
250 if (PKCS12_verify_mac(p12, NULL, 0))
251 pass = NULL;
252 else if (PKCS12_verify_mac(p12, "", 0))
253 pass = "";
254 else {
255 SUNWerr(SUNW_F_PKCS12_PARSE,
256 SUNW_R_MAC_VERIFY_FAILURE);
257 goto err;
259 } else if (PKCS12_verify_mac(p12, pass, -1) == 0) {
260 SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_MAC_VERIFY_FAILURE);
261 goto err;
264 retval = parse_pkcs12(p12, pass, matchty, keyid, keyid_len,
265 name_str, pkey, cert, ca);
266 if (retval < 0) {
267 SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_PKCS12_PARSE_ERR);
268 goto err;
270 return (retval);
272 err:
273 if (pkey && *pkey) {
274 sunw_evp_pkey_free(*pkey);
276 if (cert && *cert)
277 X509_free(*cert);
278 if (ca_supplied == B_FALSE && ca != NULL)
279 sk_X509_pop_free(*ca, X509_free);
281 return (-1);
286 * parse_pkcs12 - Oversee parsing of the pkcs12 structure. Get it
287 * parsed. After that either return what's found directly, or
288 * do any required matching.
290 * Arguments:
291 * p12 - Structure with pkcs12 info to be parsed
292 * pass - Pass phrase for the private key (possibly empty) or NULL if
293 * there is none.
294 * matchty - Info about which certs/keys to return if many are in the file.
295 * keyid - If private key localkeyids friendlynames are to match a
296 * predetermined value, the value to match. This value should
297 * be an octet string.
298 * keyid_len- Length of the keyid byte string.
299 * name_str - If friendlynames are to match a predetermined value, the value
300 * to match. This value should be a NULL terminated string.
301 * pkey - Points to location pointing to the private key returned.
302 * cert - Points to locaiton which points to the client cert returned
303 * ca - Points to location that points to a stack of 'certificate
304 * authority' certs/trust anchors.
306 * Note about error codes: This function is an internal function, and the
307 * place where it is called sets error codes. Therefore only set an error
308 * code if it is something that is unique or if the function which detected
309 * the error doesn't set one.
311 * Returns:
312 * == -1 - An error occurred. Call ERR_get_error() to get error information.
313 * Where possible, memory has been freed.
314 * == 0 - No matching returns were found.
315 * > 0 - This is the aithmetic 'or' of the FOUND_* bits that indicate which
316 * of the requested entries were found.
318 static int
319 parse_pkcs12(PKCS12 *p12, const char *pass, int matchty, char *keyid,
320 int kstr_len, char *name_str, EVP_PKEY **pkey, X509 **cert,
321 STACK_OF(X509) **ca)
323 STACK_OF(EVP_PKEY) *work_kl = NULL; /* Head for private key list */
324 STACK_OF(EVP_PKEY) *nocerts = NULL; /* Head for alt. key list */
325 STACK_OF(X509) *work_ca = NULL; /* Head for cert list */
326 STACK_OF(X509) *work_cl = NULL;
327 int retval = 0;
328 int n;
330 retval = sunw_PKCS12_contents(p12, pass, &work_kl, &work_ca);
331 if (retval < 0) {
332 goto cleanup;
333 } else if (retval == 0) {
335 * Not really an error here - its just that nothing was found.
337 goto cleanup;
340 if (sk_EVP_PKEY_num(work_kl) > 0) {
342 if (sunw_split_certs(work_kl, work_ca, &work_cl, &nocerts)
343 < 0) {
344 goto cleanup;
349 * Go through the lists of certs and private keys which were
350 * returned, looking for matches of the appropriate type. Do these
351 * in the order described above.
353 if ((matchty & DO_FIND_KEYID) != 0) {
355 if (keyid == NULL) {
356 SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_INVALID_ARG);
357 retval = -1;
358 goto cleanup;
361 /* See if string matches localkeyid's */
362 retval = sunw_find_localkeyid(keyid, kstr_len,
363 work_kl, work_cl, pkey, cert);
364 if (retval != 0) {
365 if (retval == -1)
366 goto cleanup;
367 else
368 goto last_part;
371 if ((matchty & DO_FIND_FN) != 0) {
373 if (name_str == NULL) {
374 SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_INVALID_ARG);
375 retval = -1;
376 goto cleanup;
379 /* See if string matches friendly names */
380 retval = sunw_find_fname(name_str, work_kl, work_cl,
381 pkey, cert);
382 if (retval != 0) {
383 if (retval == -1)
384 goto cleanup;
385 else
386 goto last_part;
390 if (matchty & DO_FIRST_PAIR) {
392 /* Find the first cert and private key and return them */
393 retval = get_key_cert(0, work_kl, pkey, work_cl, cert);
394 if (retval != 0) {
395 if (retval == -1)
396 goto cleanup;
397 else
398 goto last_part;
402 if (matchty & DO_LAST_PAIR) {
405 * Find the last matching cert and private key and return
406 * them. Since keys which don't have matching client certs
407 * are at the end of the list of keys, use the number of
408 * client certs to compute the position of the last private
409 * key which matches a client cert.
411 n = sk_X509_num(work_cl) - 1;
412 retval = get_key_cert(n, work_kl, pkey, work_cl, cert);
413 if (retval != 0) {
414 if (retval == -1)
415 goto cleanup;
416 else
417 goto last_part;
421 if (matchty & DO_UNMATCHING) {
422 STACK_OF(EVP_PKEY) *tmpk;
423 STACK_OF(X509) *tmpc;
425 /* Find the first cert and private key and return them */
426 tmpc = work_cl;
427 if (work_cl == NULL || sk_X509_num(work_cl) == 0)
428 tmpc = work_ca;
429 tmpk = work_kl;
430 if (work_kl == NULL || sk_EVP_PKEY_num(work_kl) == 0)
431 tmpk = nocerts;
432 retval = get_key_cert(0, tmpk, pkey, tmpc, cert);
433 if (retval != 0) {
434 if (retval == -1)
435 goto cleanup;
436 else
437 goto last_part;
441 last_part:
442 /* If no errors, terminate normally */
443 if (retval != -1)
444 retval |= set_results(NULL, NULL, NULL, NULL, ca, &work_ca,
445 NULL, NULL);
446 if (retval >= 0) {
447 goto clean_part;
450 /* Fallthrough is intentional in error cases. */
451 cleanup:
452 if (pkey != NULL && *pkey != NULL) {
453 sunw_evp_pkey_free(*pkey);
454 *pkey = NULL;
456 if (cert != NULL && *cert != NULL) {
457 X509_free(*cert);
458 *cert = NULL;
461 clean_part:
463 if (work_kl != NULL) {
464 sk_EVP_PKEY_pop_free(work_kl, sunw_evp_pkey_free);
466 if (work_ca != NULL)
467 sk_X509_pop_free(work_ca, X509_free);
468 if (work_cl != NULL)
469 sk_X509_pop_free(work_cl, X509_free);
471 return (retval);
475 * sunw_PKCS12_contents() parses a pkcs#12 structure and returns component
476 * parts found, without evaluation.
478 * Parse and decrypt a PKCS#12 structure returning any user keys and/or
479 * various certs. Note these should either be NULL, *whatever should
480 * be NULL, or it should point to a valid STACK_OF(X509) structure.
482 * Arguments:
483 * p12 - Structure with pkcs12 info to be parsed
484 * pass - Pass phrase for the private key and entire pkcs12 wad (possibly
485 * empty) or NULL if there is none.
486 * pkeys - Points to address of a stack of private keys to return.
487 * certs - Points to address of a stack of client certs return.
489 * Note: The certs and keys being returned are in random order.
491 * Returns:
492 * < 0 - An error returned. Call ERR_get_error() to get errors information.
493 * Where possible, memory has been freed.
494 * >= 0 - Objects were found and returned. Which objects are indicated by
495 * which bits are set (FOUND_PKEY or FOUND_CERT)
497 static int
498 sunw_PKCS12_contents(PKCS12 *p12, const char *pass, STACK_OF(EVP_PKEY) **pkey,
499 STACK_OF(X509) **certs)
501 STACK_OF(EVP_PKEY) *work_kl = NULL;
502 STACK_OF(X509) *work_ca = NULL;
503 int retval = -1;
506 * Allocate the working stacks for private key and for the
507 * ca certs.
509 if ((work_kl = sk_EVP_PKEY_new_null()) == NULL) {
510 SUNWerr(SUNW_F_PKCS12_CONTENTS, SUNW_R_MEMORY_FAILURE);
511 goto cleanup;
514 if ((work_ca = sk_X509_new_null()) == NULL) {
515 SUNWerr(SUNW_F_PKCS12_CONTENTS, SUNW_R_MEMORY_FAILURE);
516 goto cleanup;
519 if (parse_outer(p12, pass, work_kl, work_ca) == 0) {
521 * Error already on stack
523 goto cleanup;
526 /* on error, set_results() returns an error on the stack */
527 retval = set_results(pkey, &work_kl, certs, &work_ca, NULL,
528 NULL, NULL, NULL);
530 cleanup:
531 if (work_kl != NULL) {
532 sk_EVP_PKEY_pop_free(work_kl, sunw_evp_pkey_free);
535 return (retval);
539 * parse_outer - Unpack the outer PKCS#12 structure and go through the
540 * individual bags. Return stacks of certs, private keys found and
541 * CA certs found.
543 * Note about error codes: This function is an internal function, and the
544 * place where it is called sets error codes.
546 * Returns:
547 * 0 - An error returned. Call ERR_get_error() to get errors information.
548 * Where possible, memory has been freed.
549 * 1 - PKCS12 data object was parsed and lists of certs and private keys
550 * were returned.
552 static int
553 parse_outer(PKCS12 *p12, const char *pass, STACK_OF(EVP_PKEY) *kl,
554 STACK_OF(X509) *cl)
556 STACK_OF(PKCS12_SAFEBAG) *bags;
557 STACK_OF(PKCS7) *asafes;
558 int i, bagnid;
559 PKCS7 *p7;
561 if ((asafes = M_PKCS12_unpack_authsafes(p12)) == NULL)
562 return (0);
564 for (i = 0; i < sk_PKCS7_num(asafes); i++) {
565 p7 = sk_PKCS7_value(asafes, i);
566 bagnid = OBJ_obj2nid(p7->type);
567 if (bagnid == NID_pkcs7_data) {
568 bags = M_PKCS12_unpack_p7data(p7);
569 } else if (bagnid == NID_pkcs7_encrypted) {
571 * A length of '-1' means strlen() can be used
572 * to determine the password length.
574 bags = M_PKCS12_unpack_p7encdata(p7, pass, -1);
575 } else {
576 SUNWerr(SUNW_F_PARSE_OUTER, SUNW_R_BAD_BAGTYPE);
577 return (0);
580 if (bags == NULL) {
581 SUNWerr(SUNW_F_PARSE_OUTER, SUNW_R_PARSE_BAG_ERR);
582 sk_PKCS7_pop_free(asafes, PKCS7_free);
583 return (0);
585 if (parse_all_bags(bags, pass, kl, cl) == 0) {
586 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
587 sk_PKCS7_pop_free(asafes, PKCS7_free);
588 return (0);
592 return (1);
596 * parse_all_bags - go through the stack of bags, parsing each.
598 * Note about error codes: This function is an internal function, and the
599 * place where it is called sets error codes.
601 * Returns:
602 * 0 - An error returned. Call ERR_get_error() to get errors information.
603 * Where possible, memory has been freed.
604 * 1 - Stack of safebags was parsed and lists of certs and private keys
605 * were returned.
607 static int
608 parse_all_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
609 STACK_OF(EVP_PKEY) *kl, STACK_OF(X509) *cl)
611 int i;
612 for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
613 if (parse_one_bag(sk_PKCS12_SAFEBAG_value(bags, i),
614 pass, kl, cl) == 0)
615 return (0);
617 return (1);
621 * parse_one_bag - Parse an individual bag
623 * i = parse_one_bag(bag, pass, kl, cl);
625 * Arguments:
626 * bag - pkcs12 safebag to parse.
627 * pass - password for use in decryption of shrouded keybag
628 * kl - Stack of private keys found so far. New private keys will
629 * be added here if found.
630 * cl - Stack of certs found so far. New certificates will be
631 * added here if found.
633 * Returns:
634 * 0 - An error returned. Call ERR_get_error() to get errors information.
635 * Where possible, memory has been freed.
636 * 1 - one safebag was parsed. If it contained a cert or private key, it
637 * was added to the stack of certs or private keys found, respectively.
638 * localKeyId or friendlyName attributes are returned with the
639 * private key or certificate.
641 static int
642 parse_one_bag(PKCS12_SAFEBAG *bag, const char *pass, STACK_OF(EVP_PKEY) *kl,
643 STACK_OF(X509) *cl)
645 X509_ATTRIBUTE *attr = NULL;
646 ASN1_TYPE *keyid = NULL;
647 ASN1_TYPE *fname = NULL;
648 PKCS8_PRIV_KEY_INFO *p8;
649 EVP_PKEY *pkey = NULL;
650 X509 *x509 = NULL;
651 uchar_t *data = NULL;
652 char *str = NULL;
653 int retval = 1;
655 keyid = PKCS12_get_attr(bag, NID_localKeyID);
656 fname = PKCS12_get_attr(bag, NID_friendlyName);
658 switch (M_PKCS12_bag_type(bag)) {
659 case NID_keyBag:
660 if ((pkey = EVP_PKCS82PKEY(bag->value.keybag)) == NULL) {
661 SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_PARSE_BAG_ERR);
662 retval = 0;
663 break;
665 break;
667 case NID_pkcs8ShroudedKeyBag:
669 * A length of '-1' means strlen() can be used
670 * to determine the password length.
672 if ((p8 = M_PKCS12_decrypt_skey(bag, pass, -1)) == NULL) {
673 SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_PARSE_BAG_ERR);
674 retval = 0;
675 break;
677 pkey = EVP_PKCS82PKEY(p8);
678 PKCS8_PRIV_KEY_INFO_free(p8);
679 if (pkey == NULL) {
680 SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_PARSE_BAG_ERR);
681 retval = 0;
683 break;
685 case NID_certBag:
686 if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) {
687 SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_BAD_CERTTYPE);
688 break;
690 if ((x509 = M_PKCS12_certbag2x509(bag)) == NULL) {
691 SUNWerr(SUNW_F_PARSE_ONE_BAG,
692 SUNW_R_PARSE_CERT_ERR);
693 retval = 0;
694 break;
697 if (keyid != NULL) {
698 if (keyid->type != V_ASN1_OCTET_STRING) {
699 SUNWerr(SUNW_F_PARSE_ONE_BAG,
700 SUNW_R_BAD_LKID);
701 retval = 0;
702 break;
704 if (X509_keyid_set1(x509,
705 keyid->value.octet_string->data,
706 keyid->value.octet_string->length) == 0) {
707 SUNWerr(SUNW_F_PARSE_ONE_BAG,
708 SUNW_R_SET_LKID_ERR);
709 retval = 0;
710 break;
714 if (fname != NULL) {
715 ASN1_STRING *tmpstr = NULL;
716 int len;
718 if (fname->type != V_ASN1_BMPSTRING) {
719 SUNWerr(SUNW_F_PARSE_ONE_BAG,
720 SUNW_R_BAD_FNAME);
721 retval = 0;
722 break;
725 tmpstr = fname->value.asn1_string;
726 len = ASN1_STRING_to_UTF8(&data, tmpstr);
727 if (len < 0) {
728 SUNWerr(SUNW_F_PARSE_ONE_BAG,
729 SUNW_R_SET_FNAME_ERR);
730 retval = 0;
731 break;
734 if (X509_alias_set1(x509, data, len) == 0) {
735 SUNWerr(SUNW_F_PARSE_ONE_BAG,
736 SUNW_R_SET_FNAME_ERR);
737 retval = 0;
738 break;
742 if (sk_X509_push(cl, x509) == 0) {
743 SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_MEMORY_FAILURE);
744 retval = 0;
745 break;
747 x509 = NULL;
748 break;
750 case NID_safeContentsBag:
751 if (keyid != NULL)
752 ASN1_TYPE_free(keyid);
753 if (fname != NULL)
754 ASN1_TYPE_free(fname);
755 if (parse_all_bags(bag->value.safes, pass, kl, cl) == 0) {
757 * Error already on stack
759 return (0);
761 return (1);
763 default:
764 if (keyid != NULL)
765 ASN1_TYPE_free(keyid);
766 if (fname != NULL)
767 ASN1_TYPE_free(fname);
768 SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_BAD_BAGTYPE);
769 return (0);
773 if (pkey != NULL) {
774 if (retval != 0 && (keyid != NULL || fname != NULL) &&
775 pkey->attributes == NULL) {
776 pkey->attributes = sk_X509_ATTRIBUTE_new_null();
777 if (pkey->attributes == NULL) {
778 SUNWerr(SUNW_F_PARSE_ONE_BAG,
779 SUNW_R_MEMORY_FAILURE);
780 retval = 0;
784 if (retval != 0 && keyid != NULL) {
785 attr = type2attrib(keyid, NID_localKeyID);
786 if (attr == NULL)
788 * Error already on stack
790 retval = 0;
791 else {
792 keyid = NULL;
793 if (sk_X509_ATTRIBUTE_push(pkey->attributes,
794 attr) == 0) {
795 SUNWerr(SUNW_F_PARSE_ONE_BAG,
796 SUNW_R_MEMORY_FAILURE);
797 retval = 0;
798 } else {
799 attr = NULL;
804 if (retval != 0 && fname != NULL) {
805 attr = type2attrib(fname, NID_friendlyName);
806 if (attr == NULL) {
808 * Error already on stack
810 retval = 0;
811 } else {
812 fname = NULL;
813 if (sk_X509_ATTRIBUTE_push(pkey->attributes,
814 attr) == 0) {
815 SUNWerr(SUNW_F_PARSE_ONE_BAG,
816 SUNW_R_MEMORY_FAILURE);
817 retval = 0;
818 } else {
819 attr = NULL;
824 /* Save the private key */
825 if (retval != 0) {
826 if (sk_EVP_PKEY_push(kl, pkey) == 0) {
827 SUNWerr(SUNW_F_PARSE_ONE_BAG,
828 SUNW_R_MEMORY_FAILURE);
829 retval = 0;
830 } else {
831 pkey = NULL;
836 if (pkey != NULL) {
837 sunw_evp_pkey_free(pkey);
840 if (x509 != NULL)
841 X509_free(x509);
843 if (keyid != NULL)
844 ASN1_TYPE_free(keyid);
846 if (fname != NULL)
847 ASN1_TYPE_free(fname);
849 if (attr != NULL)
850 X509_ATTRIBUTE_free(attr);
852 if (data != NULL)
853 OPENSSL_free(data);
855 if (str != NULL)
856 OPENSSL_free(str);
858 return (retval);