PK11Context *pk11cx;
PK11Context *pk11cx = NULL;
sec_pkcs12_decoder_verify_mac(SEC_PKCS12DecoderContext *p12dcx){    SECStatus rv = SECFailure;    SECItem hmacRes;    unsigned char buf[IN_BUF_LEN];    unsigned int bufLen;    int iteration;    PK11Context *pk11cx;    SECItem ignore = {0};    PK11SymKey *symKey;    SECItem *params;    SECOidTag algtag;    CK_MECHANISM_TYPE integrityMech;        if(!p12dcx || p12dcx->error) {	return SECFailure;    }    /* generate hmac key */    if(p12dcx->macData.iter.data) {	iteration = (int)DER_GetInteger(&p12dcx->macData.iter);    } else {	iteration = 1;    }    params = PK11_CreatePBEParams(&p12dcx->macData.macSalt, p12dcx->pwitem,                                  iteration);    algtag = SECOID_GetAlgorithmTag(&p12dcx->macData.safeMac.digestAlgorithm);    switch (algtag) {    case SEC_OID_SHA1:	integrityMech = CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN; break;    case SEC_OID_MD5:	integrityMech = CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN;  break;    case SEC_OID_MD2:	integrityMech = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN;  break;    default:	goto loser;    }    symKey = PK11_KeyGen(NULL, integrityMech, params, 20, NULL);    PK11_DestroyPBEParams(params);    if (!symKey) goto loser;    /* init hmac */    pk11cx = PK11_CreateContextBySymKey(sec_pkcs12_algtag_to_mech(algtag),                                        CKA_SIGN, symKey, &ignore);    if(!pk11cx) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	return SECFailure;    }    rv = PK11_DigestBegin(pk11cx);    /* try to open the data for readback */    if(p12dcx->dOpen && ((*p12dcx->dOpen)(p12dcx->dArg, PR_TRUE) 			!= SECSuccess)) {	goto loser;    }    /* read the data back IN_BUF_LEN bytes at a time and recompute     * the hmac.  if fewer bytes are read than are requested, it is     * assumed that the end of file has been reached. if bytesRead     * is returned as -1, then an error occured reading from the      * file.     */    while(1) {	int bytesRead = (*p12dcx->dRead)(p12dcx->dArg, buf, IN_BUF_LEN);	if(bytesRead == -1) {	    goto loser;	}	rv = PK11_DigestOp(pk11cx, buf, bytesRead);	if(bytesRead < IN_BUF_LEN) {	    break;	}    }    /* finish the hmac context */    rv = PK11_DigestFinal(pk11cx, buf, &bufLen, IN_BUF_LEN);    hmacRes.data = buf;    hmacRes.len = bufLen;    /* is the hmac computed the same as the hmac which was decoded? */    rv = SECSuccess;    if(SECITEM_CompareItem(&hmacRes, &p12dcx->macData.safeMac.digest) 			!= SECEqual) {	PORT_SetError(SEC_ERROR_PKCS12_INVALID_MAC);	rv = SECFailure;    }loser:    /* close the file and remove it */    if(p12dcx->dClose) {	(*p12dcx->dClose)(p12dcx->dArg, PR_TRUE);    }    if(pk11cx) {	PK11_DestroyContext(pk11cx, PR_TRUE);    }    return rv;}