static int xmlSecOpenSSLHmacVerify(xmlSecTransformPtr transform, const xmlSecByte* data, xmlSecSize dataSize, xmlSecTransformCtxPtr transformCtx) { static xmlSecByte last_byte_masks[] = { 0xFF, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE }; xmlSecOpenSSLHmacCtxPtr ctx; xmlSecByte mask; xmlSecAssert2(xmlSecTransformIsValid(transform), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLHmacSize), -1); xmlSecAssert2(transform->operation == xmlSecTransformOperationVerify, -1); xmlSecAssert2(transform->status == xmlSecTransformStatusFinished, -1); xmlSecAssert2(data != NULL, -1); xmlSecAssert2(transformCtx != NULL, -1); ctx = xmlSecOpenSSLHmacGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->dgstSize > 0, -1); /* compare the digest size in bytes */ if(dataSize != ((ctx->dgstSize + 7) / 8)){ xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_SIZE, "data=%d;dgst=%d", dataSize, ((ctx->dgstSize + 7) / 8)); transform->status = xmlSecTransformStatusFail; return(0); } /* we check the last byte separatelly */ xmlSecAssert2(dataSize > 0, -1); mask = last_byte_masks[ctx->dgstSize % 8]; if((ctx->dgst[dataSize - 1] & mask) != (data[dataSize - 1] & mask)) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_DATA_NOT_MATCH, "data and digest do not match (last byte)"); transform->status = xmlSecTransformStatusFail; return(0); } /* now check the rest of the digest */ if((dataSize > 1) && (memcmp(ctx->dgst, data, dataSize - 1) != 0)) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_DATA_NOT_MATCH, "data and digest do not match"); transform->status = xmlSecTransformStatusFail; return(0); } transform->status = xmlSecTransformStatusOk; return(0); }
static void xmlSecOpenSSLHmacFinalize(xmlSecTransformPtr transform) { xmlSecOpenSSLHmacCtxPtr ctx; xmlSecAssert(xmlSecOpenSSLHmacCheckId(transform)); xmlSecAssert(xmlSecTransformCheckSize(transform, xmlSecOpenSSLHmacSize)); ctx = xmlSecOpenSSLHmacGetCtx(transform); xmlSecAssert(ctx != NULL); #ifndef XMLSEC_OPENSSL_096 HMAC_CTX_cleanup(&(ctx->hmacCtx)); #endif /* XMLSEC_OPENSSL_096 */ memset(ctx, 0, sizeof(xmlSecOpenSSLHmacCtx)); }
static void xmlSecOpenSSLHmacFinalize(xmlSecTransformPtr transform) { xmlSecOpenSSLHmacCtxPtr ctx; xmlSecAssert(xmlSecOpenSSLHmacCheckId(transform)); xmlSecAssert(xmlSecTransformCheckSize(transform, xmlSecOpenSSLHmacSize)); ctx = xmlSecOpenSSLHmacGetCtx(transform); xmlSecAssert(ctx != NULL); if(ctx->hmacCtx != NULL) { HMAC_CTX_free(ctx->hmacCtx); } memset(ctx, 0, sizeof(xmlSecOpenSSLHmacCtx)); }
static int xmlSecOpenSSLHmacSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) { xmlSecOpenSSLHmacCtxPtr ctx; xmlSecKeyDataPtr value; xmlSecBufferPtr buffer; int ret; xmlSecAssert2(xmlSecOpenSSLHmacCheckId(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLHmacSize), -1); xmlSecAssert2(key != NULL, -1); ctx = xmlSecOpenSSLHmacGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->hmacCtx != NULL, -1); xmlSecAssert2(ctx->hmacDgst != NULL, -1); xmlSecAssert2(ctx->ctxInitialized == 0, -1); value = xmlSecKeyGetValue(key); xmlSecAssert2(xmlSecKeyDataCheckId(value, xmlSecOpenSSLKeyDataHmacId), -1); buffer = xmlSecKeyDataBinaryValueGetBuffer(value); xmlSecAssert2(buffer != NULL, -1); if(xmlSecBufferGetSize(buffer) == 0) { xmlSecInvalidZeroKeyDataSizeError(xmlSecTransformGetName(transform)); return(-1); } xmlSecAssert2(xmlSecBufferGetData(buffer) != NULL, -1); ret = HMAC_Init_ex(ctx->hmacCtx, xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer), ctx->hmacDgst, NULL); if(ret != 1) { xmlSecOpenSSLError("HMAC_Init_ex", xmlSecTransformGetName(transform)); return(-1); } ctx->ctxInitialized = 1; return(0); }
static int xmlSecOpenSSLHmacNodeRead(xmlSecTransformPtr transform, xmlNodePtr node, xmlSecTransformCtxPtr transformCtx) { xmlSecOpenSSLHmacCtxPtr ctx; xmlNodePtr cur; xmlSecAssert2(xmlSecOpenSSLHmacCheckId(transform), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLHmacSize), -1); xmlSecAssert2(node!= NULL, -1); xmlSecAssert2(transformCtx != NULL, -1); ctx = xmlSecOpenSSLHmacGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); cur = xmlSecGetNextElementNode(node->children); if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeHMACOutputLength, xmlSecDSigNs)) { xmlChar *content; content = xmlNodeGetContent(cur); if(content != NULL) { ctx->dgstSize = atoi((char*)content); xmlFree(content); } /* Ensure that HMAC length is greater than min specified. Otherwise, an attacker can set this length to 0 or very small value */ if((int)ctx->dgstSize < xmlSecOpenSSLHmacGetMinOutputLength()) { xmlSecInvalidNodeContentError(cur, xmlSecTransformGetName(transform), "HMAC output length is too small"); return(-1); } cur = xmlSecGetNextElementNode(cur->next); } if(cur != NULL) { xmlSecUnexpectedNodeError(cur, xmlSecTransformGetName(transform)); return(-1); } return(0); }
static int xmlSecOpenSSLHmacSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) { xmlSecOpenSSLHmacCtxPtr ctx; xmlSecKeyDataPtr value; xmlSecBufferPtr buffer; xmlSecAssert2(xmlSecOpenSSLHmacCheckId(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLHmacSize), -1); xmlSecAssert2(key != NULL, -1); ctx = xmlSecOpenSSLHmacGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->hmacDgst != NULL, -1); xmlSecAssert2(ctx->ctxInitialized == 0, -1); value = xmlSecKeyGetValue(key); xmlSecAssert2(xmlSecKeyDataCheckId(value, xmlSecOpenSSLKeyDataHmacId), -1); buffer = xmlSecKeyDataBinaryValueGetBuffer(value); xmlSecAssert2(buffer != NULL, -1); if(xmlSecBufferGetSize(buffer) == 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE, "keySize=0"); return(-1); } xmlSecAssert2(xmlSecBufferGetData(buffer) != NULL, -1); HMAC_Init(&(ctx->hmacCtx), xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer), ctx->hmacDgst); ctx->ctxInitialized = 1; return(0); }
static int xmlSecOpenSSLHmacNodeRead(xmlSecTransformPtr transform, xmlNodePtr node, xmlSecTransformCtxPtr transformCtx) { xmlSecOpenSSLHmacCtxPtr ctx; xmlNodePtr cur; xmlSecAssert2(xmlSecOpenSSLHmacCheckId(transform), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLHmacSize), -1); xmlSecAssert2(node!= NULL, -1); xmlSecAssert2(transformCtx != NULL, -1); ctx = xmlSecOpenSSLHmacGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); cur = xmlSecGetNextElementNode(node->children); if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeHMACOutputLength, xmlSecDSigNs)) { xmlChar *content; content = xmlNodeGetContent(cur); if(content != NULL) { ctx->dgstSize = atoi((char*)content); xmlFree(content); } /* todo: error if dgstSize == 0 ?*/ cur = xmlSecGetNextElementNode(cur->next); } if(cur != NULL) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), XMLSEC_ERRORS_R_UNEXPECTED_NODE, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } return(0); }
static int xmlSecOpenSSLHmacExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { xmlSecOpenSSLHmacCtxPtr ctx; xmlSecBufferPtr in, out; int ret; xmlSecAssert2(xmlSecTransformIsValid(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLHmacSize), -1); xmlSecAssert2(transformCtx != NULL, -1); in = &(transform->inBuf); out = &(transform->outBuf); ctx = xmlSecOpenSSLHmacGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->ctxInitialized != 0, -1); xmlSecAssert2(ctx->hmacCtx != NULL, -1); if(transform->status == xmlSecTransformStatusNone) { /* we should be already initialized when we set key */ transform->status = xmlSecTransformStatusWorking; } if(transform->status == xmlSecTransformStatusWorking) { xmlSecSize inSize; inSize = xmlSecBufferGetSize(in); if(inSize > 0) { ret = HMAC_Update(ctx->hmacCtx, xmlSecBufferGetData(in), inSize); if(ret != 1) { xmlSecOpenSSLError("HMAC_Update", xmlSecTransformGetName(transform)); return(-1); } ret = xmlSecBufferRemoveHead(in, inSize); if(ret < 0) { xmlSecInternalError2("xmlSecBufferRemoveHead", xmlSecTransformGetName(transform), "size=%d", inSize); return(-1); } } if(last) { unsigned int dgstSize = 0; ret = HMAC_Final(ctx->hmacCtx, ctx->dgst, &dgstSize); if(ret != 1) { xmlSecOpenSSLError("HMAC_Final", xmlSecTransformGetName(transform)); return(-1); } xmlSecAssert2(dgstSize > 0, -1); /* check/set the result digest size */ if(ctx->dgstSize == 0) { ctx->dgstSize = XMLSEC_SIZE_BAD_CAST(dgstSize * 8); /* no dgst size specified, use all we have */ } else if(ctx->dgstSize <= XMLSEC_SIZE_BAD_CAST(8 * dgstSize)) { dgstSize = ((ctx->dgstSize + 7) / 8); /* we need to truncate result digest */ } else { xmlSecInvalidSizeLessThanError("HMAC digest (bits)", 8 * dgstSize, ctx->dgstSize, xmlSecTransformGetName(transform)); return(-1); } /* finally write result to output */ if(transform->operation == xmlSecTransformOperationSign) { ret = xmlSecBufferAppend(out, ctx->dgst, dgstSize); if(ret < 0) { xmlSecInternalError2("xmlSecBufferAppend", xmlSecTransformGetName(transform), "size=%d", dgstSize); return(-1); } } transform->status = xmlSecTransformStatusFinished; } } else if(transform->status == xmlSecTransformStatusFinished) { /* the only way we can get here is if there is no input */ xmlSecAssert2(xmlSecBufferGetSize(in) == 0, -1); } else { xmlSecInvalidTransfromStatusError(transform); return(-1); } return(0); }
static int xmlSecOpenSSLHmacInitialize(xmlSecTransformPtr transform) { xmlSecOpenSSLHmacCtxPtr ctx; xmlSecAssert2(xmlSecOpenSSLHmacCheckId(transform), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLHmacSize), -1); ctx = xmlSecOpenSSLHmacGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); /* initialize context */ memset(ctx, 0, sizeof(xmlSecOpenSSLHmacCtx)); #ifndef XMLSEC_NO_SHA1 if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformHmacSha1Id)) { ctx->hmacDgst = EVP_sha1(); } else #endif /* XMLSEC_NO_SHA1 */ #ifndef XMLSEC_NO_SHA224 if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformHmacSha224Id)) { ctx->hmacDgst = EVP_sha224(); } else #endif /* XMLSEC_NO_SHA224 */ #ifndef XMLSEC_NO_SHA256 if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformHmacSha256Id)) { ctx->hmacDgst = EVP_sha256(); } else #endif /* XMLSEC_NO_SHA256 */ #ifndef XMLSEC_NO_SHA384 if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformHmacSha384Id)) { ctx->hmacDgst = EVP_sha384(); } else #endif /* XMLSEC_NO_SHA384 */ #ifndef XMLSEC_NO_SHA512 if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformHmacSha512Id)) { ctx->hmacDgst = EVP_sha512(); } else #endif /* XMLSEC_NO_SHA512 */ #ifndef XMLSEC_NO_RIPEMD160 if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformHmacRipemd160Id)) { ctx->hmacDgst = EVP_ripemd160(); } else #endif /* XMLSEC_NO_RIPEMD160 */ #ifndef XMLSEC_NO_MD5 if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformHmacMd5Id)) { ctx->hmacDgst = EVP_md5(); } else #endif /* XMLSEC_NO_MD5 */ { xmlSecInvalidTransfromError(transform) return(-1); } /* create hmac CTX */ ctx->hmacCtx = HMAC_CTX_new(); if(ctx->hmacCtx == NULL) { xmlSecOpenSSLError("HMAC_CTX_new", xmlSecTransformGetName(transform)); return(-1); } /* done */ return(0); }
static int xmlSecOpenSSLHmacExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { xmlSecOpenSSLHmacCtxPtr ctx; xmlSecBufferPtr in, out; int ret; xmlSecAssert2(xmlSecTransformIsValid(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLHmacSize), -1); xmlSecAssert2(transformCtx != NULL, -1); in = &(transform->inBuf); out = &(transform->outBuf); ctx = xmlSecOpenSSLHmacGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->ctxInitialized != 0, -1); if(transform->status == xmlSecTransformStatusNone) { /* we should be already initialized when we set key */ transform->status = xmlSecTransformStatusWorking; } if(transform->status == xmlSecTransformStatusWorking) { xmlSecSize inSize; inSize = xmlSecBufferGetSize(in); if(inSize > 0) { HMAC_Update(&(ctx->hmacCtx), xmlSecBufferGetData(in), inSize); ret = xmlSecBufferRemoveHead(in, inSize); if(ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferRemoveHead", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", inSize); return(-1); } } if(last) { xmlSecSize dgstSize; HMAC_Final(&(ctx->hmacCtx), ctx->dgst, &dgstSize); xmlSecAssert2(dgstSize > 0, -1); /* check/set the result digest size */ if(ctx->dgstSize == 0) { ctx->dgstSize = dgstSize * 8; /* no dgst size specified, use all we have */ } else if(ctx->dgstSize <= 8 * dgstSize) { dgstSize = ((ctx->dgstSize + 7) / 8); /* we need to truncate result digest */ } else { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_SIZE, "result-bits=%d;required-bits=%d", 8 * dgstSize, ctx->dgstSize); return(-1); } /* finally write result to output */ if(transform->operation == xmlSecTransformOperationSign) { ret = xmlSecBufferAppend(out, ctx->dgst, dgstSize); if(ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferAppend", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", dgstSize); return(-1); } } transform->status = xmlSecTransformStatusFinished; } } else if(transform->status == xmlSecTransformStatusFinished) { /* the only way we can get here is if there is no input */ xmlSecAssert2(xmlSecBufferGetSize(in) == 0, -1); } else { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_STATUS, "status=%d", transform->status); return(-1); } return(0); }
static int xmlSecOpenSSLHmacInitialize(xmlSecTransformPtr transform) { xmlSecOpenSSLHmacCtxPtr ctx; xmlSecAssert2(xmlSecOpenSSLHmacCheckId(transform), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLHmacSize), -1); ctx = xmlSecOpenSSLHmacGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); /* initialize context */ memset(ctx, 0, sizeof(xmlSecOpenSSLHmacCtx)); #ifndef XMLSEC_NO_SHA1 if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformHmacSha1Id)) { ctx->hmacDgst = EVP_sha1(); } else #endif /* XMLSEC_NO_SHA1 */ #ifndef XMLSEC_NO_SHA224 if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformHmacSha224Id)) { ctx->hmacDgst = EVP_sha224(); } else #endif /* XMLSEC_NO_SHA224 */ #ifndef XMLSEC_NO_SHA256 if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformHmacSha256Id)) { ctx->hmacDgst = EVP_sha256(); } else #endif /* XMLSEC_NO_SHA256 */ #ifndef XMLSEC_NO_SHA384 if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformHmacSha384Id)) { ctx->hmacDgst = EVP_sha384(); } else #endif /* XMLSEC_NO_SHA384 */ #ifndef XMLSEC_NO_SHA512 if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformHmacSha512Id)) { ctx->hmacDgst = EVP_sha512(); } else #endif /* XMLSEC_NO_SHA512 */ #ifndef XMLSEC_NO_RIPEMD160 if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformHmacRipemd160Id)) { ctx->hmacDgst = EVP_ripemd160(); } else #endif /* XMLSEC_NO_RIPEMD160 */ #ifndef XMLSEC_NO_MD5 if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformHmacMd5Id)) { ctx->hmacDgst = EVP_md5(); } else #endif /* XMLSEC_NO_MD5 */ { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_TRANSFORM, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } #ifndef XMLSEC_OPENSSL_096 HMAC_CTX_init(&(ctx->hmacCtx)); #endif /* XMLSEC_OPENSSL_096 */ return(0); }