static int xmlSecOpenSSLRsaPkcs1Process(xmlSecTransformPtr transform, xmlSecTransformCtxPtr transformCtx) { xmlSecOpenSSLRsaPkcs1CtxPtr ctx; xmlSecBufferPtr in, out; xmlSecSize inSize, outSize; xmlSecSize keySize; int ret; xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaPkcs1Id), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaPkcs1Size), -1); xmlSecAssert2(transformCtx != NULL, -1); ctx = xmlSecOpenSSLRsaPkcs1GetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->pKey != NULL, -1); xmlSecAssert2(ctx->pKey->type == EVP_PKEY_RSA, -1); xmlSecAssert2(ctx->pKey->pkey.rsa != NULL, -1); keySize = RSA_size(ctx->pKey->pkey.rsa); xmlSecAssert2(keySize > 0, -1); in = &(transform->inBuf); out = &(transform->outBuf); inSize = xmlSecBufferGetSize(in); outSize = xmlSecBufferGetSize(out); xmlSecAssert2(outSize == 0, -1); /* the encoded size is equal to the keys size so we could not * process more than that */ if((transform->operation == xmlSecTransformOperationEncrypt) && (inSize >= keySize)) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_SIZE, "%d when expected less than %d", inSize, keySize); return(-1); } else if((transform->operation == xmlSecTransformOperationDecrypt) && (inSize != keySize)) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_SIZE, "%d when expected %d", inSize, keySize); return(-1); } outSize = keySize; ret = xmlSecBufferSetMaxSize(out, outSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferSetMaxSize", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", outSize); return(-1); } if(transform->operation == xmlSecTransformOperationEncrypt) { ret = RSA_public_encrypt(inSize, xmlSecBufferGetData(in), xmlSecBufferGetData(out), ctx->pKey->pkey.rsa, RSA_PKCS1_PADDING); if(ret <= 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "RSA_public_encrypt", XMLSEC_ERRORS_R_CRYPTO_FAILED, "size=%d", inSize); return(-1); } outSize = ret; } else { ret = RSA_private_decrypt(inSize, xmlSecBufferGetData(in), xmlSecBufferGetData(out), ctx->pKey->pkey.rsa, RSA_PKCS1_PADDING); if(ret <= 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "RSA_private_decrypt", XMLSEC_ERRORS_R_CRYPTO_FAILED, "size=%d", inSize); return(-1); } outSize = ret; } ret = xmlSecBufferSetSize(out, outSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferSetSize", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", outSize); return(-1); } ret = xmlSecBufferRemoveHead(in, inSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferRemoveHead", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", inSize); return(-1); } return(0); }
/** * xmlSecEncCtxDecrypt: * @encCtx: the pointer to <enc:EncryptedData/> processing context. * @node: the pointer to <enc:EncryptedData/> node. * * Decrypts @node and if necessary replaces @node with decrypted data. * * Returns: 0 on success or a negative value if an error occurs. */ int xmlSecEncCtxDecrypt(xmlSecEncCtxPtr encCtx, xmlNodePtr node) { xmlSecBufferPtr buffer; int ret; xmlSecAssert2(encCtx != NULL, -1); xmlSecAssert2(node != NULL, -1); /* decrypt */ buffer = xmlSecEncCtxDecryptToBuffer(encCtx, node); if(buffer == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecEncCtxDecryptToBuffer", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } /* replace original node if requested */ if((encCtx->type != NULL) && xmlStrEqual(encCtx->type, xmlSecTypeEncElement)) { /* check if we need to return the replaced node */ if((encCtx->flags & XMLSEC_ENC_RETURN_REPLACED_NODE) != 0) { ret = xmlSecReplaceNodeBufferAndReturn(node, xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer), &(encCtx->replacedNodeList)); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecReplaceNodeBufferAndReturn", XMLSEC_ERRORS_R_XMLSEC_FAILED, "node=%s", xmlSecErrorsSafeString(xmlSecNodeGetName(node))); return(-1); } } else { ret = xmlSecReplaceNodeBuffer(node, xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer)); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecReplaceNodeBuffer", XMLSEC_ERRORS_R_XMLSEC_FAILED, "node=%s", xmlSecErrorsSafeString(xmlSecNodeGetName(node))); return(-1); } } encCtx->resultReplaced = 1; } else if((encCtx->type != NULL) && xmlStrEqual(encCtx->type, xmlSecTypeEncContent)) { /* replace the node with the buffer */ /* check if we need to return the replaced node */ if((encCtx->flags & XMLSEC_ENC_RETURN_REPLACED_NODE) != 0) { ret = xmlSecReplaceNodeBufferAndReturn(node, xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer), &(encCtx->replacedNodeList)); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecReplaceNodeBufferAndReturn", XMLSEC_ERRORS_R_XMLSEC_FAILED, "node=%s", xmlSecErrorsSafeString(xmlSecNodeGetName(node))); return(-1); } } else { ret = xmlSecReplaceNodeBuffer(node, xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer)); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecReplaceNodeBuffer", XMLSEC_ERRORS_R_XMLSEC_FAILED, "node=%s", xmlSecErrorsSafeString(xmlSecNodeGetName(node))); return(-1); } } encCtx->resultReplaced = 1; } return(0); }
static int xmlSecNssKWAesExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { xmlSecBufferPtr in, out, key; xmlSecSize inSize, outSize, keySize, expectedKeySize; int ret; xmlSecAssert2(xmlSecNssKWAesCheckId(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssKWAesSize), -1); xmlSecAssert2(transformCtx != NULL, -1); key = xmlSecNssKWAesGetKey(transform); xmlSecAssert2(key != NULL, -1); keySize = xmlSecBufferGetSize(key); expectedKeySize = xmlSecNssKWAesGetKeySize(transform); xmlSecAssert2(keySize == expectedKeySize, -1); in = &(transform->inBuf); out = &(transform->outBuf); inSize = xmlSecBufferGetSize(in); outSize = xmlSecBufferGetSize(out); xmlSecAssert2(outSize == 0, -1); if(transform->status == xmlSecTransformStatusNone) { transform->status = xmlSecTransformStatusWorking; } if((transform->status == xmlSecTransformStatusWorking) && (last == 0)) { /* just do nothing */ } else if((transform->status == xmlSecTransformStatusWorking) && (last != 0)) { if((inSize % 8) != 0) { xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_SIZE, "size=%d(not 8 bytes aligned)", inSize); return(-1); } if(transform->operation == xmlSecTransformOperationEncrypt) { /* the encoded key might be 8 bytes longer plus 8 bytes just in case */ outSize = inSize + XMLSEC_NSS_KW_AES_MAGIC_BLOCK_SIZE + XMLSEC_NSS_AES_BLOCK_SIZE; } else { outSize = inSize + XMLSEC_NSS_AES_BLOCK_SIZE; } ret = xmlSecBufferSetMaxSize(out, outSize); if(ret < 0) { xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferSetMaxSize", XMLSEC_ERRORS_R_XMLSEC_FAILED, "outSize=%d", outSize); return(-1); } if(transform->operation == xmlSecTransformOperationEncrypt) { ret = xmlSecNssKWAesOp(xmlSecBufferGetData(key), keySize, xmlSecBufferGetData(in), inSize, xmlSecBufferGetData(out), outSize, 1); if(ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecNssKWAesOp", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } outSize = ret; } else { ret = xmlSecNssKWAesOp(xmlSecBufferGetData(key), keySize, xmlSecBufferGetData(in), inSize, xmlSecBufferGetData(out), outSize, 0); if(ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecNssKWAesOp", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } outSize = ret; } ret = xmlSecBufferSetSize(out, outSize); if(ret < 0) { xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferSetSize", XMLSEC_ERRORS_R_XMLSEC_FAILED, g "outSize=%d", outSize); return(-1); } ret = xmlSecBufferRemoveHead(in, inSize); if(ret < 0) { xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferRemoveHead", XMLSEC_ERRORS_R_XMLSEC_FAILED, "inSize%d", inSize); 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(&(transform->inBuf)) == 0, -1); } else { xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_STATUS, "status=%d", transform->status); return(-1); } return(0); }
static int xmlSecGCryptKWAesBlockDecrypt(const xmlSecByte * in, xmlSecSize inSize, xmlSecByte * out, xmlSecSize outSize, void * context) { xmlSecGCryptKWAesCtxPtr ctx = (xmlSecGCryptKWAesCtxPtr)context; gcry_cipher_hd_t cipherCtx; gcry_error_t err; xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(in != NULL, -1); xmlSecAssert2(inSize >= ctx->blockSize, -1); xmlSecAssert2(out != NULL, -1); xmlSecAssert2(outSize >= ctx->blockSize, -1); err = gcry_cipher_open(&cipherCtx, ctx->cipher, ctx->mode, ctx->flags); if(err != GPG_ERR_NO_ERROR) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "gcry_cipher_open", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_GCRYPT_REPORT_ERROR(err)); return(-1); } err = gcry_cipher_setkey(cipherCtx, xmlSecBufferGetData(&ctx->keyBuffer), xmlSecBufferGetSize(&ctx->keyBuffer)); if(err != GPG_ERR_NO_ERROR) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "gcry_cipher_setkey", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_GCRYPT_REPORT_ERROR(err)); return(-1); } /* use zero IV and CBC mode to ensure we get result as-is */ err = gcry_cipher_setiv(cipherCtx, g_zero_iv, sizeof(g_zero_iv)); if(err != GPG_ERR_NO_ERROR) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "gcry_cipher_setiv", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_GCRYPT_REPORT_ERROR(err)); return(-1); } err = gcry_cipher_decrypt(cipherCtx, out, outSize, in, inSize); if(err != GPG_ERR_NO_ERROR) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "gcry_cipher_decrypt", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_GCRYPT_REPORT_ERROR(err)); gcry_cipher_close(cipherCtx); return(-1); } gcry_cipher_close(cipherCtx); return(ctx->blockSize); }
/** * xmlSecEncCtxDebugDump: * @encCtx: the pointer to <enc:EncryptedData/> processing context. * @output: the pointer to output FILE. * * Prints the debug information about @encCtx to @output. */ void xmlSecEncCtxDebugDump(xmlSecEncCtxPtr encCtx, FILE* output) { xmlSecAssert(encCtx != NULL); xmlSecAssert(output != NULL); switch(encCtx->mode) { case xmlEncCtxModeEncryptedData: if(encCtx->operation == xmlSecTransformOperationEncrypt) { fprintf(output, "= DATA ENCRYPTION CONTEXT\n"); } else { fprintf(output, "= DATA DECRYPTION CONTEXT\n"); } break; case xmlEncCtxModeEncryptedKey: if(encCtx->operation == xmlSecTransformOperationEncrypt) { fprintf(output, "= KEY ENCRYPTION CONTEXT\n"); } else { fprintf(output, "= KEY DECRYPTION CONTEXT\n"); } break; } fprintf(output, "== Status: %s\n", (encCtx->resultReplaced) ? "replaced" : "not-replaced" ); fprintf(output, "== flags: 0x%08x\n", encCtx->flags); fprintf(output, "== flags2: 0x%08x\n", encCtx->flags2); if(encCtx->id != NULL) { fprintf(output, "== Id: \"%s\"\n", encCtx->id); } if(encCtx->type != NULL) { fprintf(output, "== Type: \"%s\"\n", encCtx->type); } if(encCtx->mimeType != NULL) { fprintf(output, "== MimeType: \"%s\"\n", encCtx->mimeType); } if(encCtx->encoding != NULL) { fprintf(output, "== Encoding: \"%s\"\n", encCtx->encoding); } if(encCtx->recipient != NULL) { fprintf(output, "== Recipient: \"%s\"\n", encCtx->recipient); } if(encCtx->carriedKeyName != NULL) { fprintf(output, "== CarriedKeyName: \"%s\"\n", encCtx->carriedKeyName); } fprintf(output, "== Key Info Read Ctx:\n"); xmlSecKeyInfoCtxDebugDump(&(encCtx->keyInfoReadCtx), output); fprintf(output, "== Key Info Write Ctx:\n"); xmlSecKeyInfoCtxDebugDump(&(encCtx->keyInfoWriteCtx), output); fprintf(output, "== Encryption Transform Ctx:\n"); xmlSecTransformCtxDebugDump(&(encCtx->transformCtx), output); if(encCtx->encMethod != NULL) { fprintf(output, "== Encryption Method:\n"); xmlSecTransformDebugDump(encCtx->encMethod, output); } if(encCtx->encKey != NULL) { fprintf(output, "== Encryption Key:\n"); xmlSecKeyDebugDump(encCtx->encKey, output); } if((encCtx->result != NULL) && (xmlSecBufferGetData(encCtx->result) != NULL) && (encCtx->resultBase64Encoded != 0)) { fprintf(output, "== Result - start buffer:\n"); fwrite(xmlSecBufferGetData(encCtx->result), xmlSecBufferGetSize(encCtx->result), 1, output); fprintf(output, "\n== Result - end buffer\n"); } }
static int xmlSecTransformRelationshipPopBin(xmlSecTransformPtr transform, xmlSecByte* data, xmlSecSize maxDataSize, xmlSecSize* dataSize, xmlSecTransformCtxPtr transformCtx) { xmlSecBufferPtr out; int ret; xmlSecAssert2(data != NULL, -1); xmlSecAssert2(dataSize != NULL, -1); xmlSecAssert2(transformCtx != NULL, -1); out = &(transform->outBuf); if(transform->status == xmlSecTransformStatusNone) { xmlOutputBufferPtr buf; xmlSecAssert2(transform->inNodes == NULL, -1); if(transform->prev == NULL) { (*dataSize) = 0; transform->status = xmlSecTransformStatusFinished; return(0); } /* get xml data from previous transform */ ret = xmlSecTransformPopXml(transform->prev, &(transform->inNodes), transformCtx); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecTransformPopXml", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } /* dump everything to internal buffer */ buf = xmlSecBufferCreateOutputBuffer(out); if(buf == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferCreateOutputBuffer", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } ret = xmlC14NExecute(transform->inNodes->doc, (xmlC14NIsVisibleCallback)xmlSecNodeSetContains, transform->inNodes, XML_C14N_1_0, NULL, 0, buf); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecTransformC14NExecute", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); xmlOutputBufferClose(buf); return(-1); } ret = xmlOutputBufferClose(buf); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlOutputBufferClose", XMLSEC_ERRORS_R_XML_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } transform->status = xmlSecTransformStatusWorking; } if(transform->status == xmlSecTransformStatusWorking) { xmlSecSize outSize; /* return chunk after chunk */ outSize = xmlSecBufferGetSize(out); if(outSize > maxDataSize) { outSize = maxDataSize; } if(outSize > XMLSEC_TRANSFORM_BINARY_CHUNK) { outSize = XMLSEC_TRANSFORM_BINARY_CHUNK; } if(outSize > 0) { xmlSecAssert2(xmlSecBufferGetData(out), -1); memcpy(data, xmlSecBufferGetData(out), outSize); ret = xmlSecBufferRemoveHead(out, outSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferRemoveHead", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", outSize); return(-1); } } else if(xmlSecBufferGetSize(out) == 0) { transform->status = xmlSecTransformStatusFinished; } (*dataSize) = outSize; } else if(transform->status == xmlSecTransformStatusFinished) { /* the only way we can get here is if there is no output */ xmlSecAssert2(xmlSecBufferGetSize(out) == 0, -1); (*dataSize) = 0; } else { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_STATUS, "status=%d", transform->status); return(-1); } return(0); }
static int xmlSecMSCngSignatureExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { xmlSecMSCngSignatureCtxPtr ctx; xmlSecSize inSize; xmlSecSize outSize; NTSTATUS status; DWORD cbData = 0; DWORD cbHashObject = 0; int ret; xmlSecAssert2(xmlSecMSCngSignatureCheckId(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCngSignatureSize), -1); xmlSecAssert2(transformCtx != NULL, -1); ctx = xmlSecMSCngSignatureGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->pszHashAlgId != NULL, -1); inSize = xmlSecBufferGetSize(&transform->inBuf); outSize = xmlSecBufferGetSize(&transform->outBuf); if(transform->status == xmlSecTransformStatusNone) { xmlSecAssert2(outSize == 0, -1); /* open an algorithm handle */ status = BCryptOpenAlgorithmProvider( &ctx->hHashAlg, ctx->pszHashAlgId, NULL, 0); if(status != STATUS_SUCCESS) { xmlSecMSCngNtError("BCryptOpenAlgorithmProvider", xmlSecTransformGetName(transform), status); return(-1); } /* calculate the size of the buffer to hold the hash object */ status = BCryptGetProperty( ctx->hHashAlg, BCRYPT_OBJECT_LENGTH, (PBYTE)&cbHashObject, sizeof(DWORD), &cbData, 0); if(status != STATUS_SUCCESS) { xmlSecMSCngNtError("BCryptGetProperty", xmlSecTransformGetName(transform), status); return(-1); } /* allocate the hash object on the heap */ ctx->pbHashObject = (PBYTE)xmlMalloc(cbHashObject); if(ctx->pbHashObject == NULL) { xmlSecMallocError(cbHashObject, NULL); return(-1); } /* calculate the length of the hash */ status = BCryptGetProperty( ctx->hHashAlg, BCRYPT_HASH_LENGTH, (PBYTE)&ctx->cbHash, sizeof(DWORD), &cbData, 0); if(status != STATUS_SUCCESS) { xmlSecMSCngNtError("BCryptGetProperty", xmlSecTransformGetName(transform), status); return(-1); } /* allocate the hash buffer on the heap */ ctx->pbHash = (PBYTE)xmlMalloc(ctx->cbHash); if(ctx->pbHash == NULL) { xmlSecMallocError(ctx->cbHash, NULL); return(-1); } /* create the hash */ status = BCryptCreateHash( ctx->hHashAlg, &ctx->hHash, ctx->pbHashObject, cbHashObject, NULL, 0, 0); if(status != STATUS_SUCCESS) { xmlSecMSCngNtError("BCryptCreateHash", xmlSecTransformGetName(transform), status); return(-1); } transform->status = xmlSecTransformStatusWorking; } if((transform->status == xmlSecTransformStatusWorking)) { if(inSize > 0) { xmlSecAssert2(outSize == 0, -1); /* hash some data */ status = BCryptHashData( ctx->hHash, (PBYTE)xmlSecBufferGetData(&transform->inBuf), inSize, 0); if(status != STATUS_SUCCESS) { xmlSecMSCngNtError("BCryptHashData", xmlSecTransformGetName(transform), status); return(-1); } ret = xmlSecBufferRemoveHead(&transform->inBuf, inSize); if(ret < 0) { xmlSecInternalError("xmlSecBufferRemoveHead", xmlSecTransformGetName(transform)); return(-1); } } if(last != 0) { /* close the hash */ status = BCryptFinishHash( ctx->hHash, ctx->pbHash, ctx->cbHash, 0); if(status != STATUS_SUCCESS) { xmlSecMSCngNtError("BCryptFinishHash", xmlSecTransformGetName(transform), status); return(-1); } xmlSecAssert2(ctx->cbHash > 0, -1); if(transform->operation == xmlSecTransformOperationSign) { xmlSecNotImplementedError(NULL); return(-1); } transform->status = xmlSecTransformStatusFinished; } } if((transform->status == xmlSecTransformStatusWorking) || (transform->status == xmlSecTransformStatusFinished)) { xmlSecAssert2(xmlSecBufferGetSize(&transform->inBuf) == 0, -1); } else { xmlSecInvalidTransfromStatusError(transform); 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); }
/** * xmlSecKeyDataBinaryValueXmlRead: * @id: the data klass. * @key: the pointer to destination key. * @node: the pointer to an XML node. * @keyInfoCtx: the pointer to <dsig:KeyInfo/> element processing context. * * Reads binary key data from @node to the key by base64 decoding the @node content. * * Returns: 0 on success or a negative value otherwise. */ int xmlSecKeyDataBinaryValueXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { xmlChar* str; xmlSecSize len; xmlSecKeyDataPtr data; int ret; xmlSecAssert2(id != xmlSecKeyDataIdUnknown, -1); xmlSecAssert2(key != NULL, -1); xmlSecAssert2(node != NULL, -1); xmlSecAssert2(keyInfoCtx != NULL, -1); str = xmlNodeGetContent(node); if(str == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), xmlSecErrorsSafeString(xmlSecNodeGetName(node)), XMLSEC_ERRORS_R_INVALID_NODE_CONTENT, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } /* usual trick: decode into the same buffer */ ret = xmlSecBase64Decode(str, (xmlSecByte*)str, xmlStrlen(str)); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), "xmlSecBase64Decode", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); xmlFree(str); return(-1); } len = ret; /* check do we have a key already */ data = xmlSecKeyGetValue(key); if(data != NULL) { xmlSecBufferPtr buffer; if(!xmlSecKeyDataCheckId(data, id)) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST, XMLSEC_ERRORS_NO_MESSAGE); xmlFree(str); return(-1); } buffer = xmlSecKeyDataBinaryValueGetBuffer(data); if((buffer != NULL) && ((xmlSecSize)xmlSecBufferGetSize(buffer) != len)) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST, "cur-data-size=%d;new-data-size=%d", xmlSecBufferGetSize(buffer), len); xmlFree(str); return(-1); } if((buffer != NULL) && (len > 0) && (memcmp(xmlSecBufferGetData(buffer), str, len) != 0)) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST, "key already has a different value"); xmlFree(str); return(-1); } if(buffer != NULL) { /* we already have exactly the same key */ xmlFree(str); return(0); } /* we have binary key value with empty buffer */ } data = xmlSecKeyDataCreate(id); if(data == NULL ) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), "xmlSecKeyDataCreate", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); xmlFree(str); return(-1); } ret = xmlSecKeyDataBinaryValueSetBuffer(data, (xmlSecByte*)str, len); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), "xmlSecKeyDataBinaryValueSetBuffer", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", len); xmlSecKeyDataDestroy(data); xmlFree(str); return(-1); } xmlFree(str); if(xmlSecKeyReqMatchKeyValue(&(keyInfoCtx->keyReq), data) != 1) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), "xmlSecKeyReqMatchKeyValue", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); xmlSecKeyDataDestroy(data); return(0); } ret = xmlSecKeySetValue(key, data); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), "xmlSecKeySetValue", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); xmlSecKeyDataDestroy(data); return(-1); } return(0); }
static int xmlSecTransformMemBufExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { xmlSecBufferPtr buffer; xmlSecBufferPtr in, out; xmlSecSize inSize; int ret; xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformMemBufId), -1); xmlSecAssert2(transformCtx != NULL, -1); buffer = xmlSecTransformMemBufGetBuf(transform); xmlSecAssert2(buffer != NULL, -1); in = &(transform->inBuf); out = &(transform->outBuf); inSize = xmlSecBufferGetSize(in); if(transform->status == xmlSecTransformStatusNone) { transform->status = xmlSecTransformStatusWorking; } if(transform->status == xmlSecTransformStatusWorking) { /* just copy everything from in to our buffer and out */ ret = xmlSecBufferAppend(buffer, xmlSecBufferGetData(in), inSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferAppend", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", inSize); return(-1); } ret = xmlSecBufferAppend(out, xmlSecBufferGetData(in), inSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferAppend", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", inSize); return(-1); } ret = xmlSecBufferRemoveHead(in, inSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferRemoveHead", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", inSize); return(-1); } if(last != 0) { transform->status = xmlSecTransformStatusFinished; } } else if(transform->status == xmlSecTransformStatusFinished) { /* the only way we can get here is if there is no input */ xmlSecAssert2(inSize == 0, -1); } else { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_STATUS, "status=%d", transform->status); return(-1); } return(0); }
static int xmlSecGCryptHmacExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { xmlSecGCryptHmacCtxPtr ctx; xmlSecBufferPtr in, out; xmlSecByte* dgst; xmlSecSize dgstSize; int ret; xmlSecAssert2(xmlSecGCryptHmacCheckId(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGCryptHmacSize), -1); xmlSecAssert2(transformCtx != NULL, -1); ctx = xmlSecGCryptHmacGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->digestCtx != NULL, -1); in = &(transform->inBuf); out = &(transform->outBuf); if(transform->status == xmlSecTransformStatusNone) { transform->status = xmlSecTransformStatusWorking; } if(transform->status == xmlSecTransformStatusWorking) { xmlSecSize inSize; inSize = xmlSecBufferGetSize(in); if(inSize > 0) { gcry_md_write(ctx->digestCtx, xmlSecBufferGetData(in), inSize); ret = xmlSecBufferRemoveHead(in, inSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferRemoveHead", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", inSize); return(-1); } } if(last) { /* get the final digest */ gcry_md_final(ctx->digestCtx); dgst = gcry_md_read(ctx->digestCtx, ctx->digest); if(dgst == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "gcry_md_read", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } /* copy it to our internal buffer */ dgstSize = gcry_md_get_algo_dlen(ctx->digest); xmlSecAssert2(dgstSize > 0, -1); xmlSecAssert2(dgstSize <= sizeof(ctx->dgst), -1); memcpy(ctx->dgst, dgst, dgstSize); /* 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 { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_SIZE, "result-bits=%d;required-bits=%d", 8 * dgstSize, ctx->dgstSize); return(-1); } if(transform->operation == xmlSecTransformOperationSign) { ret = xmlSecBufferAppend(out, ctx->dgst, dgstSize); if(ret < 0) { xmlSecError(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(&(transform->inBuf)) == 0, -1); } else { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_STATUS, "size=%d", transform->status); return(-1); } return(0); }
static int xmlSecMSCryptoHmacExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { xmlSecMSCryptoHmacCtxPtr ctx; xmlSecBufferPtr in, out; int ret; xmlSecAssert2(xmlSecTransformIsValid(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCryptoHmacSize), -1); xmlSecAssert2(transformCtx != NULL, -1); in = &(transform->inBuf); out = &(transform->outBuf); ctx = xmlSecMSCryptoHmacGetCtx(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) { ret = CryptHashData(ctx->mscHash, xmlSecBufferGetData(in), inSize, 0); if(ret == 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "CryptHashData", XMLSEC_ERRORS_R_CRYPTO_FAILED, "size=%d", inSize); return(-1); } ret = xmlSecBufferRemoveHead(in, inSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferRemoveHead", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", inSize); return(-1); } } if(last) { /* TODO: make a MSCrypto compatible assert here */ /* xmlSecAssert2((xmlSecSize)EVP_MD_size(ctx->digest) <= sizeof(ctx->dgst), -1); */ DWORD retLen; retLen = XMLSEC_MSCRYPTO_MAX_HMAC_SIZE; ret = CryptGetHashParam(ctx->mscHash, HP_HASHVAL, ctx->dgst, &retLen, 0); if (ret == 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "CryptGetHashParam", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", inSize); return(-1); } xmlSecAssert2(retLen > 0, -1); /* check/set the result digest size */ if(ctx->dgstSize == 0) { ctx->dgstSize = retLen * 8; /* no dgst size specified, use all we have */ } else if(ctx->dgstSize <= 8 * retLen) { retLen = ((ctx->dgstSize + 7) / 8); /* we need to truncate result digest */ } else { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_SIZE, "result-bits=%d;required-bits=%d", 8 * retLen, ctx->dgstSize); return(-1); } /* copy result to output */ if(transform->operation == xmlSecTransformOperationSign) { ret = xmlSecBufferAppend(out, ctx->dgst, retLen); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferAppend", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", ctx->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 { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_STATUS, "status=%d", transform->status); return(-1); } return(0); }
static int xmlSecMSCryptoHmacSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) { xmlSecMSCryptoHmacCtxPtr ctx; xmlSecKeyDataPtr value; xmlSecBufferPtr buffer; HMAC_INFO hmacInfo; int ret; xmlSecAssert2(xmlSecMSCryptoHmacCheckId(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCryptoHmacSize), -1); xmlSecAssert2(key != NULL, -1); ctx = xmlSecMSCryptoHmacGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->ctxInitialized == 0, -1); xmlSecAssert2(ctx->provider != 0, -1); xmlSecAssert2(ctx->pubPrivKey != 0, -1); xmlSecAssert2(ctx->cryptKey == 0, -1); xmlSecAssert2(ctx->mscHash == 0, -1); value = xmlSecKeyGetValue(key); xmlSecAssert2(xmlSecKeyDataCheckId(value, xmlSecMSCryptoKeyDataHmacId), -1); buffer = xmlSecKeyDataBinaryValueGetBuffer(value); xmlSecAssert2(buffer != NULL, -1); if(xmlSecBufferGetSize(buffer) == 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE, "keySize=0"); return(-1); } xmlSecAssert2(xmlSecBufferGetData(buffer) != NULL, -1); /* Import this key and get an HCRYPTKEY handle. * * HACK!!! HACK!!! HACK!!! * * Using CALG_RC2 instead of CALG_HMAC for the key algorithm so we don't want to check key length */ if (!xmlSecMSCryptoImportPlainSessionBlob(ctx->provider, ctx->pubPrivKey, CALG_RC2, xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer), FALSE, &(ctx->cryptKey) ) || (ctx->cryptKey == 0)) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecMSCryptoImportPlainSessionBlob", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } /* create hash */ ret = CryptCreateHash(ctx->provider, CALG_HMAC, ctx->cryptKey, 0, &(ctx->mscHash)); if((ret == 0) || (ctx->mscHash == 0)) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "CryptCreateHash", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } /* set parameters */ memset(&hmacInfo, 0, sizeof(hmacInfo)); hmacInfo.HashAlgid = ctx->alg_id; ret = CryptSetHashParam(ctx->mscHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0); if(ret == 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "CryptSetHashParam", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } /* done */ ctx->ctxInitialized = 1; return(0); }
static int xmlSecOpenSSLRsaOaepProcess(xmlSecTransformPtr transform, xmlSecTransformCtxPtr transformCtx) { xmlSecOpenSSLRsaOaepCtxPtr ctx; xmlSecSize paramsSize; xmlSecBufferPtr in, out; xmlSecSize inSize, outSize; xmlSecSize keySize; int ret; xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaOaepId), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaOaepSize), -1); xmlSecAssert2(transformCtx != NULL, -1); ctx = xmlSecOpenSSLRsaOaepGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->pKey != NULL, -1); xmlSecAssert2(ctx->pKey->type == EVP_PKEY_RSA, -1); xmlSecAssert2(ctx->pKey->pkey.rsa != NULL, -1); keySize = RSA_size(ctx->pKey->pkey.rsa); xmlSecAssert2(keySize > 0, -1); in = &(transform->inBuf); out = &(transform->outBuf); inSize = xmlSecBufferGetSize(in); outSize = xmlSecBufferGetSize(out); xmlSecAssert2(outSize == 0, -1); /* the encoded size is equal to the keys size so we could not * process more than that */ if((transform->operation == xmlSecTransformOperationEncrypt) && (inSize >= keySize)) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_SIZE, "%d when expected less than %d", inSize, keySize); return(-1); } else if((transform->operation == xmlSecTransformOperationDecrypt) && (inSize != keySize)) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_SIZE, "%d when expected %d", inSize, keySize); return(-1); } outSize = keySize; ret = xmlSecBufferSetMaxSize(out, outSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferSetMaxSize", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", outSize); return(-1); } paramsSize = xmlSecBufferGetSize(&(ctx->oaepParams)); if((transform->operation == xmlSecTransformOperationEncrypt) && (paramsSize == 0)) { /* encode w/o OAEPParams --> simple */ ret = RSA_public_encrypt(inSize, xmlSecBufferGetData(in), xmlSecBufferGetData(out), ctx->pKey->pkey.rsa, RSA_PKCS1_OAEP_PADDING); if(ret <= 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "RSA_public_encrypt(RSA_PKCS1_OAEP_PADDING)", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } outSize = ret; } else if((transform->operation == xmlSecTransformOperationEncrypt) && (paramsSize > 0)) { xmlSecAssert2(xmlSecBufferGetData(&(ctx->oaepParams)) != NULL, -1); /* add space for padding */ ret = xmlSecBufferSetMaxSize(in, keySize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferSetMaxSize", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", keySize); return(-1); } /* add padding */ ret = RSA_padding_add_PKCS1_OAEP(xmlSecBufferGetData(in), keySize, xmlSecBufferGetData(in), inSize, xmlSecBufferGetData(&(ctx->oaepParams)), paramsSize); if(ret != 1) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "RSA_padding_add_PKCS1_OAEP", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } inSize = keySize; /* encode with OAEPParams */ ret = RSA_public_encrypt(inSize, xmlSecBufferGetData(in), xmlSecBufferGetData(out), ctx->pKey->pkey.rsa, RSA_NO_PADDING); if(ret <= 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "RSA_public_encrypt(RSA_NO_PADDING)", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } outSize = ret; } else if((transform->operation == xmlSecTransformOperationDecrypt) && (paramsSize == 0)) { ret = RSA_private_decrypt(inSize, xmlSecBufferGetData(in), xmlSecBufferGetData(out), ctx->pKey->pkey.rsa, RSA_PKCS1_OAEP_PADDING); if(ret <= 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "RSA_private_decrypt(RSA_PKCS1_OAEP_PADDING)", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } outSize = ret; } else if((transform->operation == xmlSecTransformOperationDecrypt) && (paramsSize != 0)) { BIGNUM bn; ret = RSA_private_decrypt(inSize, xmlSecBufferGetData(in), xmlSecBufferGetData(out), ctx->pKey->pkey.rsa, RSA_NO_PADDING); if(ret <= 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "RSA_private_decrypt(RSA_NO_PADDING)", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } outSize = ret; /* * the private decrypt w/o padding adds '0's at the begginning. * it's not clear for me can I simply skip all '0's from the * beggining so I have to do decode it back to BIGNUM and dump * buffer again */ BN_init(&bn); if(BN_bin2bn(xmlSecBufferGetData(out), outSize, &bn) == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "BN_bin2bn", XMLSEC_ERRORS_R_CRYPTO_FAILED, "size=%d", outSize); BN_clear_free(&bn); return(-1); } ret = BN_bn2bin(&bn, xmlSecBufferGetData(out)); if(ret <= 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "BN_bn2bin", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); BN_clear_free(&bn); return(-1); } BN_clear_free(&bn); outSize = ret; ret = RSA_padding_check_PKCS1_OAEP(xmlSecBufferGetData(out), outSize, xmlSecBufferGetData(out), outSize, keySize, xmlSecBufferGetData(&(ctx->oaepParams)), paramsSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "RSA_padding_check_PKCS1_OAEP", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } outSize = ret; } else { xmlSecAssert2("we could not be here" == NULL, -1); return(-1); } ret = xmlSecBufferSetSize(out, outSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferSetSize", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", outSize); return(-1); } ret = xmlSecBufferRemoveHead(in, inSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferRemoveHead", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", inSize); return(-1); } return(0); }
static int xmlSecNssKWAesExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { xmlSecNssKWAesCtxPtr ctx; xmlSecBufferPtr in, out; xmlSecSize inSize, outSize, keySize; int ret; xmlSecAssert2(xmlSecNssKWAesCheckId(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssKWAesSize), -1); xmlSecAssert2(transformCtx != NULL, -1); ctx = xmlSecNssKWAesGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); keySize = xmlSecBufferGetSize(&(ctx->keyBuffer)); xmlSecAssert2(keySize == ctx->keyExpectedSize, -1); in = &(transform->inBuf); out = &(transform->outBuf); inSize = xmlSecBufferGetSize(in); outSize = xmlSecBufferGetSize(out); xmlSecAssert2(outSize == 0, -1); if(transform->status == xmlSecTransformStatusNone) { transform->status = xmlSecTransformStatusWorking; } if((transform->status == xmlSecTransformStatusWorking) && (last == 0)) { /* just do nothing */ } else if((transform->status == xmlSecTransformStatusWorking) && (last != 0)) { if((inSize % 8) != 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_SIZE, "size=%d(not 8 bytes aligned)", inSize); return(-1); } if(transform->operation == xmlSecTransformOperationEncrypt) { /* the encoded key might be 8 bytes longer plus 8 bytes just in case */ outSize = inSize + XMLSEC_KW_AES_MAGIC_BLOCK_SIZE + XMLSEC_KW_AES_BLOCK_SIZE; } else { outSize = inSize + XMLSEC_KW_AES_BLOCK_SIZE; } ret = xmlSecBufferSetMaxSize(out, outSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferSetMaxSize", XMLSEC_ERRORS_R_XMLSEC_FAILED, "outSize=%d", outSize); return(-1); } if(transform->operation == xmlSecTransformOperationEncrypt) { PK11SymKey *aeskey = NULL; /* create key */ aeskey = xmlSecNssMakeAesKey(xmlSecBufferGetData(&(ctx->keyBuffer)), keySize, 1); /* encrypt */ if(aeskey == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecNssMakeAesKey", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } /* encrypt */ ret = xmlSecKWAesEncode(&xmlSecNssKWAesKlass, aeskey, xmlSecBufferGetData(in), inSize, xmlSecBufferGetData(out), outSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecKWAesEncode", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); PK11_FreeSymKey(aeskey); return(-1); } outSize = ret; PK11_FreeSymKey(aeskey); } else { PK11SymKey *aeskey = NULL; /* create key */ aeskey = xmlSecNssMakeAesKey(xmlSecBufferGetData(&(ctx->keyBuffer)), keySize, 0); /* decrypt */ if(aeskey == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecNssMakeAesKey", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } /* decrypt */ ret = xmlSecKWAesDecode(&xmlSecNssKWAesKlass, aeskey, xmlSecBufferGetData(in), inSize, xmlSecBufferGetData(out), outSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecKWAesDecode", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); PK11_FreeSymKey(aeskey); return(-1); } outSize = ret; PK11_FreeSymKey(aeskey); } ret = xmlSecBufferSetSize(out, outSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferSetSize", XMLSEC_ERRORS_R_XMLSEC_FAILED, "outSize=%d", outSize); return(-1); } ret = xmlSecBufferRemoveHead(in, inSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferRemoveHead", XMLSEC_ERRORS_R_XMLSEC_FAILED, "inSize%d", inSize); 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(&(transform->inBuf)) == 0, -1); } else { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_STATUS, "status=%d", transform->status); return(-1); } return(0); }
/** * xmlSecKeyDataBinaryValueBinRead: * @id: the data klass. * @key: the pointer to destination key. * @buf: the source binary buffer. * @bufSize: the source binary buffer size. * @keyInfoCtx: the pointer to <dsig:KeyInfo/> element processing context. * * Reads binary key data of the klass @id from @buf to the @key. * * Returns: 0 on success or a negative value otherwise. */ int xmlSecKeyDataBinaryValueBinRead(xmlSecKeyDataId id, xmlSecKeyPtr key, const xmlSecByte* buf, xmlSecSize bufSize, xmlSecKeyInfoCtxPtr keyInfoCtx) { xmlSecKeyDataPtr data; int ret; xmlSecAssert2(id != xmlSecKeyDataIdUnknown, -1); xmlSecAssert2(key != NULL, -1); xmlSecAssert2(buf != NULL, -1); xmlSecAssert2(bufSize > 0, -1); xmlSecAssert2(keyInfoCtx != NULL, -1); /* check do we have a key already */ data = xmlSecKeyGetValue(key); if(data != NULL) { xmlSecBufferPtr buffer; if(!xmlSecKeyDataCheckId(data, id)) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } buffer = xmlSecKeyDataBinaryValueGetBuffer(data); if((buffer != NULL) && ((xmlSecSize)xmlSecBufferGetSize(buffer) != bufSize)) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST, "cur-data-size=%d;new-data-size=%d", xmlSecBufferGetSize(buffer), bufSize); return(-1); } if((buffer != NULL) && (bufSize > 0) && (memcmp(xmlSecBufferGetData(buffer), buf, bufSize) != 0)) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST, "key already has a different value"); return(-1); } if(buffer != NULL) { /* we already have exactly the same key */ return(0); } /* we have binary key value with empty buffer */ } data = xmlSecKeyDataCreate(id); if(data == NULL ) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), "xmlSecKeyDataCreate", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } ret = xmlSecKeyDataBinaryValueSetBuffer(data, buf, bufSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), "xmlSecKeyDataBinaryValueSetBuffer", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", bufSize); xmlSecKeyDataDestroy(data); return(-1); } if(xmlSecKeyReqMatchKeyValue(&(keyInfoCtx->keyReq), data) != 1) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), "xmlSecKeyReqMatchKeyValue", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); xmlSecKeyDataDestroy(data); return(0); } ret = xmlSecKeySetValue(key, data); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), "xmlSecKeySetValue", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); xmlSecKeyDataDestroy(data); return(-1); } return(0); }
/** * xmlSecMSCryptoAppKeyLoad: * @filename: the key filename. * @format: the key file format. * @pwd: the key file password. * @pwdCallback: the key password callback. * @pwdCallbackCtx: the user context for password callback. * * Reads key from the a file. * * Returns pointer to the key or NULL if an error occurs. */ xmlSecKeyPtr xmlSecMSCryptoAppKeyLoad(const char *filename, xmlSecKeyDataFormat format, const char *pwd, void* pwdCallback, void* pwdCallbackCtx) { xmlSecBuffer buffer; xmlSecKeyPtr key = NULL; int ret; xmlSecAssert2(filename != NULL, NULL); xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL); switch (format) { case xmlSecKeyDataFormatPkcs12: key = xmlSecMSCryptoAppPkcs12Load(filename, pwd, pwdCallback, pwdCallbackCtx); if(key == NULL) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecMSCryptoAppPkcs12Load", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(NULL); } break; case xmlSecKeyDataFormatCertDer: ret = xmlSecBufferInitialize(&buffer, 0); if(ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecBufferInitialize", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(NULL); } ret = xmlSecBufferReadFile(&buffer, filename); if(ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecBufferReadFile", XMLSEC_ERRORS_R_XMLSEC_FAILED, "filename=%s", xmlSecErrorsSafeString(filename)); xmlSecBufferFinalize(&buffer); return (NULL); } key = xmlSecMSCryptoAppKeyLoadMemory(xmlSecBufferGetData(&buffer), xmlSecBufferGetSize(&buffer), format, pwd, pwdCallback, pwdCallbackCtx); if(key == NULL) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecMSCryptoAppKeyLoadMemory", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); xmlSecBufferFinalize(&buffer); return(NULL); } xmlSecBufferFinalize(&buffer); break; default: /* Any other format like PEM keys is currently not supported */ xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, NULL, XMLSEC_ERRORS_R_INVALID_FORMAT, "format=%d", format); return(NULL); } return(key); }
static int xmlSecMSCryptoDigestExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { xmlSecMSCryptoDigestCtxPtr ctx; xmlSecBufferPtr in, out; int ret; xmlSecAssert2(xmlSecMSCryptoDigestCheckId(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCryptoDigestSize), -1); xmlSecAssert2(transformCtx != NULL, -1); in = &(transform->inBuf); xmlSecAssert2(in != NULL, -1); out = &(transform->outBuf); xmlSecAssert2(out != NULL, -1); ctx = xmlSecMSCryptoDigestGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); if(transform->status == xmlSecTransformStatusNone) { ret = CryptCreateHash(ctx->provider, ctx->alg_id, 0, 0, &(ctx->mscHash)); if((ret == 0) || (ctx->mscHash == 0)) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "CryptCreateHash", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } transform->status = xmlSecTransformStatusWorking; } if (transform->status == xmlSecTransformStatusWorking) { xmlSecSize inSize; inSize = xmlSecBufferGetSize(in); if(inSize > 0) { ret = CryptHashData(ctx->mscHash, xmlSecBufferGetData(in), inSize, 0); if(ret == 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "CryptHashData", XMLSEC_ERRORS_R_CRYPTO_FAILED, "size=%d", inSize); return(-1); } ret = xmlSecBufferRemoveHead(in, inSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferRemoveHead", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", inSize); return(-1); } } if(last) { /* TODO: make a MSCrypto compatible assert here */ /* xmlSecAssert2((xmlSecSize)EVP_MD_size(ctx->digest) <= sizeof(ctx->dgst), -1); */ DWORD retLen; retLen = MSCRYPTO_MAX_HASH_SIZE; ret = CryptGetHashParam(ctx->mscHash, HP_HASHVAL, ctx->dgst, &retLen, 0); if (ret == 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "CryptGetHashParam(HP_HASHVAL)", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", MSCRYPTO_MAX_HASH_SIZE); return(-1); } ctx->dgstSize = (size_t)retLen; xmlSecAssert2(ctx->dgstSize > 0, -1); /* copy result to output */ if(transform->operation == xmlSecTransformOperationSign) { ret = xmlSecBufferAppend(out, ctx->dgst, ctx->dgstSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferAppend", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", ctx->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 { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_STATUS, "status=%d", transform->status); return(-1); } return(0); }
static int xmlSecBase64Execute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { xmlSecBase64CtxPtr ctx; xmlSecBufferPtr in, out; xmlSecSize inSize, outSize, outLen; int ret; xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformBase64Id), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationEncode) || (transform->operation == xmlSecTransformOperationDecode), -1); xmlSecAssert2(transformCtx != NULL, -1); ctx = xmlSecBase64GetCtx(transform); xmlSecAssert2(ctx != NULL, -1); in = &(transform->inBuf); out = &(transform->outBuf); if(transform->status == xmlSecTransformStatusNone) { ctx->encode = (transform->operation == xmlSecTransformOperationEncode) ? 1 : 0; transform->status = xmlSecTransformStatusWorking; } switch(transform->status) { case xmlSecTransformStatusWorking: inSize = xmlSecBufferGetSize(in); outSize = xmlSecBufferGetSize(out); if(inSize > 0) { if(ctx->encode != 0) { outLen = 4 * inSize / 3 + 8; if(ctx->columns > 0) { outLen += inSize / ctx->columns + 4; } } else { outLen = 3 * inSize / 4 + 8; } ret = xmlSecBufferSetMaxSize(out, outSize + outLen); if(ret < 0) { xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferSetMaxSize", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", outSize + outLen); return(-1); } /* encode/decode the next chunk */ ret = xmlSecBase64CtxUpdate(ctx, xmlSecBufferGetData(in), inSize, xmlSecBufferGetData(out) + outSize, outLen); if(ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBase64CtxUpdate", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } outLen = ret; /* set correct size */ ret = xmlSecBufferSetSize(out, outSize + outLen); if(ret < 0) { xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferSetSize", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", outSize + outLen); return(-1); } /* remove chunk from input */ ret = xmlSecBufferRemoveHead(in, inSize); if(ret < 0) { xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferRemoveHead", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", inSize); return(-1); } } if(last) { outSize = xmlSecBufferGetSize(out); ret = xmlSecBufferSetMaxSize(out, outSize + 16); if(ret < 0) { xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferSetMaxSize", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", outSize + 16); return(-1); } /* add from ctx buffer */ ret = xmlSecBase64CtxFinal(ctx, xmlSecBufferGetData(out) + outSize, 16); if(ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBase64CtxFinal", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } outLen = ret; /* set correct size */ ret = xmlSecBufferSetSize(out, outSize + outLen); if(ret < 0) { xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferSetSize", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", outSize + outLen); return(-1); } transform->status = xmlSecTransformStatusFinished; } break; case xmlSecTransformStatusFinished: /* the only way we can get here is if there is no input */ xmlSecAssert2(xmlSecBufferGetSize(in) == 0, -1); break; default: xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_STATUS, "status=%d", transform->status); return(-1); } return(0); }
static int xmlSecOpenSSLEvpSignatureExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { xmlSecOpenSSLEvpSignatureCtxPtr ctx; xmlSecBufferPtr in, out; xmlSecSize inSize; xmlSecSize outSize; int ret; xmlSecAssert2(xmlSecOpenSSLEvpSignatureCheckId(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLEvpSignatureSize), -1); xmlSecAssert2(transformCtx != NULL, -1); ctx = xmlSecOpenSSLEvpSignatureGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); in = &(transform->inBuf); out = &(transform->outBuf); inSize = xmlSecBufferGetSize(in); outSize = xmlSecBufferGetSize(out); ctx = xmlSecOpenSSLEvpSignatureGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->digest != NULL, -1); xmlSecAssert2(ctx->pKey != NULL, -1); if(transform->status == xmlSecTransformStatusNone) { xmlSecAssert2(outSize == 0, -1); if(transform->operation == xmlSecTransformOperationSign) { #ifndef XMLSEC_OPENSSL_096 ret = EVP_SignInit(&(ctx->digestCtx), ctx->digest); if(ret != 1) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "EVP_SignInit", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } #else /* XMLSEC_OPENSSL_096 */ EVP_SignInit(&(ctx->digestCtx), ctx->digest); #endif /* XMLSEC_OPENSSL_096 */ } else { #ifndef XMLSEC_OPENSSL_096 ret = EVP_VerifyInit(&(ctx->digestCtx), ctx->digest); if(ret != 1) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "EVP_VerifyInit", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } #else /* XMLSEC_OPENSSL_096 */ EVP_VerifyInit(&(ctx->digestCtx), ctx->digest); #endif /* XMLSEC_OPENSSL_096 */ } transform->status = xmlSecTransformStatusWorking; } if((transform->status == xmlSecTransformStatusWorking) && (inSize > 0)) { xmlSecAssert2(outSize == 0, -1); if(transform->operation == xmlSecTransformOperationSign) { #ifndef XMLSEC_OPENSSL_096 ret = EVP_SignUpdate(&(ctx->digestCtx), xmlSecBufferGetData(in), inSize); if(ret != 1) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "EVP_SignUpdate", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } #else /* XMLSEC_OPENSSL_096 */ EVP_SignUpdate(&(ctx->digestCtx), xmlSecBufferGetData(in), inSize); #endif /* XMLSEC_OPENSSL_096 */ } else { #ifndef XMLSEC_OPENSSL_096 ret = EVP_VerifyUpdate(&(ctx->digestCtx), xmlSecBufferGetData(in), inSize); if(ret != 1) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "EVP_VerifyUpdate", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } #else /* XMLSEC_OPENSSL_096 */ EVP_VerifyUpdate(&(ctx->digestCtx), xmlSecBufferGetData(in), inSize); #endif /* XMLSEC_OPENSSL_096 */ } ret = xmlSecBufferRemoveHead(in, inSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferRemoveHead", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } } if((transform->status == xmlSecTransformStatusWorking) && (last != 0)) { xmlSecAssert2(outSize == 0, -1); if(transform->operation == xmlSecTransformOperationSign) { unsigned int signSize; /* this is a hack: for rsa signatures * we get size from EVP_PKEY_size(), * for dsa signature we use a fixed constant */ signSize = EVP_PKEY_size(ctx->pKey); #ifndef XMLSEC_NO_DSA if(signSize < XMLSEC_OPENSSL_DSA_SIGNATURE_SIZE) { signSize = XMLSEC_OPENSSL_DSA_SIGNATURE_SIZE; } #endif /* XMLSEC_NO_DSA */ ret = xmlSecBufferSetMaxSize(out, signSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferSetMaxSize", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%u", signSize); return(-1); } ret = EVP_SignFinal(&(ctx->digestCtx), xmlSecBufferGetData(out), &signSize, ctx->pKey); if(ret != 1) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "EVP_SignFinal", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } ret = xmlSecBufferSetSize(out, signSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferSetSize", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%u", signSize); return(-1); } } transform->status = xmlSecTransformStatusFinished; } if((transform->status == xmlSecTransformStatusWorking) || (transform->status == xmlSecTransformStatusFinished)) { /* the only way we can get here is if there is no input */ xmlSecAssert2(xmlSecBufferGetSize(&(transform->inBuf)) == 0, -1); } else { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_STATUS, "status=%d", transform->status); return(-1); } return(0); }
static int xmlSecOpenSSLEvpDigestExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { xmlSecOpenSSLDigestCtxPtr ctx; xmlSecBufferPtr in, out; int ret; xmlSecAssert2(xmlSecOpenSSLEvpDigestCheckId(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLEvpDigestSize), -1); xmlSecAssert2(transformCtx != NULL, -1); in = &(transform->inBuf); xmlSecAssert2(in != NULL, -1); out = &(transform->outBuf); xmlSecAssert2(out != NULL, -1); ctx = xmlSecOpenSSLEvpDigestGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->digest != NULL, -1); if(transform->status == xmlSecTransformStatusNone) { #ifndef XMLSEC_OPENSSL_096 ret = EVP_DigestInit(&(ctx->digestCtx), ctx->digest); if(ret != 1) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "EVP_DigestInit", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } #else /* XMLSEC_OPENSSL_096 */ EVP_DigestInit(&(ctx->digestCtx), ctx->digest); #endif /* XMLSEC_OPENSSL_096 */ transform->status = xmlSecTransformStatusWorking; } if(transform->status == xmlSecTransformStatusWorking) { xmlSecSize inSize; inSize = xmlSecBufferGetSize(in); if(inSize > 0) { #ifndef XMLSEC_OPENSSL_096 ret = EVP_DigestUpdate(&(ctx->digestCtx), xmlSecBufferGetData(in), inSize); if(ret != 1) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "EVP_DigestUpdate", XMLSEC_ERRORS_R_CRYPTO_FAILED, "size=%d", inSize); return(-1); } #else /* XMLSEC_OPENSSL_096 */ EVP_DigestUpdate(&(ctx->digestCtx), xmlSecBufferGetData(in), inSize); #endif /* XMLSEC_OPENSSL_096 */ 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) { xmlSecAssert2((xmlSecSize)EVP_MD_size(ctx->digest) <= sizeof(ctx->dgst), -1); #ifndef XMLSEC_OPENSSL_096 ret = EVP_DigestFinal(&(ctx->digestCtx), ctx->dgst, &ctx->dgstSize); if(ret != 1) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "EVP_DigestFinal", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } #else /* XMLSEC_OPENSSL_096 */ EVP_DigestFinal(&(ctx->digestCtx), ctx->dgst, &ctx->dgstSize); #endif /* XMLSEC_OPENSSL_096 */ xmlSecAssert2(ctx->dgstSize > 0, -1); /* copy result to output */ if(transform->operation == xmlSecTransformOperationSign) { ret = xmlSecBufferAppend(out, ctx->dgst, ctx->dgstSize); if(ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferAppend", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", ctx->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 xmlSecGCryptDigestExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { xmlSecGCryptDigestCtxPtr ctx; xmlSecBufferPtr in, out; int ret; xmlSecAssert2(xmlSecGCryptDigestCheckId(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); xmlSecAssert2(transformCtx != NULL, -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGCryptDigestSize), -1); ctx = xmlSecGCryptDigestGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->digest != GCRY_MD_NONE, -1); xmlSecAssert2(ctx->digestCtx != NULL, -1); in = &(transform->inBuf); out = &(transform->outBuf); if(transform->status == xmlSecTransformStatusNone) { transform->status = xmlSecTransformStatusWorking; } if(transform->status == xmlSecTransformStatusWorking) { xmlSecSize inSize; inSize = xmlSecBufferGetSize(in); if(inSize > 0) { gcry_md_write(ctx->digestCtx, xmlSecBufferGetData(in), inSize); ret = xmlSecBufferRemoveHead(in, inSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferRemoveHead", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", inSize); return(-1); } } if(last != 0) { xmlSecByte* buf; /* get the final digest */ gcry_md_final(ctx->digestCtx); buf = gcry_md_read(ctx->digestCtx, ctx->digest); if(buf == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "gcry_md_read", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } /* copy it to our internal buffer */ ctx->dgstSize = gcry_md_get_algo_dlen(ctx->digest); xmlSecAssert2(ctx->dgstSize > 0, -1); xmlSecAssert2(ctx->dgstSize <= sizeof(ctx->dgst), -1); memcpy(ctx->dgst, buf, ctx->dgstSize); /* and to the output if needed */ if(transform->operation == xmlSecTransformOperationSign) { ret = xmlSecBufferAppend(out, ctx->dgst, ctx->dgstSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferAppend", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", ctx->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(&(transform->inBuf)) == 0, -1); } else { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_STATUS, "status=%d", transform->status); return(-1); } return(0); }
static int xmlSecNssDigestExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { xmlSecNssDigestCtxPtr ctx; xmlSecBufferPtr in, out; SECStatus rv; int ret; xmlSecAssert2(xmlSecNssDigestCheckId(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); xmlSecAssert2(transformCtx != NULL, -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssDigestSize), -1); ctx = xmlSecNssDigestGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->digestCtx != NULL, -1); in = &(transform->inBuf); out = &(transform->outBuf); if(transform->status == xmlSecTransformStatusNone) { rv = PK11_DigestBegin(ctx->digestCtx); if(rv != SECSuccess) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "PK11_DigestBegin", XMLSEC_ERRORS_R_CRYPTO_FAILED, "error code=%d", PORT_GetError()); return(-1); } transform->status = xmlSecTransformStatusWorking; } if(transform->status == xmlSecTransformStatusWorking) { xmlSecSize inSize; inSize = xmlSecBufferGetSize(in); if(inSize > 0) { rv = PK11_DigestOp(ctx->digestCtx, xmlSecBufferGetData(in), inSize); if (rv != SECSuccess) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "PK11_DigestOp", XMLSEC_ERRORS_R_CRYPTO_FAILED, "error code=%d", PORT_GetError()); return(-1); } ret = xmlSecBufferRemoveHead(in, inSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferRemoveHead", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", inSize); return(-1); } } if(last) { unsigned int dgstSize; rv = PK11_DigestFinal(ctx->digestCtx, ctx->dgst, &dgstSize, sizeof(ctx->dgst)); if(rv != SECSuccess) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "PK11_DigestFinal", XMLSEC_ERRORS_R_CRYPTO_FAILED, "error code=%d", PORT_GetError()); return(-1); } xmlSecAssert2(dgstSize > 0, -1); ctx->dgstSize = XMLSEC_SIZE_BAD_CAST(dgstSize); if(transform->operation == xmlSecTransformOperationSign) { ret = xmlSecBufferAppend(out, ctx->dgst, ctx->dgstSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferAppend", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", ctx->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(&(transform->inBuf)) == 0, -1); } else { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_STATUS, "status=%d", transform->status); return(-1); } return(0); }
/** * xmlSecBnGetData: * @bn: the pointer to BN. * * Gets pointer to the binary @bn representation. * * Returns pointer to binary BN data or NULL if an error occurs. */ EXPORT_C xmlSecByte* xmlSecBnGetData(xmlSecBnPtr bn) { return(xmlSecBufferGetData(bn)); }
/** * xmlSecEncCtxDebugXmlDump: * @encCtx: the pointer to <enc:EncryptedData/> processing context. * @output: the pointer to output FILE. * * Prints the debug information about @encCtx to @output in XML format. */ void xmlSecEncCtxDebugXmlDump(xmlSecEncCtxPtr encCtx, FILE* output) { xmlSecAssert(encCtx != NULL); xmlSecAssert(output != NULL); switch(encCtx->mode) { case xmlEncCtxModeEncryptedData: if(encCtx->operation == xmlSecTransformOperationEncrypt) { fprintf(output, "<DataEncryptionContext "); } else { fprintf(output, "<DataDecryptionContext "); } break; case xmlEncCtxModeEncryptedKey: if(encCtx->operation == xmlSecTransformOperationEncrypt) { fprintf(output, "<KeyEncryptionContext "); } else { fprintf(output, "<KeyDecryptionContext "); } break; } fprintf(output, "status=\"%s\" >\n", (encCtx->resultReplaced) ? "replaced" : "not-replaced" ); fprintf(output, "<Flags>%08x</Flags>\n", encCtx->flags); fprintf(output, "<Flags2>%08x</Flags2>\n", encCtx->flags2); fprintf(output, "<Id>"); xmlSecPrintXmlString(output, encCtx->id); fprintf(output, "</Id>"); fprintf(output, "<Type>"); xmlSecPrintXmlString(output, encCtx->type); fprintf(output, "</Type>"); fprintf(output, "<MimeType>"); xmlSecPrintXmlString(output, encCtx->mimeType); fprintf(output, "</MimeType>"); fprintf(output, "<Encoding>"); xmlSecPrintXmlString(output, encCtx->encoding); fprintf(output, "</Encoding>"); fprintf(output, "<Recipient>"); xmlSecPrintXmlString(output, encCtx->recipient); fprintf(output, "</Recipient>"); fprintf(output, "<CarriedKeyName>"); xmlSecPrintXmlString(output, encCtx->carriedKeyName); fprintf(output, "</CarriedKeyName>"); fprintf(output, "<KeyInfoReadCtx>\n"); xmlSecKeyInfoCtxDebugXmlDump(&(encCtx->keyInfoReadCtx), output); fprintf(output, "</KeyInfoReadCtx>\n"); fprintf(output, "<KeyInfoWriteCtx>\n"); xmlSecKeyInfoCtxDebugXmlDump(&(encCtx->keyInfoWriteCtx), output); fprintf(output, "</KeyInfoWriteCtx>\n"); fprintf(output, "<EncryptionTransformCtx>\n"); xmlSecTransformCtxDebugXmlDump(&(encCtx->transformCtx), output); fprintf(output, "</EncryptionTransformCtx>\n"); if(encCtx->encMethod != NULL) { fprintf(output, "<EncryptionMethod>\n"); xmlSecTransformDebugXmlDump(encCtx->encMethod, output); fprintf(output, "</EncryptionMethod>\n"); } if(encCtx->encKey != NULL) { fprintf(output, "<EncryptionKey>\n"); xmlSecKeyDebugXmlDump(encCtx->encKey, output); fprintf(output, "</EncryptionKey>\n"); } if((encCtx->result != NULL) && (xmlSecBufferGetData(encCtx->result) != NULL) && (encCtx->resultBase64Encoded != 0)) { fprintf(output, "<Result>"); fwrite(xmlSecBufferGetData(encCtx->result), xmlSecBufferGetSize(encCtx->result), 1, output); fprintf(output, "</Result>\n"); } switch(encCtx->mode) { case xmlEncCtxModeEncryptedData: if(encCtx->operation == xmlSecTransformOperationEncrypt) { fprintf(output, "</DataEncryptionContext>\n"); } else { fprintf(output, "</DataDecryptionContext>\n"); } break; case xmlEncCtxModeEncryptedKey: if(encCtx->operation == xmlSecTransformOperationEncrypt) { fprintf(output, "</KeyEncryptionContext>\n"); } else { fprintf(output, "</KeyDecryptionContext>\n"); } break; } }
/** * xmlSecBnFromString: * @bn: the pointer to BN. * @str: the string with BN. * @base: the base for @str. * * Reads @bn from string @str assuming it has base @base. * * Returns 0 on success or a negative value if an error occurs. */ EXPORT_C int xmlSecBnFromString(xmlSecBnPtr bn, const xmlChar* str, xmlSecSize base) { xmlSecSize i, len, size; xmlSecByte ch; xmlSecByte* data; int positive; int nn; int ret; xmlSecAssert2(bn != NULL, -1); xmlSecAssert2(str != NULL, -1); xmlSecAssert2(base > 1, -1); xmlSecAssert2(base <= sizeof(xmlSecBnRevLookupTable), -1); /* trivial case */ len = xmlStrlen(str); if(len == 0) { return(0); } /* The result size could not exceed the input string length * because each char fits inside a byte in all cases :) * In truth, it would be likely less than 1/2 input string length * because each byte is represented by 2 chars. If needed, * buffer size would be increased by Mul/Add functions. * Finally, we can add one byte for 00 or 10 prefix. */ ret = xmlSecBufferSetMaxSize(bn, xmlSecBufferGetSize(bn) + len / 2 + 1 + 1); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecBnRevLookupTable", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", len / 2 + 1); return (-1); } /* figure out if it is positive or negative number */ positive = 1; i = 0; while(i < len) { ch = str[i++]; /* skip spaces */ if(isspace(ch)) { continue; } /* check if it is + or - */ if(ch == '+') { positive = 1; break; } else if(ch == '-') { positive = 0; break; } /* otherwise, it must be start of the number */ nn = xmlSecBnLookupTable[ch]; if((nn >= 0) && ((xmlSecSize)nn < base)) { xmlSecAssert2(i > 0, -1); /* no sign, positive by default */ positive = 1; --i; /* make sure that we will look at this character in next loop */ break; } else { xmlSecError(XMLSEC_ERRORS_HERE, NULL, NULL, XMLSEC_ERRORS_R_INVALID_DATA, "char=%c;base=%d", ch, base); return (-1); } } /* now parse the number itself */ while(i < len) { ch = str[i++]; if(isspace(ch)) { continue; } xmlSecAssert2(ch <(sizeof(xmlSecBnLookupTable)/sizeof(xmlSecBnLookupTable[0])), -1); nn = xmlSecBnLookupTable[ch]; if((nn < 0) || ((xmlSecSize)nn > base)) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, NULL, XMLSEC_ERRORS_R_INVALID_DATA, "char=%c;base=%d", ch, base); return (-1); } ret = xmlSecBnMul(bn, base); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecBnMul", XMLSEC_ERRORS_R_XMLSEC_FAILED, "base=%d", base); return (-1); } ret = xmlSecBnAdd(bn, nn); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecBnAdd", XMLSEC_ERRORS_R_XMLSEC_FAILED, "base=%d", base); return (-1); } } /* check if we need to add 00 prefix, do this for empty bn too */ data = xmlSecBufferGetData(bn); size = xmlSecBufferGetSize(bn); if(((size > 0) && (data[0] > 127)) || (size == 0)) { ch = 0; ret = xmlSecBufferPrepend(bn, &ch, 1); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecBufferPrepend", XMLSEC_ERRORS_R_XMLSEC_FAILED, "base=%d", base); return (-1); } } /* do 2's compliment and add 1 to represent negative value */ if(positive == 0) { data = xmlSecBufferGetData(bn); size = xmlSecBufferGetSize(bn); for(i = 0; i < size; ++i) { data[i] ^= 0xFF; } ret = xmlSecBnAdd(bn, 1); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecBnAdd", XMLSEC_ERRORS_R_XMLSEC_FAILED, "base=%d", base); return (-1); } } return(0); }
static int xmlSecGCryptKWDes3Execute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { xmlSecGCryptKWDes3CtxPtr ctx; xmlSecBufferPtr in, out; xmlSecSize inSize, outSize, keySize; int ret; xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecGCryptTransformKWDes3Id), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGCryptKWDes3Size), -1); xmlSecAssert2(transformCtx != NULL, -1); ctx = xmlSecGCryptKWDes3GetCtx(transform); xmlSecAssert2(ctx != NULL, -1); keySize = xmlSecBufferGetSize(&(ctx->keyBuffer)); xmlSecAssert2(keySize == XMLSEC_KW_DES3_KEY_LENGTH, -1); in = &(transform->inBuf); out = &(transform->outBuf); inSize = xmlSecBufferGetSize(in); outSize = xmlSecBufferGetSize(out); xmlSecAssert2(outSize == 0, -1); if(transform->status == xmlSecTransformStatusNone) { transform->status = xmlSecTransformStatusWorking; } if((transform->status == xmlSecTransformStatusWorking) && (last == 0)) { /* just do nothing */ } else if((transform->status == xmlSecTransformStatusWorking) && (last != 0)) { if((inSize % XMLSEC_KW_DES3_BLOCK_LENGTH) != 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_SIZE, "%d bytes - not %d bytes aligned", inSize, XMLSEC_KW_DES3_BLOCK_LENGTH); return(-1); } if(transform->operation == xmlSecTransformOperationEncrypt) { /* the encoded key might be 16 bytes longer plus one block just in case */ outSize = inSize + XMLSEC_KW_DES3_IV_LENGTH + XMLSEC_KW_DES3_BLOCK_LENGTH + XMLSEC_KW_DES3_BLOCK_LENGTH; } else { /* just in case, add a block */ outSize = inSize + XMLSEC_KW_DES3_BLOCK_LENGTH; } ret = xmlSecBufferSetMaxSize(out, outSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferSetMaxSize", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", outSize); return(-1); } if(transform->operation == xmlSecTransformOperationEncrypt) { ret = xmlSecKWDes3Encode(&xmlSecGCryptKWDes3ImplKlass, ctx, xmlSecBufferGetData(in), inSize, xmlSecBufferGetData(out), outSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecKWDes3Encode", XMLSEC_ERRORS_R_XMLSEC_FAILED, "key=%d,in=%d,out=%d", keySize, inSize, outSize); return(-1); } outSize = ret; } else { ret = xmlSecKWDes3Decode(&xmlSecGCryptKWDes3ImplKlass, ctx, xmlSecBufferGetData(in), inSize, xmlSecBufferGetData(out), outSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecKWDes3Decode", XMLSEC_ERRORS_R_XMLSEC_FAILED, "key=%d,in=%d,out=%d", keySize, inSize, outSize); return(-1); } outSize = ret; } ret = xmlSecBufferSetSize(out, outSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferSetSize", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", outSize); return(-1); } ret = xmlSecBufferRemoveHead(in, inSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferRemoveHead", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", inSize); 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(&(transform->inBuf)) == 0, -1); } else { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_STATUS, "status=%d", transform->status); return(-1); } return(0); }
/** * xmlSecBnToString: * @bn: the pointer to BN. * @base: the base for returned string. * * Writes @bn to string with base @base. Caller is responsible for * freeing returned string with @xmlFree. * * Returns the string represenataion if BN or a NULL if an error occurs. */ EXPORT_C xmlChar* xmlSecBnToString(xmlSecBnPtr bn, xmlSecSize base) { xmlSecBn bn2; int positive = 1; xmlChar* res; xmlSecSize i, len, size; xmlSecByte* data; int ret; int nn; xmlChar ch; xmlSecAssert2(bn != NULL, NULL); xmlSecAssert2(base > 1, NULL); xmlSecAssert2(base <= sizeof(xmlSecBnRevLookupTable), NULL); /* copy bn */ data = xmlSecBufferGetData(bn); size = xmlSecBufferGetSize(bn); ret = xmlSecBnInitialize(&bn2, size); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecBnCreate", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", size); return (NULL); } ret = xmlSecBnSetData(&bn2, data, size); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecBnSetData", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", size); xmlSecBnFinalize(&bn2); return (NULL); } /* check if it is a negative number or not */ data = xmlSecBufferGetData(&bn2); size = xmlSecBufferGetSize(&bn2); if((size > 0) && (data[0] > 127)) { /* subtract 1 and do 2's compliment */ ret = xmlSecBnAdd(&bn2, -1); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecBnAdd", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", size); xmlSecBnFinalize(&bn2); return (NULL); } for(i = 0; i < size; ++i) { data[i] ^= 0xFF; } positive = 0; } else { positive = 1; } /* Result string len is * len = log base (256) * <bn size> * Since the smallest base == 2 then we can get away with * len = 8 * <bn size> */ len = 8 * size + 1 + 1; res = (xmlChar*)xmlMalloc(len + 1); if(res == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, NULL, XMLSEC_ERRORS_R_MALLOC_FAILED, "len=%d", len); xmlSecBnFinalize(&bn2); return (NULL); } memset(res, 0, len + 1); for(i = 0; (xmlSecBufferGetSize(&bn2) > 0) && (i < len); i++) { if(xmlSecBnDiv(&bn2, base, &nn) < 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecBnDiv", XMLSEC_ERRORS_R_XMLSEC_FAILED, "base=%d", base); xmlFree(res); xmlSecBnFinalize(&bn2); return (NULL); } if(nn >=(sizeof(xmlSecBnRevLookupTable)/sizeof(xmlSecBnRevLookupTable[0]))) { xmlFree(res); return (NULL); } res[i] = xmlSecBnRevLookupTable[nn]; } if(i >=len) { xmlFree(res); return (NULL); } /* we might have '0' at the beggining, remove it but keep one zero */ for(len = i; (len > 1) && (res[len - 1] == '0'); len--) { }; res[len] = '\0'; /* add "-" for negative numbers */ if(positive == 0) { res[len] = '-'; res[++len] = '\0'; } /* swap the string because we wrote it in reverse order */ for(i = 0; i < len / 2; i++) { ch = res[i]; res[i] = res[len - i - 1]; res[len - i - 1] = ch; } xmlSecBnFinalize(&bn2); return(res); }
/** * decrypt_file: * @mngr: the pointer to keys manager. * @enc_file: the encrypted XML file name. * * Decrypts the XML file #enc_file using DES key from #key_file and * prints results to stdout. * * Returns 0 on success or a negative value if an error occurs. */ int decrypt_file(xmlSecKeysMngrPtr mngr, const char* enc_file) { xmlDocPtr doc = NULL; xmlNodePtr node = NULL; xmlSecEncCtxPtr encCtx = NULL; int res = -1; assert(mngr); assert(enc_file); /* load template */ doc = xmlParseFile(enc_file); if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){ fprintf(stderr, "Error: unable to parse file \"%s\"\n", enc_file); goto done; } /* find start node */ node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeEncryptedData, xmlSecEncNs); if(node == NULL) { fprintf(stderr, "Error: start node not found in \"%s\"\n", enc_file); goto done; } /* create encryption context */ encCtx = xmlSecEncCtxCreate(mngr); if(encCtx == NULL) { fprintf(stderr,"Error: failed to create encryption context\n"); goto done; } /* decrypt the data */ if((xmlSecEncCtxDecrypt(encCtx, node) < 0) || (encCtx->result == NULL)) { fprintf(stderr,"Error: decryption failed\n"); goto done; } /* print decrypted data to stdout */ if(encCtx->resultReplaced != 0) { fprintf(stdout, "Decrypted XML data:\n"); xmlDocDump(stdout, doc); } else { fprintf(stdout, "Decrypted binary data (%d bytes):\n", xmlSecBufferGetSize(encCtx->result)); if(xmlSecBufferGetData(encCtx->result) != NULL) { fwrite(xmlSecBufferGetData(encCtx->result), 1, xmlSecBufferGetSize(encCtx->result), stdout); } } fprintf(stdout, "\n"); /* success */ res = 0; done: /* cleanup */ if(encCtx != NULL) { xmlSecEncCtxDestroy(encCtx); } if(doc != NULL) { xmlFreeDoc(doc); } return(res); }
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); }