diff --git a/apps/xmlsec.c b/apps/xmlsec.c index 9620fb30e..0c13445f1 100644 --- a/apps/xmlsec.c +++ b/apps/xmlsec.c @@ -8,6 +8,7 @@ #include #include #include +#include #if defined(_MSC_VER) && _MSC_VER < 1900 #define snprintf _snprintf @@ -18,6 +19,7 @@ #include #include #include +#include #ifndef XMLSEC_NO_XSLT #include @@ -1316,16 +1318,9 @@ xmlSecAppSignFile(const char* filename) { total_time += clock() - start_time; if(repeats <= 1) { - FILE* f; - - f = xmlSecAppOpenFile(xmlSecAppCmdLineParamGetString(&outputParam)); - if(f == NULL) { - fprintf(stderr,"Error: failed to open output file \"%s\"\n", - xmlSecAppCmdLineParamGetString(&outputParam)); + if(xmlSecAppWriteResult(data->doc, NULL) < 0) { goto done; } - xmlDocDump(f, data->doc); - xmlSecAppCloseFile(f); } res = 0; @@ -1368,7 +1363,7 @@ xmlSecAppVerifyFile(const char* filename) { goto done; } - /* sign */ + /* verify */ start_time = clock(); if(xmlSecDSigCtxVerify(&dsigCtx, data->startNode) < 0) { fprintf(stderr,"Error: signature failed \n"); @@ -1376,29 +1371,14 @@ xmlSecAppVerifyFile(const char* filename) { } total_time += clock() - start_time; - if((repeats <= 1) && (dsigCtx.status != xmlSecDSigStatusSucceeded)){ + if((repeats <= 1) && (dsigCtx.status != xmlSecDSigStatusSucceeded)) { /* return an error if signature does not match */ goto done; } - if(repeats <= 1) { - FILE* f; - - /* - * Note: the output file must be opened before the "done:" label. - * Otherwise a failed open would "goto done" and re-enter this block, - * retrying the same failing open forever. - */ - f = xmlSecAppOpenFile(xmlSecAppCmdLineParamGetString(&outputParam)); - if(f == NULL) { - fprintf(stderr,"Error: failed to open output file \"%s\"\n", - xmlSecAppCmdLineParamGetString(&outputParam)); - goto done; - } - xmlSecAppCloseFile(f); - } - + /* success */ res = 0; + done: /* print debug info if requested */ if(repeats <= 1) { @@ -1549,16 +1529,9 @@ xmlSecAppSignTmpl(void) { total_time += clock() - start_time; if(repeats <= 1) { - FILE* f; - - f = xmlSecAppOpenFile(xmlSecAppCmdLineParamGetString(&outputParam)); - if(f == NULL) { - fprintf(stderr,"Error: failed to open output file \"%s\"\n", - xmlSecAppCmdLineParamGetString(&outputParam)); + if(xmlSecAppWriteResult(doc, NULL) < 0) { goto done; } - xmlDocDump(f, doc); - xmlSecAppCloseFile(f); } res = 0; @@ -3073,21 +3046,67 @@ xmlSecAppCloseFile(FILE* file) { static int xmlSecAppWriteResult(xmlDocPtr doc, xmlSecBufferPtr buffer) { FILE* f; + xmlOutputBufferPtr outBuffer; + int ret; f = xmlSecAppOpenFile(xmlSecAppCmdLineParamGetString(&outputParam)); if(f == NULL) { return(-1); } + + outBuffer = xmlOutputBufferCreateFile(f, NULL); + if(outBuffer == NULL) { + fprintf(stderr, "Error: failed to create output buffer\n"); + xmlSecAppCloseFile(f); + return(-1); + } + + /* dump output */ if(doc != NULL) { - xmlDocDump(f, doc); - } else if((buffer != NULL) && (xmlSecBufferGetData(buffer) != NULL)) { - (void)fwrite(xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer), 1, f); + ret = xmlSaveFileTo(outBuffer, doc, (const char*)doc->encoding); + if (ret < 0) { + fprintf(stderr, "Error: failed to write xml output\n"); + /* xmlSaveFileTo closes the buffer and the file */ + return(-1); + } + /* xmlSaveFileTo closes the buffer and the file */ + } else if(buffer != NULL) { + xmlSecSize bufSize; + const xmlSecByte* bufData; + + bufData = xmlSecBufferGetData(buffer); + bufSize = xmlSecBufferGetSize(buffer); + if((bufData == NULL) && (bufSize != 0)) { + fprintf(stderr, "Error: buffer data is NULL but buffer size is not zero\n"); + /* xmlOutputBufferClose closes the file */ + (void)xmlOutputBufferClose(outBuffer); + return(-1); + } + if(bufSize > (size_t)INT_MAX) { + fprintf(stderr, "Error: binary output size exceeds int limit\n"); + /* xmlOutputBufferClose closes the file */ + (void)xmlOutputBufferClose(outBuffer); + return(-1); + } + if(bufData != NULL) { + ret = xmlOutputBufferWrite(outBuffer, (int)bufSize, (const char*)bufData); + if (ret < 0) { + /* xmlOutputBufferClose closes the file */ + fprintf(stderr, "Error: failed to write binary output\n"); + (void)xmlOutputBufferClose(outBuffer); + return(-1); + } + } + /* xmlOutputBufferClose closes the file */ + (void)xmlOutputBufferClose(outBuffer); } else { fprintf(stderr, "Error: both result doc and result buffer are null\n"); - xmlSecAppCloseFile(f); + /* xmlOutputBufferClose closes the file */ + (void)xmlOutputBufferClose(outBuffer); return(-1); } - xmlSecAppCloseFile(f); + + /* done */ return(0); } diff --git a/src/bn.c b/src/bn.c index 41b84b3ad..893811687 100644 --- a/src/bn.c +++ b/src/bn.c @@ -825,6 +825,9 @@ xmlSecBnGetNodeValue(xmlSecBnPtr bn, xmlNodePtr cur, xmlSecBnFormat format, int } xmlFree(content); break; + default: + xmlSecInvalidDataError("unsupported BN format", NULL); + return(-1); } if(reverse != 0) { @@ -897,6 +900,10 @@ xmlSecBnSetNodeValue(xmlSecBnPtr bn, xmlNodePtr cur, xmlSecBnFormat format, int xmlNodeSetContent(cur, content); xmlFree(content); break; + default: + /* invalid format */ + xmlSecInvalidDataError("unsupported BN format", NULL); + return(-1); } if(addLineBreaks) { diff --git a/src/c14n.c b/src/c14n.c index f51739216..bfb4671a5 100644 --- a/src/c14n.c +++ b/src/c14n.c @@ -278,11 +278,10 @@ xmlSecTransformC14NPopBin(xmlSecTransformPtr transform, xmlSecByte* data, xmlSecAssert2(transform->inNodes == NULL, -1); - /* todo: isn't it an error? */ + /* a C14N transform with no previous transform has no input to canonicalize */ if(transform->prev == NULL) { - (*dataSize) = 0; - transform->status = xmlSecTransformStatusFinished; - return(0); + xmlSecInternalError("xmlSecTransformC14NPopBin", xmlSecTransformGetName(transform)); + return(-1); } /* get xml data from previous transform */ diff --git a/src/dl.c b/src/dl.c index bff80650c..c6f81b751 100644 --- a/src/dl.c +++ b/src/dl.c @@ -391,6 +391,12 @@ int xmlSecCryptoDLShutdown(void) { int ret; + if(!xmlSecPtrListIsValid(&gXmlSecCryptoDLLibraries)) { + /* the dynamic loading engine was not initialized */ + gXmlSecCryptoDLFunctions = NULL; + return(0); + } + xmlSecPtrListFinalize(&gXmlSecCryptoDLLibraries); gXmlSecCryptoDLFunctions = NULL; diff --git a/src/gnutls/asymkeys.c b/src/gnutls/asymkeys.c index 35cb5f536..b68e28e2c 100644 --- a/src/gnutls/asymkeys.c +++ b/src/gnutls/asymkeys.c @@ -312,7 +312,11 @@ xmlSecGnuTLSKeyDataRsaAdoptPrivateKey(xmlSecKeyDataPtr data, gnutls_x509_privkey /* First check that p < q; if not swap p and q and recompute u. */ if (gcry_mpi_cmp(mpis[3], mpis[4]) > 0) { gcry_mpi_swap(mpis[3], mpis[4]); - gcry_mpi_invm(mpis[5], mpis[3], mpis[4]); + if(!gcry_mpi_invm(mpis[5], mpis[3], mpis[4])) { + xmlSecGnuTLSGCryptError("gcry_mpi_invm", (gcry_error_t)GPG_ERR_NO_ERROR, NULL); + xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0])); + return(-1); + } } /* build expressions */ diff --git a/src/io.c b/src/io.c index b839f7271..c3d883413 100644 --- a/src/io.c +++ b/src/io.c @@ -603,6 +603,7 @@ xmlSecTransformInputURIOpen(xmlSecTransformPtr transform, const xmlChar *uri) { int xmlSecTransformInputURIClose(xmlSecTransformPtr transform) { xmlSecInputURICtxPtr ctx; + int ret; xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformInputURIId), -1); @@ -611,7 +612,14 @@ xmlSecTransformInputURIClose(xmlSecTransformPtr transform) { /* close if still open and mark as closed */ if((ctx->clbksCtx != NULL) && (ctx->clbks != NULL) && (ctx->clbks->closecallback != NULL)) { - (ctx->clbks->closecallback)(ctx->clbksCtx); + ret = (ctx->clbks->closecallback)(ctx->clbksCtx); + if(ret != 0) { + xmlSecIOError("ctx->clbks->closecallback", xmlSecTransformGetName(transform), NULL); + /* mark as closed to prevent a second close attempt on finalize */ + ctx->clbksCtx = NULL; + ctx->clbks = NULL; + return(-1); + } } ctx->clbksCtx = NULL; ctx->clbks = NULL; diff --git a/src/keyinfo.c b/src/keyinfo.c index c43208401..fcd5d32e4 100644 --- a/src/keyinfo.c +++ b/src/keyinfo.c @@ -639,6 +639,7 @@ xmlSecKeyDataNameGetKlass(void) { static int xmlSecKeyDataNameXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { xmlChar* newName; + const xmlChar* oldName; int ret; xmlSecAssert2(id == xmlSecKeyDataNameId, -1); @@ -687,29 +688,32 @@ xmlSecKeyDataNameXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key, xmlNodePtr node, xmlFree(newName); return(-1); } + + /* done */ + xmlFree(newName); + return(0); } + /* key not found in the manager; fall through to set the name anyway */ /* TODO: record the key names we tried */ - } else { - const xmlChar* oldName; + } - /* if we already have a keyname, make sure that it matches or set it */ - oldName = xmlSecKeyGetName(key); - if(oldName != NULL) { - if(!xmlStrEqual(oldName, newName)) { - xmlSecOtherError(XMLSEC_ERRORS_R_INVALID_KEY_DATA, - xmlSecKeyDataKlassGetName(id), - "key name is already specified"); - xmlFree(newName); - return(-1); - } - } else { - ret = xmlSecKeySetName(key, newName); - if(ret < 0) { - xmlSecInternalError("xmlSecKeySetName", - xmlSecKeyDataKlassGetName(id)); - xmlFree(newName); - return(-1); - } + /* if we already have a keyname, make sure that it matches or set it */ + oldName = xmlSecKeyGetName(key); + if(oldName != NULL) { + if(!xmlStrEqual(oldName, newName)) { + xmlSecOtherError(XMLSEC_ERRORS_R_INVALID_KEY_DATA, + xmlSecKeyDataKlassGetName(id), + "key name is already specified"); + xmlFree(newName); + return(-1); + } + } else { + ret = xmlSecKeySetName(key, newName); + if(ret < 0) { + xmlSecInternalError("xmlSecKeySetName", + xmlSecKeyDataKlassGetName(id)); + xmlFree(newName); + return(-1); } } diff --git a/src/mscng/certkeys.c b/src/mscng/certkeys.c index 287a7baa1..cf2037381 100644 --- a/src/mscng/certkeys.c +++ b/src/mscng/certkeys.c @@ -893,8 +893,8 @@ xmlSecMSCngKeyDataDsaGenerate(xmlSecKeyDataPtr data, xmlSecSize sizeBits, int ret; int res = -1; - xmlSecAssert2(xmlSecKeyDataIsValid(data), xmlSecKeyDataTypeUnknown); - xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecMSCngKeyDataSize), xmlSecKeyDataTypeUnknown); + xmlSecAssert2(xmlSecKeyDataIsValid(data), -1); + xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecMSCngKeyDataSize), -1); xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCngKeyDataDsaId), -1); xmlSecAssert2(sizeBits > 0, -1); @@ -1296,6 +1296,10 @@ xmlSecMSCngKeyDataGetSize(xmlSecKeyDataPtr data) { xmlSecAssert2(ctx->cert->pCertInfo != NULL, 0); length = CertGetPublicKeyLength(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &ctx->cert->pCertInfo->SubjectPublicKeyInfo); + if(length == 0) { + xmlSecMSCngLastError("CertGetPublicKeyLength", NULL); + return(0); + } } else if(ctx->pubkey != 0) { DWORD lenlen = sizeof(length); status = BCryptGetProperty(ctx->pubkey, @@ -1372,8 +1376,8 @@ xmlSecMSCngKeyDataRsaGenerate(xmlSecKeyDataPtr data, xmlSecSize sizeBits, int ret; int res = -1; - xmlSecAssert2(xmlSecKeyDataIsValid(data), xmlSecKeyDataTypeUnknown); - xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecMSCngKeyDataSize), xmlSecKeyDataTypeUnknown); + xmlSecAssert2(xmlSecKeyDataIsValid(data), -1); + xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecMSCngKeyDataSize), -1); xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCngKeyDataRsaId), -1); xmlSecAssert2(sizeBits > 0, -1); diff --git a/src/mscng/keysstore.c b/src/mscng/keysstore.c index b7c112418..fbfd8001e 100644 --- a/src/mscng/keysstore.c +++ b/src/mscng/keysstore.c @@ -113,7 +113,10 @@ xmlSecMSCngKeysStoreFindCert(xmlSecKeyStorePtr store, const xmlChar* name, if(wcName == NULL) { xmlSecInternalError("xmlSecWin32ConvertUtf8ToTstr(name)", xmlSecKeyStoreGetName(store)); - CertCloseStore(hStore, 0); + if(!CertCloseStore(hStore, 0)) { + xmlSecMSCngLastError("CertCloseStore", + xmlSecKeyStoreGetName(store)); + } return(NULL); } @@ -137,7 +140,10 @@ xmlSecMSCngKeysStoreFindCert(xmlSecKeyStorePtr store, const xmlChar* name, xmlSecInternalError("xmlSecWin32ConvertUtf8ToUnicode(name)", xmlSecKeyStoreGetName(store)); xmlFree(wcName); - CertCloseStore(hStore, 0); + if(!CertCloseStore(hStore, 0)) { + xmlSecMSCngLastError("CertCloseStore", + xmlSecKeyStoreGetName(store)); + } return(NULL); } @@ -159,7 +165,10 @@ xmlSecMSCngKeysStoreFindCert(xmlSecKeyStorePtr store, const xmlChar* name, xmlSecMallocError(dwPropSize, xmlSecKeyStoreGetName(store)); xmlFree(lpwName); xmlFree(wcName); - CertCloseStore(hStore, 0); + if(!CertCloseStore(hStore, 0)) { + xmlSecMSCngLastError("CertCloseStore", + xmlSecKeyStoreGetName(store)); + } CertFreeCertificateContext(pCertCtxIter); return(NULL); } @@ -200,7 +209,10 @@ xmlSecMSCngKeysStoreFindCert(xmlSecKeyStorePtr store, const xmlChar* name, xmlFree(wcName); /* dwFlags=0 means close the store with memory remaining allocated for * contexts that have not been freed */ - CertCloseStore(hStore, 0); + if(!CertCloseStore(hStore, 0)) { + xmlSecMSCngLastError("CertCloseStore", + xmlSecKeyStoreGetName(store)); + } return(pCertContext); #else /* XMLSEC_NO_X509 */ diff --git a/src/mscrypto/app.c b/src/mscrypto/app.c index 07c055852..3e5a2bd1f 100644 --- a/src/mscrypto/app.c +++ b/src/mscrypto/app.c @@ -1036,8 +1036,8 @@ xmlSecMSCryptoAppDefaultKeysMngrPrivateKeyLoad(xmlSecKeysMngrPtr mngr, HCRYPTKEY xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(hKey != 0, -1); - /* TODO */ - return(0); + xmlSecNotImplementedError("MSCrypto doesn't support loading private keys at runtime"); + return(-1); } /** @@ -1054,8 +1054,8 @@ xmlSecMSCryptoAppDefaultKeysMngrPublicKeyLoad(xmlSecKeysMngrPtr mngr, HCRYPTKEY xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(hKey != 0, -1); - /* TODO */ - return(0); + xmlSecNotImplementedError("MSCrypto doesn't support loading public keys at runtime"); + return(-1); } /** @@ -1072,8 +1072,8 @@ xmlSecMSCryptoAppDefaultKeysMngrSymKeyLoad(xmlSecKeysMngrPtr mngr, HCRYPTKEY hKe xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(hKey != 0, -1); - /* TODO */ - return(0); + xmlSecNotImplementedError("MSCrypto doesn't support loading symmetric keys at runtime"); + return(-1); } /** diff --git a/src/mscrypto/kt_rsa.c b/src/mscrypto/kt_rsa.c index ca0db8234..fba153979 100644 --- a/src/mscrypto/kt_rsa.c +++ b/src/mscrypto/kt_rsa.c @@ -265,7 +265,13 @@ xmlSecMSCryptoRsaPkcs1OaepProcess(xmlSecTransformPtr transform) { /* the encoded size is equal to the keys size so we could not * process more than that */ - if((transform->operation == xmlSecTransformOperationEncrypt) && (inSize >= keySize)) { + if((transform->operation == xmlSecTransformOperationEncrypt) && (inSize == 0)) { + /* zero-length encrypt is not supported (matches the decrypt path, + * which rejects any input size != keySize) */ + xmlSecInvalidDataError("zero-length OAEP encrypt input", + xmlSecTransformGetName(transform)); + return(-1); + } else if((transform->operation == xmlSecTransformOperationEncrypt) && (inSize >= keySize)) { xmlSecInvalidSizeLessThanError("Input data", inSize, keySize, xmlSecTransformGetName(transform)); return(-1); diff --git a/src/mscrypto/signatures.c b/src/mscrypto/signatures.c index 8faab47fa..8a5679755 100644 --- a/src/mscrypto/signatures.c +++ b/src/mscrypto/signatures.c @@ -511,11 +511,13 @@ static int xmlSecMSCryptoSignatureVerify(xmlSecTransformPtr transform, XMLSEC_SAFE_CAST_SIZE_TO_ULONG(dataSize, dwDataSize, goto done, xmlSecTransformGetName(transform)); if (!CryptVerifySignature(ctx->mscHash, tmpBuf, dwDataSize, hKey, NULL, 0)) { + /* CryptoAPI sets the last error to an NTE_* code, so compare against it directly. */ dwError = GetLastError(); - if (NTE_BAD_SIGNATURE == HRESULT_FROM_WIN32(dwError)) { + if (((DWORD)NTE_BAD_SIGNATURE) == dwError) { xmlSecOtherError(XMLSEC_ERRORS_R_DATA_NOT_MATCH, xmlSecTransformGetName(transform), "CryptVerifySignature: signature verification failed"); transform->status = xmlSecTransformStatusFail; + res = 0; goto done; } else { xmlSecMSCryptoError("CryptVerifySignature", xmlSecTransformGetName(transform)); diff --git a/src/nss/pkikeys.c b/src/nss/pkikeys.c index 2b5a1c156..d6040e091 100644 --- a/src/nss/pkikeys.c +++ b/src/nss/pkikeys.c @@ -1238,7 +1238,6 @@ xmlSecNssKeyDataRsaRead(xmlSecKeyDataId id, xmlSecKeyValueRsaPtr rsaValue) { if(ret < 0) { xmlSecInternalError("xmlSecNssPKIKeyDataAdoptKey", xmlSecKeyDataKlassGetName(id)); - xmlSecKeyDataDestroy(data); goto done; } pubkey = NULL; /* owned by data now */ diff --git a/src/nss/x509vfy.c b/src/nss/x509vfy.c index 4ae9db965..2bab7fd1d 100644 --- a/src/nss/x509vfy.c +++ b/src/nss/x509vfy.c @@ -340,24 +340,12 @@ xmlSecNssX509StoreAdoptCert(xmlSecKeyDataStorePtr store, CERTCertificate* cert, xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->certDb != NULL, -1); - if(ctx->certsList == NULL) { - ctx->certsList = CERT_NewCertList(); - if(ctx->certsList == NULL) { - xmlSecNssError("CERT_NewCertList", xmlSecKeyDataStoreGetName(store)); - return(-1); - } - } - - ret = CERT_AddCertToListTail(ctx->certsList, cert); - if(ret != SECSuccess) { - xmlSecNssError("CERT_AddCertToListTail", xmlSecKeyDataStoreGetName(store)); - return(-1); - } - if(type == xmlSecKeyDataTypeTrusted) { SECStatus status; - /* if requested, mark the certificate as trusted */ + /* if requested, mark the certificate as trusted; this is done before + * adding the cert to the list so that on failure the caller can still + * safely free the cert (the store does not hold a reference to it yet) */ CERTCertTrust trust; status = CERT_DecodeTrustString(&trust, "TCu,Cu,Tu"); if(status != SECSuccess) { @@ -371,6 +359,20 @@ xmlSecNssX509StoreAdoptCert(xmlSecKeyDataStorePtr store, CERTCertificate* cert, } } + if(ctx->certsList == NULL) { + ctx->certsList = CERT_NewCertList(); + if(ctx->certsList == NULL) { + xmlSecNssError("CERT_NewCertList", xmlSecKeyDataStoreGetName(store)); + return(-1); + } + } + + ret = CERT_AddCertToListTail(ctx->certsList, cert); + if(ret != SECSuccess) { + xmlSecNssError("CERT_AddCertToListTail", xmlSecKeyDataStoreGetName(store)); + return(-1); + } + return(0); } diff --git a/src/openssl/ciphers.c b/src/openssl/ciphers.c index 354cdde0c..971b84c67 100644 --- a/src/openssl/ciphers.c +++ b/src/openssl/ciphers.c @@ -566,7 +566,11 @@ xmlSecOpenSSLEvpBlockCipherGCMCtxFinal(xmlSecOpenSSLEvpBlockCipherCtxPtr ctx, /* extract the tag */ memcpy(tag, inBuf + inSize - XMLSEC_OPENSSL_AES_GCM_TAG_SIZE, XMLSEC_OPENSSL_AES_GCM_TAG_SIZE); - xmlSecBufferRemoveTail(in, XMLSEC_OPENSSL_AES_GCM_TAG_SIZE); + ret = xmlSecBufferRemoveTail(in, XMLSEC_OPENSSL_AES_GCM_TAG_SIZE); + if(ret < 0) { + xmlSecInternalError("xmlSecBufferRemoveTail", cipherName); + return(-1); + } inBuf = xmlSecBufferGetData(in); inSize = xmlSecBufferGetSize(in); diff --git a/src/templates.c b/src/templates.c index 96aeb28ee..159ac94d7 100644 --- a/src/templates.c +++ b/src/templates.c @@ -1608,7 +1608,12 @@ xmlSecTmplTransformAddC14NInclNamespaces(xmlNodePtr transformNode, return(-1); } - xmlSetProp(cur, xmlSecAttrPrefixList, prefixList); + if(xmlSetProp(cur, xmlSecAttrPrefixList, prefixList) == NULL) { + xmlSecXmlError2("xmlSetProp", NULL, "name=%s", xmlSecErrorsSafeString(xmlSecAttrPrefixList)); + xmlUnlinkNode(cur); + xmlFreeNode(cur); + return(-1); + } return(0); } diff --git a/src/x509.c b/src/x509.c index fe2f64397..1070e151e 100644 --- a/src/x509.c +++ b/src/x509.c @@ -51,7 +51,7 @@ xmlSecX509DataGetNodeContent (xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { xmlNodePtr cur; int content = 0; - xmlSecAssert2(node != NULL, 0); + xmlSecAssert2(node != NULL, -1); xmlSecAssert2(keyInfoCtx != NULL, -1); /* determine the current node content */ diff --git a/src/xmldsig.c b/src/xmldsig.c index c66aaf0e5..b4f19f8ec 100644 --- a/src/xmldsig.c +++ b/src/xmldsig.c @@ -315,7 +315,15 @@ xmlSecDSigCtxSign(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr tmpl) { outBuf = xmlSecBufferGetData(dsigCtx->result); outSize = xmlSecBufferGetSize(dsigCtx->result); XMLSEC_SAFE_CAST_SIZE_TO_INT(outSize, outLen, return(-1), NULL); +#if LIBXML_VERSION >= 21300 + if(xmlNodeSetContentLen(dsigCtx->signValueNode, outBuf, outLen) < 0) { + xmlSecXmlError("xmlNodeSetContentLen", dsigCtx->signValueNode); + return(-1); + } +#else /* LIBXML_VERSION >= 21300 */ + /* libxml2 < 2.13.0: xmlNodeSetContentLen() returns void and cannot report errors */ xmlNodeSetContentLen(dsigCtx->signValueNode, outBuf, outLen); +#endif /* LIBXML_VERSION >= 21300 */ /* set success status and we are done */ dsigCtx->status = xmlSecDSigStatusSucceeded; @@ -1432,7 +1440,15 @@ xmlSecDSigReferenceCtxProcessNode(xmlSecDSigReferenceCtxPtr dsigRefCtx, xmlNodeP outBuf = xmlSecBufferGetData(dsigRefCtx->result); outSize = xmlSecBufferGetSize(dsigRefCtx->result); XMLSEC_SAFE_CAST_SIZE_TO_INT(outSize, outLen, return(-1), NULL); +#if LIBXML_VERSION >= 21300 + if(xmlNodeSetContentLen(digestValueNode, outBuf, outLen) < 0) { + xmlSecXmlError("xmlNodeSetContentLen", digestValueNode); + return(-1); + } +#else /* LIBXML_VERSION >= 21300 */ + /* libxml2 < 2.13.0: xmlNodeSetContentLen() returns void and cannot report errors */ xmlNodeSetContentLen(digestValueNode, outBuf, outLen); +#endif /* LIBXML_VERSION >= 21300 */ /* set success status and we are done */ dsigRefCtx->status = xmlSecDSigStatusSucceeded; diff --git a/src/xmlsec.c b/src/xmlsec.c index 0f92c3248..55435d3e1 100644 --- a/src/xmlsec.c +++ b/src/xmlsec.c @@ -228,6 +228,9 @@ xmlSecCheckVersionExt(int major, int minor, int subminor, xmlSecCheckVersionMode return(0); } break; + default: + xmlSecUnsupportedEnumValueError("mode", mode, NULL); + return(0); } return(1); diff --git a/src/xpath.c b/src/xpath.c index d3434866e..480b9b2a5 100644 --- a/src/xpath.c +++ b/src/xpath.c @@ -267,17 +267,19 @@ xmlSecXPathDataExecute(xmlSecXPathDataPtr data, xmlDocPtr doc, xmlNodePtr hereNo return(NULL); } - /* sometime LibXML2 returns an empty nodeset or just NULL, we want - to reserve NULL for our own purposes so we simply create an empty - node set here */ + /* A Reference URI must resolve to a node set; if the expression did not + * evaluate to a node set (e.g. it evaluated to a boolean, number, or + * string), report an error instead of silently substituting an empty node + * set, which would cause a legitimate reference to resolve to nothing. + * Note that libxml2 returns an (empty) node set for expressions that match + * no nodes, so a NULL nodesetval here means the result was not a node set + * at all. */ if(xpathObj->nodesetval == NULL) { - xpathObj->nodesetval = xmlXPathNodeSetCreate(NULL); - if(xpathObj->nodesetval == NULL) { - xmlXPathFreeObject(xpathObj); - xmlSecXmlError2("xmlXPathNodeSetCreate", NULL, - "expr=%s", xmlSecErrorsSafeString(data->expr)); - return(NULL); - } + xmlSecInternalError2("xmlSecXPathDataExecute", NULL, + "expression did not evaluate to a node set, expr=%s", + xmlSecErrorsSafeString(data->expr)); + xmlXPathFreeObject(xpathObj); + return(NULL); } nodes = xmlSecNodeSetCreate(doc, xpathObj->nodesetval, data->nodeSetType);