PORT_SetError(SEC_ERROR_PKCS12_UNABLE_TO_READ);
PORT_SetError(SEC_ERROR_INPUT_LEN);
sec_pkcs12_decoder_verify_mac(SEC_PKCS12DecoderContext *p12dcx){    PK11Context *     pk11cx = NULL;    PK11SymKey *      symKey = NULL;    SECItem *         params = NULL;    unsigned char *   buf;    SECStatus         rv     = SECFailure;    SECStatus         lrv;    unsigned int      bufLen;    int               iteration;    int               bytesRead;    SECOidTag         algtag;    SECItem           hmacRes;    SECItem           ignore = {0};    CK_MECHANISM_TYPE integrityMech;        if(!p12dcx || p12dcx->error) {	return SECFailure;    }    buf = (unsigned char *)PORT_Alloc(IN_BUF_LEN + FUDGE);    if (!buf)    	return SECFailure;  /* error code has been set. */#ifdef DEBUG    memcpy(buf + IN_BUF_LEN, bufferEnd, sizeof bufferEnd);#endif    /* 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);    params = NULL;    if (!symKey) goto loser;    /* init hmac */    pk11cx = PK11_CreateContextBySymKey(sec_pkcs12_algtag_to_mech(algtag),                                        CKA_SIGN, symKey, &ignore);    if(!pk11cx) {	goto loser;    }    lrv = PK11_DigestBegin(pk11cx);    if (lrv == SECFailure ) {	goto loser;    }    /* 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.     */    do {	bytesRead = (*p12dcx->dRead)(p12dcx->dArg, buf, IN_BUF_LEN);	if (bytesRead < 0) {	    PORT_SetError(SEC_ERROR_PKCS12_UNABLE_TO_READ);	    goto loser;	}	PORT_Assert(bytesRead <= IN_BUF_LEN);	PORT_Assert(!memcmp(buf + IN_BUF_LEN, bufferEnd, sizeof bufferEnd));	if (bytesRead > IN_BUF_LEN) {	    /* dRead callback overflowed buffer. */	    PORT_SetError(SEC_ERROR_PKCS12_UNABLE_TO_READ);	    goto loser;	}	if (bytesRead) {	    lrv = PK11_DigestOp(pk11cx, buf, bytesRead);	    if (lrv == SECFailure) {		goto loser;	    }    	}    } while (bytesRead == IN_BUF_LEN);    /* finish the hmac context */    lrv = PK11_DigestFinal(pk11cx, buf, &bufLen, IN_BUF_LEN);    if (lrv == SECFailure ) {	goto loser;    }    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);    }    if (params) {	PK11_DestroyPBEParams(params);    }    if (symKey) {	PK11_FreeSymKey(symKey);    }    PORT_ZFree(buf, IN_BUF_LEN + FUDGE);    return rv;}