PKCS12err(PKCS12_F_PARSE_BAGS,ERR_R_MALLOC_FAILURE);
PKCS12err(PKCS12_F_PARSE_BAG,ERR_R_MALLOC_FAILURE);
static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,		      EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca,		      ASN1_OCTET_STRING **keyid,	     char *keymatch){	PKCS8_PRIV_KEY_INFO *p8;	X509 *x509;	ASN1_OCTET_STRING *lkey = NULL, *ckid = NULL;	ASN1_TYPE *attrib;	ASN1_BMPSTRING *fname = NULL;	if ((attrib = PKCS12_get_attr (bag, NID_friendlyName)))		fname = attrib->value.bmpstring;	if ((attrib = PKCS12_get_attr (bag, NID_localKeyID))) {		lkey = attrib->value.octet_string;		ckid = lkey;	}	/* Check for any local key id matching (if needed) */	if (lkey && ((*keymatch & MATCH_ALL) != MATCH_ALL)) {		if (*keyid) {			if (M_ASN1_OCTET_STRING_cmp(*keyid, lkey)) lkey = NULL;		} else {			if (!(*keyid = M_ASN1_OCTET_STRING_dup(lkey))) {				PKCS12err(PKCS12_F_PARSE_BAGS,ERR_R_MALLOC_FAILURE);				return 0;		    }		}	}		switch (M_PKCS12_bag_type(bag))	{	case NID_keyBag:		if (!lkey || !pkey) return 1;			if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag))) return 0;		*keymatch |= MATCH_KEY;	break;	case NID_pkcs8ShroudedKeyBag:		if (!lkey || !pkey) return 1;			if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen)))				return 0;		*pkey = EVP_PKCS82PKEY(p8);		PKCS8_PRIV_KEY_INFO_free(p8);		if (!(*pkey)) return 0;		*keymatch |= MATCH_KEY;	break;	case NID_certBag:		if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate )								 return 1;		if (!(x509 = PKCS12_certbag2x509(bag))) return 0;		if(ckid)			{			if (!X509_keyid_set1(x509, ckid->data, ckid->length))				{				X509_free(x509);				return 0;				}			}		if(fname) {			int len, r;			unsigned char *data;			len = ASN1_STRING_to_UTF8(&data, fname);			if(len > 0) {				r = X509_alias_set1(x509, data, len);				OPENSSL_free(data);				if (!r)					{					X509_free(x509);					return 0;					}			}		}		if (lkey) {			*keymatch |= MATCH_CERT;			if (cert) *cert = x509;			else X509_free(x509);		} else {			if(ca) sk_X509_push (*ca, x509);			else X509_free(x509);		}	break;	case NID_safeContentsBag:		return parse_bags(bag->value.safes, pass, passlen,			 		pkey, cert, ca, keyid, keymatch);	break;	default:		return 1;	break;	}	return 1;}