From e3328a6712ff0067ba9f9636c422f50bcbd5ac4d Mon Sep 17 00:00:00 2001 From: Aleksey Sanin Date: Thu, 1 Oct 2026 21:23:26 -0400 Subject: [PATCH] Fixed build files; fixed time verification for certs in xmlsec-gnutls; resolved other minor issues --- apps/cmdline.c | 2 +- configure.ac | 26 +++++---- src/gnutls/x509vfy.c | 122 +++++++++++++++++++++++++++++++++++------- src/keyinfo.c | 4 ++ src/kw_aes_des.c | 30 +++++++++-- src/nss/ciphers.c | 5 +- src/nss/keytrans.c | 6 ++- src/nss/x509.c | 42 ++++++++------- src/openssl/bn.c | 9 ++++ src/openssl/x509vfy.c | 4 -- src/relationship.c | 15 ++++-- src/templates.c | 7 ++- src/xpath.c | 6 ++- xmlsec-config.in | 29 +++++++++- xmlsec-gcrypt.pc.in | 2 +- xmlsec-gnutls.pc.in | 2 +- xmlsec-openssl.pc.in | 2 +- xmlsecConf.sh.in | 1 + 18 files changed, 239 insertions(+), 75 deletions(-) diff --git a/apps/cmdline.c b/apps/cmdline.c index b88c3d917..7b9bd3ea7 100644 --- a/apps/cmdline.c +++ b/apps/cmdline.c @@ -115,7 +115,7 @@ xmlSecAppCmdLineParamsListParse(xmlSecAppCmdLineParamPtr* params, /* check that all parameters at the end are filenames */ for(ii = pos; (ii < argc); ++ii) { - if((argv[ii][0] == '-') && (strcmp(argv[pos], XMLSEC_STDOUT_FILENAME) != 0)) { + if((argv[ii][0] == '-') && (strcmp(argv[ii], XMLSEC_STDOUT_FILENAME) != 0)) { fprintf(stderr, "Error: filename is expected instead of parameter \"%s\".\n", argv[ii]); return(-1); } diff --git a/configure.ac b/configure.ac index f1327fa13..4f66ddda0 100644 --- a/configure.ac +++ b/configure.ac @@ -1024,7 +1024,7 @@ dnl seamonkey-nspr and seamonkey-nss dnl mozilla-nspr and mozilla-nss dnl xulrunner-nspr and xulrunner-nss dnl nspr and nss -if test "z$NSPR_FOUND" = "zno" -a "z$PKGCONFIG_FOUND" = "zyes" -a "z$with_mozilla_ver" = "z" -a "z$with_seamonkey_ver" ; then +if test "z$NSPR_FOUND" = "zno" -a "z$PKGCONFIG_FOUND" = "zyes" -a "z$with_mozilla_ver" = "z" ; then if test "z$NSPR_FOUND" = "zno" ; then PKG_CHECK_MODULES(NSPR, seamonkey-nspr >= $NSPR_MIN_VERSION, [NSPR_FOUND=yes NSPR_PACKAGE=seamonkey-nspr], @@ -1046,7 +1046,7 @@ if test "z$NSPR_FOUND" = "zno" -a "z$PKGCONFIG_FOUND" = "zyes" -a "z$with_mozill [NSPR_FOUND=no]) fi fi -if test "z$NSS_FOUND" = "zno" -a "z$PKGCONFIG_FOUND" = "zyes" -a "z$with_mozilla_ver" = "z" -a "z$with_seamonkey_ver" ; then +if test "z$NSS_FOUND" = "zno" -a "z$PKGCONFIG_FOUND" = "zyes" -a "z$with_mozilla_ver" = "z" ; then if test "z$NSS_FOUND" = "zno" ; then PKG_CHECK_MODULES(NSS, seamonkey-nss >= $SEAMONKEY_MIN_VERSION, [NSS_FOUND=yes NSS_PACKAGE=seamonkey-nss], @@ -1263,6 +1263,7 @@ GCRYPT_INCLUDE_MARKER="gcrypt.h" GCRYPT_LIB_MARKER="libgcrypt$shrext" GCRYPT_CRYPTO_LIB="$XMLSEC_PACKAGE-gcrypt" GCRYPT_LIBS_LIST="-lgcrypt" +GCRYPT_PACKAGE=libgcrypt XMLSEC_NO_GCRYPT="1" GCRYPT_VERSION= @@ -1302,22 +1303,22 @@ dnl Priority 3: Guess with pkg_config if test "z$GCRYPT_FOUND" = "zno" -a "z$PKGCONFIG_FOUND" = "zyes" ; then if test "z$GCRYPT_FOUND" = "zno" ; then PKG_CHECK_MODULES(GCRYPT, gcrypt >= $GCRYPT_MIN_VERSION, - [GCRYPT_FOUND=yes], + [GCRYPT_FOUND=yes GCRYPT_PACKAGE=gcrypt], [GCRYPT_FOUND=no]) fi if test "z$GCRYPT_FOUND" = "zno" ; then PKG_CHECK_MODULES(GCRYPT, libgcrypt20 >= $GCRYPT_MIN_VERSION, - [GCRYPT_FOUND=yes], + [GCRYPT_FOUND=yes GCRYPT_PACKAGE=libgcrypt20], [GCRYPT_FOUND=no]) fi if test "z$GCRYPT_FOUND" = "zno" ; then PKG_CHECK_MODULES(GCRYPT, libgcrypt11 >= $GCRYPT_MIN_VERSION, - [GCRYPT_FOUND=yes], + [GCRYPT_FOUND=yes GCRYPT_PACKAGE=libgcrypt11], [GCRYPT_FOUND=no]) fi if test "z$GCRYPT_FOUND" = "zno" ; then PKG_CHECK_MODULES(GCRYPT, libgcrypt >= $GCRYPT_MIN_VERSION, - [GCRYPT_FOUND=yes], + [GCRYPT_FOUND=yes GCRYPT_PACKAGE=libgcrypt], [GCRYPT_FOUND=no]) fi fi @@ -1434,6 +1435,7 @@ AC_SUBST(GCRYPT_CFLAGS) AC_SUBST(GCRYPT_LIBS) AC_SUBST(GCRYPT_CRYPTO_LIB) AC_SUBST(GCRYPT_MIN_VERSION) +AC_SUBST(GCRYPT_PACKAGE) dnl ========================================================================== dnl See if we can find GnuTLS @@ -1445,6 +1447,7 @@ GNUTLS_INCLUDE_MARKER="gnutls/gnutls.h" GNUTLS_LIB_MARKER="libgnutls$shrext" GNUTLS_CRYPTO_LIB="$XMLSEC_PACKAGE-gnutls" GNUTLS_LIBS_LIST="-lgnutls" +GNUTLS_PACKAGE=gnutls XMLSEC_NO_GNUTLS="1" GNUTLS_INCLUDE_PATH= @@ -1479,12 +1482,12 @@ dnl Priority 3: Guess with pkg_config if test "z$GNUTLS_FOUND" = "zno" -a "z$PKGCONFIG_FOUND" = "zyes" ; then if test "z$GNUTLS_FOUND" = "zno" ; then PKG_CHECK_MODULES(GNUTLS, gnutls >= $GNUTLS_MIN_VERSION, - [GNUTLS_FOUND=yes], + [GNUTLS_FOUND=yes GNUTLS_PACKAGE=gnutls], [GNUTLS_FOUND=no]) fi if test "z$GNUTLS_FOUND" = "zno" ; then PKG_CHECK_MODULES(GNUTLS, libgnutls >= $GNUTLS_MIN_VERSION, - [GNUTLS_FOUND=yes], + [GNUTLS_FOUND=yes GNUTLS_PACKAGE=libgnutls], [GNUTLS_FOUND=no]) fi fi @@ -1587,6 +1590,7 @@ AC_SUBST(GNUTLS_CFLAGS) AC_SUBST(GNUTLS_LIBS) AC_SUBST(GNUTLS_CRYPTO_LIB) AC_SUBST(GNUTLS_MIN_VERSION) +AC_SUBST(GNUTLS_PACKAGE) dnl ========================================================================== @@ -2396,8 +2400,10 @@ dnl ========================================================================== dnl See do we need templates tests dnl ========================================================================== AC_MSG_CHECKING(for templates testing) -AC_ARG_ENABLE([tmpl_tests], [AS_HELP_STRING([--enable-tmpl-tests],[enable templates testing in xmlsec utility (yes)])]) -if test "z$enable_tmpl_tests" = "zyes" ; then +AC_ARG_ENABLE([tmpl_tests], [AS_HELP_STRING([--enable-tmpl-tests],[enable templates testing in xmlsec utility (yes)]), + [enable_tmpl_tests=$enableval], + [enable_tmpl_tests=yes]]) +if test "z$enable_tmpl_tests" = "zno" ; then XMLSEC_DEFINES="$XMLSEC_DEFINES -DXMLSEC_NO_TMPL_TEST=1" AC_MSG_RESULT([disabled]) else diff --git a/src/gnutls/x509vfy.c b/src/gnutls/x509vfy.c index b727d185e..8e9fddfaa 100644 --- a/src/gnutls/x509vfy.c +++ b/src/gnutls/x509vfy.c @@ -249,6 +249,49 @@ xmlSecGnuTLSX509CheckTime(const gnutls_x509_crt_t * cert_list, return(1); } +/* For custom verification time, check only trusted certs that could act as + * issuer for @p cert. This avoids rejecting valid chains because of unrelated + * expired certs in the trust store. */ +static int +xmlSecGnuTLSX509StoreCheckTrustedAnchorTime(xmlSecGnuTLSX509StoreCtxPtr ctx, + gnutls_x509_crt_t cert, + time_t verification_time) { + xmlSecSize ca_list_size, ii; + + xmlSecAssert2(ctx != NULL, -1); + xmlSecAssert2(cert != NULL, -1); + + ca_list_size = xmlSecPtrListGetSize(&(ctx->certsTrusted)); + for(ii = 0; ii < ca_list_size; ++ii) { + gnutls_x509_crt_t trusted_cert; + unsigned int is_issuer; + int ret; + + trusted_cert = xmlSecPtrListGetItem(&(ctx->certsTrusted), ii); + if(trusted_cert == NULL) { + xmlSecInternalError("xmlSecPtrListGetItem(certsTrusted)", NULL); + return(-1); + } + + is_issuer = gnutls_x509_crt_check_issuer(cert, trusted_cert); + if(is_issuer == 0) { + continue; + } + + ret = xmlSecGnuTLSX509CheckTime(&trusted_cert, 1, verification_time); + if(ret < 0) { + xmlSecInternalError("xmlSecGnuTLSX509CheckTime(trusted_cert)", NULL); + return(-1); + } else if(ret == 1) { + /* found a matching trusted cert that is valid at the requested time */ + return(1); + } + } + + /* no valid matching trusted cert found at the requested verification time */ + return(0); +} + static int xmlSecGnuTLSX509GetVerificationFlags(const xmlSecKeyInfoCtx* keyInfoCtx, unsigned int* flags) { @@ -258,8 +301,13 @@ xmlSecGnuTLSX509GetVerificationFlags(const xmlSecKeyInfoCtx* keyInfoCtx, (*flags) = 0; /* gnutls doesn't allow to specify "verification" timestamp so - we have to do it ourselves */ - (*flags) |= GNUTLS_VERIFY_DISABLE_TIME_CHECKS; + we have to do it ourselves; disable the gnutls time checks only + in this case, otherwise gnutls checks the validity periods of + all certificates (including the trusted ones) against the + current time */ + if(keyInfoCtx->certsVerificationTime > 0) { + (*flags) |= GNUTLS_VERIFY_DISABLE_TIME_CHECKS; + } if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_SKIP_STRICT_CHECKS) != 0) { (*flags) |= GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2; @@ -471,12 +519,32 @@ xmlSecGnuTLSX509StoreVerify(xmlSecKeyDataStorePtr store, } /* gnutls doesn't allow to specify "verification" timestamp so - we have to do it ourselves */ - ret = xmlSecGnuTLSX509CheckTime(cert_list, cert_list_cur_size, verification_time); - if(ret != 1) { - xmlSecInternalError("xmlSecGnuTLSX509CheckTime", NULL); - /* ignore error, don't stop, continue! */ - continue; + we have to do it ourselves (gnutls only checks the time against + the current time, which is not the custom verification time) */ + if(keyInfoCtx->certsVerificationTime > 0) { + ret = xmlSecGnuTLSX509CheckTime(cert_list, cert_list_cur_size, verification_time); + if(ret < 0) { + xmlSecInternalError("xmlSecGnuTLSX509CheckTime", NULL); + /* ignore error, don't stop, continue! */ + continue; + } else if(ret != 1) { + /* cert in the candidate chain is not valid at verification time */ + continue; + } + + /* GNUTLS_VERIFY_DISABLE_TIME_CHECKS disables time checks for trusted + certs too, so check only the trust anchor candidates for this + chain instead of all trusted certs in the store. */ + ret = xmlSecGnuTLSX509StoreCheckTrustedAnchorTime(ctx, + cert_list[cert_list_cur_size - 1], verification_time); + if(ret < 0) { + xmlSecInternalError("xmlSecGnuTLSX509StoreCheckTrustedAnchorTime", NULL); + /* ignore error, don't stop, continue! */ + continue; + } else if(ret != 1) { + /* trusted cert candidate not valid at the verification time */ + continue; + } } /* DONE! */ @@ -598,18 +666,32 @@ xmlSecGnuTLSX509StoreVerifyIssuerCert(xmlSecGnuTLSX509StoreCtxPtr ctx, } /* gnutls doesn't allow to specify "verification" timestamp so - we have to do it ourselves */ - verification_time = (keyInfoCtx->certsVerificationTime > 0) ? - keyInfoCtx->certsVerificationTime : - time(0); - ret = xmlSecGnuTLSX509CheckTime(chain, chain_cur_size, verification_time); - if(ret < 0) { - xmlSecInternalError("xmlSecGnuTLSX509CheckTime", NULL); - goto done; - } else if(ret != 1) { - /* issuer cert not valid at the verification time */ - res = 0; - goto done; + we have to do it ourselves; GNUTLS_VERIFY_DISABLE_TIME_CHECKS makes + gnutls skip the time checks for the trusted certs as well, so they + have to be checked here too */ + if(keyInfoCtx->certsVerificationTime > 0) { + verification_time = keyInfoCtx->certsVerificationTime; + + ret = xmlSecGnuTLSX509CheckTime(chain, chain_cur_size, verification_time); + if(ret < 0) { + xmlSecInternalError("xmlSecGnuTLSX509CheckTime", NULL); + goto done; + } else if(ret != 1) { + /* issuer cert not valid at the verification time */ + res = 0; + goto done; + } + + ret = xmlSecGnuTLSX509StoreCheckTrustedAnchorTime(ctx, + chain[chain_cur_size - 1], verification_time); + if(ret < 0) { + xmlSecInternalError("xmlSecGnuTLSX509StoreCheckTrustedAnchorTime", NULL); + goto done; + } else if(ret != 1) { + /* trusted cert candidate not valid at the verification time */ + res = 0; + goto done; + } } /* done! */ diff --git a/src/keyinfo.c b/src/keyinfo.c index cfe1b418e..379b1564f 100644 --- a/src/keyinfo.c +++ b/src/keyinfo.c @@ -1429,6 +1429,10 @@ xmlSecKeyDataEncryptedKeyXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key, xmlNodeP } xmlSecAssert2(keyInfoCtx->encCtx != NULL, -1); + /* setup current recursion levels for the write context */ + keyInfoCtx->encCtx->keyInfoWriteCtx.curRetrievalMethodLevel = keyInfoCtx->curRetrievalMethodLevel; + keyInfoCtx->encCtx->keyInfoWriteCtx.curEncryptedKeyLevel = keyInfoCtx->curEncryptedKeyLevel + 1; + /* encrypt */ ret = xmlSecEncCtxBinaryEncrypt(keyInfoCtx->encCtx, node, keyBuf, keySize); if(ret < 0) { diff --git a/src/kw_aes_des.c b/src/kw_aes_des.c index 6bdea9950..80bd85b39 100644 --- a/src/kw_aes_des.c +++ b/src/kw_aes_des.c @@ -15,6 +15,7 @@ #include "globals.h" +#include #include #include @@ -763,6 +764,21 @@ static const xmlSecByte xmlSecKWAesMagicBlock[XMLSEC_KW_AES_MAGIC_BLOCK_SIZE] = 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6 }; +/* XORs the full 64-bit counter @p counter into the 8-byte A register @p block + * (big-endian), as required by RFC 3394. Only the low byte is not enough: for + * N >= 43 the counter t exceeds 255 and the high bytes must be mixed in too. */ +static void +xmlSecKWAesXorCounter(xmlSecByte* block, uint64_t counter) { + xmlSecSize ii; + + xmlSecAssert(block != NULL); + + for(ii = 0; ii < XMLSEC_KW_AES_MAGIC_BLOCK_SIZE; ++ii) { + /* the shift (up to 56) is well-defined */ + block[ii] ^= (xmlSecByte)(counter >> (8 * (XMLSEC_KW_AES_MAGIC_BLOCK_SIZE - 1 - ii))); + } +} + int xmlSecKWAesEncode(xmlSecKWAesId kwAesId, xmlSecTransformPtr transform, const xmlSecByte *in, xmlSecSize inSize, @@ -818,7 +834,7 @@ xmlSecKWAesEncode(xmlSecKWAesId kwAesId, xmlSecTransformPtr transform, "outWritten2=" XMLSEC_SIZE_FMT, outWritten2); return(-1); } - block[7] ^= (xmlSecByte)tt; + xmlSecKWAesXorCounter(block, tt); memcpy(out, block, 8); memcpy(p, block + 8, 8); } @@ -844,11 +860,19 @@ xmlSecKWAesDecode(xmlSecKWAesId kwAesId, xmlSecTransformPtr transform, xmlSecAssert2(kwAesId->decrypt != NULL, -1); xmlSecAssert2(transform != NULL, -1); xmlSecAssert2(in != NULL, -1); - xmlSecAssert2(inSize >= XMLSEC_KW_AES_MAGIC_BLOCK_SIZE, -1); xmlSecAssert2(out != NULL, -1); xmlSecAssert2(outSize >= inSize, -1); xmlSecAssert2(outWritten != NULL, -1); + /* a valid wrapped key is at least the magic block plus one data block; + * reject a bare magic block (NN == 0) which would otherwise "unwrap" to a + * zero-length key without any decryption or integrity check */ + if(inSize < 2 * XMLSEC_KW_AES_MAGIC_BLOCK_SIZE) { + xmlSecInvalidSizeLessThanError("Input data", inSize, + 2 * XMLSEC_KW_AES_MAGIC_BLOCK_SIZE, NULL); + return(-1); + } + /* copy input */ if(in != out) { memcpy(out, in, inSize); @@ -872,7 +896,7 @@ xmlSecKWAesDecode(xmlSecKWAesId kwAesId, xmlSecTransformPtr transform, memcpy(block, out, 8); memcpy(block + 8, p, 8); - block[7] ^= (xmlSecByte)tt; + xmlSecKWAesXorCounter(block, tt); outWritten2 = 0; ret = kwAesId->decrypt(transform, block, sizeof(block), diff --git a/src/nss/ciphers.c b/src/nss/ciphers.c index fa8e03ad9..e4e28c5e2 100644 --- a/src/nss/ciphers.c +++ b/src/nss/ciphers.c @@ -152,7 +152,7 @@ xmlSecNssBlockCipherCtxInit(xmlSecNssBlockCipherCtxPtr ctx, } symKey = PK11_ImportSymKey(slot, ctx->cipher, PK11_OriginDerive, - CKA_ENCRYPT, &keyItem, NULL); + (encrypt) ? CKA_ENCRYPT : CKA_DECRYPT, &keyItem, NULL); if(symKey == NULL) { xmlSecNssError("PK11_ImportSymKey", cipherName); PK11_FreeSlot(slot); @@ -160,8 +160,7 @@ xmlSecNssBlockCipherCtxInit(xmlSecNssBlockCipherCtxPtr ctx, } ctx->cipherCtx = PK11_CreateContextBySymKey(ctx->cipher, - (encrypt) ? CKA_ENCRYPT : CKA_DECRYPT, - symKey, &ivItem); + (encrypt) ? CKA_ENCRYPT : CKA_DECRYPT, symKey, &ivItem); if(ctx->cipherCtx == NULL) { xmlSecNssError("PK11_CreateContextBySymKey", cipherName); PK11_FreeSymKey(symKey); diff --git a/src/nss/keytrans.c b/src/nss/keytrans.c index 556897197..2f96639f0 100644 --- a/src/nss/keytrans.c +++ b/src/nss/keytrans.c @@ -449,7 +449,11 @@ xmlSecNssKeyTransportCtxFinal(xmlSecNssKeyTransportCtxPtr ctx, xmlSecBufferPtr i SECItem* keyItem; /* pay attention to mechanism */ - symKey = PK11_PubUnwrapSymKey(ctx->prikey, &oriskv, ctx->cipher, CKA_UNWRAP, 0); + /* target is the mechanism of the unwrapped symmetric key, which is + * unknown here (passing ctx->cipher, e.g. CKM_RSA_PKCS, would make + * NSS mark the unwrapped session key as CKK_RSA), so pass + * CKM_GENERIC_SECRET_KEY_GEN */ + symKey = PK11_PubUnwrapSymKey(ctx->prikey, &oriskv, CKM_GENERIC_SECRET_KEY_GEN, CKA_UNWRAP, 0); if(symKey == NULL) { xmlSecNssError("PK11_PubUnwrapSymKey", NULL); xmlSecBufferDestroy(result); diff --git a/src/nss/x509.c b/src/nss/x509.c index 0f23a74b6..b6f08fbee 100644 --- a/src/nss/x509.c +++ b/src/nss/x509.c @@ -44,6 +44,7 @@ #include #include #include +#include #include "../cast_helpers.h" #include "../keysdata_helpers.h" @@ -1167,37 +1168,42 @@ xmlSecNssX509NameWrite(CERTName* nm) { } -/* not more than 64 chars */ -#define XMLSEC_NSS_INT_TO_STR_MAX_SIZE 64 - static xmlChar* xmlSecNssASN1IntegerWrite(SECItem *num) { + xmlSecBn bn; xmlChar *res = NULL; - PRUint64 val = 0; - unsigned int ii = 0; - int shift = 0; + int ret; xmlSecAssert2(num != NULL, NULL); xmlSecAssert2(num->type == siBuffer, NULL); xmlSecAssert2(num->data != NULL, NULL); - /* HACK : to be fixed after - * NSS bug http://bugzilla.mozilla.org/show_bug.cgi?id=212864 is fixed - */ - for(ii = num->len; ii > 0; --ii, shift += 8) { - xmlSecAssert2(shift < 64 || num->data[ii - 1] == 0, NULL); - if(num->data[ii - 1] != 0) { - val |= ((PRUint64)num->data[ii - 1]) << shift; - } + /* the value is a DER-encoded INTEGER, i.e. big-endian unsigned bytes + (possibly with a leading 0x00 padding byte when the most significant + bit of the first content byte is set); use xmlSecBn to support + arbitrary length values (RFC 5280 serial numbers are up to 20 octets) + and let xmlSecBnToDecString() handle the leading zeros */ + ret = xmlSecBnInitialize(&bn, num->len + 1); + if(ret < 0) { + xmlSecInternalError2("xmlSecBnInitialize", NULL, "size=%u", num->len + 1); + return(NULL); } - res = (xmlChar*)xmlMalloc(XMLSEC_NSS_INT_TO_STR_MAX_SIZE + 1); + ret = xmlSecBnSetData(&bn, (const xmlSecByte*)num->data, num->len); + if(ret < 0) { + xmlSecInternalError2("xmlSecBnSetData", NULL, "size=%u", num->len); + xmlSecBnFinalize(&bn); + return(NULL); + } + + res = xmlSecBnToDecString(&bn); if(res == NULL) { - xmlSecMallocError(XMLSEC_NSS_INT_TO_STR_MAX_SIZE + 1, NULL); - return (NULL); + xmlSecInternalError("xmlSecBnToDecString", NULL); + xmlSecBnFinalize(&bn); + return(NULL); } - PR_snprintf((char*)res, XMLSEC_NSS_INT_TO_STR_MAX_SIZE, "%llu", val); + xmlSecBnFinalize(&bn); return(res); } diff --git a/src/openssl/bn.c b/src/openssl/bn.c index 0901a472d..2652aef57 100644 --- a/src/openssl/bn.c +++ b/src/openssl/bn.c @@ -115,6 +115,15 @@ xmlSecOpenSSLNodeSetBNValue(xmlNodePtr cur, const BIGNUM *a, int addLineBreaks) xmlSecAssert2(a != NULL, -1); xmlSecAssert2(cur != NULL, -1); + /* CryptoBinary values are non-negative + (http://www.w3.org/TR/xmldsig-core/#sec-CryptoBinary) and + BN_bn2bin() writes the absolute value |a| only, so reject + negative BIGNUMs instead of silently dropping the sign */ + if(BN_is_negative(a) != 0) { + xmlSecInvalidIntegerDataError("BIGNUM value", -1, ">= 0", NULL); + goto done; + } + ret = BN_num_bytes(a); if(ret < 0) { xmlSecOpenSSLError("BN_num_bytes", NULL); diff --git a/src/openssl/x509vfy.c b/src/openssl/x509vfy.c index c0590828e..9d94d0893 100644 --- a/src/openssl/x509vfy.c +++ b/src/openssl/x509vfy.c @@ -1523,10 +1523,6 @@ xmlSecOpenSSLX509StoreVerifySetParams(X509_STORE_CTX *xsc, xmlSecKeyInfoCtx* key xmlSecAssert2(xsc != NULL, -1); xmlSecAssert2(keyInfoCtx != NULL, -1); - if(keyInfoCtx->certsVerificationTime > 0) { - X509_STORE_CTX_set_time(xsc, 0, keyInfoCtx->certsVerificationTime); - } - vpm = X509_VERIFY_PARAM_new(); if(vpm == NULL) { xmlSecOpenSSLError("X509_VERIFY_PARAM_new", NULL); diff --git a/src/relationship.c b/src/relationship.c index b3ea47fb1..46e53e328 100644 --- a/src/relationship.c +++ b/src/relationship.c @@ -81,6 +81,7 @@ #include #include #include +#include #include #include @@ -257,6 +258,11 @@ xmlSecTransformRelationshipCompare(xmlNodePtr node1, xmlNodePtr node2) { id1 = xmlGetProp(node1, xmlSecRelationshipAttrId); id2 = xmlGetProp(node2, xmlSecRelationshipAttrId); + if(id1 == NULL && id2 == NULL) { + /* Both lack an Id: treat as equal so the comparator is a strict weak ordering. */ + ret = 0; + goto done; + } if(id1 == NULL) { ret = -1; goto done; @@ -297,10 +303,11 @@ xmlSecTransformRelationshipProcessNode(xmlSecTransformPtr transform, xmlOutputBu if(xmlSecCheckNodeName(cur, xmlSecNodeRelationship, xmlSecRelationshipsNs)) { xmlChar* id = xmlGetProp(cur, xmlSecRelationshipAttrId); if(id == NULL) { - xmlSecXmlError2("xmlGetProp(xmlSecRelationshipAttrId)", - xmlSecTransformGetName(transform), - "name=%s", xmlSecRelationshipAttrId); - return(-1); + /* xmlGetProp() returns NULL both when the Id attribute is absent + * and when it cannot allocate the return value. Current behavior + * treats either case as "no usable Id", so per step 2, point 4 + * the node is dropped instead of failing the transform. */ + return(0); } ctx = xmlSecRelationshipGetCtx(transform); diff --git a/src/templates.c b/src/templates.c index 159ac94d7..26191b0b4 100644 --- a/src/templates.c +++ b/src/templates.c @@ -860,9 +860,8 @@ xmlSecTmplEncDataGetEncMethodNode(xmlNodePtr encNode) { * @cipherReferenceNode: the pointer to node. * @transformId: the transform id. * - * Adds node (and the parent node) - * with specified transform methods @transform to the - * child node of the node @encNode. + * Adds node (and the parent node) + * with specified @transformId transform to the @cipherReferenceNode. * * Returns: the pointer to newly created node or * NULL if an error occurs. @@ -1126,7 +1125,7 @@ xmlSecTmplKeyInfoAddRetrievalMethod(xmlNodePtr keyInfoNode, const xmlChar *uri, * @transformId: the transform id. * * Adds node (and the parent node - * if required) to the node @retrMethod. + * if required) to the @retrMethodNode. * * Returns: the pointer to the newly created node or * NULL if an error occurs. diff --git a/src/xpath.c b/src/xpath.c index 480b9b2a5..8798ff9fd 100644 --- a/src/xpath.c +++ b/src/xpath.c @@ -796,8 +796,6 @@ xmlSecTransformXPointerSetExpr(xmlSecTransformPtr transform, const xmlChar* expr xmlSecAssert2(expr != NULL, -1); xmlSecAssert2(hereNode != NULL, -1); - transform->hereNode = hereNode; - dataList = xmlSecXPathGetCtx(transform); xmlSecAssert2(xmlSecPtrListCheckId(dataList, xmlSecXPathDataListId), -1); xmlSecAssert2(xmlSecPtrListGetSize(dataList) == 0, -1); @@ -838,6 +836,10 @@ xmlSecTransformXPointerSetExpr(xmlSecTransformPtr transform, const xmlChar* expr data->nodeSetOp = xmlSecNodeSetIntersection; data->nodeSetType = nodeSetType; + /* set the "here" node only after all fallible operations succeeded, + * so a failed call leaves the transform unmodified */ + transform->hereNode = hereNode; + return(0); } diff --git a/xmlsec-config.in b/xmlsec-config.in index 502ac04a3..16c244781 100644 --- a/xmlsec-config.in +++ b/xmlsec-config.in @@ -23,7 +23,8 @@ Known values for OPTION are: --exec-prefix=DIR change XMLSEC executable prefix folder --libdir=DIR change XMLSEC libraries folder --crypto=LIB configure with XMLSEC crypto library (one of the - following: none default openssl nss gnutls gcrypt) + following: none default openssl nss gnutls gcrypt + mscng mscrypto) --help display this help and exit --version output version information EOF @@ -190,7 +191,7 @@ gnutls) gcrypt) if test "@XMLSEC_NO_GCRYPT@" = "0" ; then - the_crypto_flags="@GCRYPT_CFLAGS@L" + the_crypto_flags="@GCRYPT_CFLAGS@" the_crypto_libs="@GCRYPT_LIBS@" the_xmlsec_crypto_lib="-l@GCRYPT_CRYPTO_LIB@" else @@ -211,6 +212,30 @@ nss) fi ;; +mscng) + if test "@XMLSEC_NO_MSCNG@" = "0"; + then + the_crypto_flags="@MSCNG_CFLAGS@" + the_crypto_libs="@MSCNG_LIBS@" + the_xmlsec_crypto_lib="-l@MSCNG_CRYPTO_LIB@" + else + echo "Error: the \"$crypto\" cryptographic library is not supported" + usage 1 + fi + ;; + +mscrypto) + if test "@XMLSEC_NO_MSCRYPTO@" = "0"; + then + the_crypto_flags="@MSCRYPTO_CFLAGS@" + the_crypto_libs="@MSCRYPTO_LIBS@" + the_xmlsec_crypto_lib="-l@MSCRYPTO_CRYPTO_LIB@" + else + echo "Error: the \"$crypto\" cryptographic library is not supported" + usage 1 + fi + ;; + *) echo "Error: the \"$crypto\" cryptographic library is not supported" usage 1 diff --git a/xmlsec-gcrypt.pc.in b/xmlsec-gcrypt.pc.in index 79f8ce421..7e8d9ef10 100644 --- a/xmlsec-gcrypt.pc.in +++ b/xmlsec-gcrypt.pc.in @@ -6,7 +6,7 @@ includedir=@includedir@ Name: xmlsec1-gcrypt Version: @VERSION@ Description: XML Security Library implements XML Signature and XML Encryption standards -Requires: libxml-2.0 >= @LIBXML_MIN_VERSION@ @LIBXSLT_PC_FILE_COND@ +Requires: @GCRYPT_PACKAGE@ >= @GCRYPT_MIN_VERSION@, libxml-2.0 >= @LIBXML_MIN_VERSION@ @LIBXSLT_PC_FILE_COND@ Cflags: @XMLSEC_GCRYPT_CFLAGS@ Cflags.private: -DXMLSEC_STATIC Libs: @XMLSEC_GCRYPT_LIBS@ diff --git a/xmlsec-gnutls.pc.in b/xmlsec-gnutls.pc.in index 712e1a44d..5da1e1f31 100644 --- a/xmlsec-gnutls.pc.in +++ b/xmlsec-gnutls.pc.in @@ -6,7 +6,7 @@ includedir=@includedir@ Name: xmlsec1-gnutls Version: @VERSION@ Description: XML Security Library implements XML Signature and XML Encryption standards -Requires: libxml-2.0 >= @LIBXML_MIN_VERSION@ @LIBXSLT_PC_FILE_COND@ +Requires: @GNUTLS_PACKAGE@ >= @GNUTLS_MIN_VERSION@, libxml-2.0 >= @LIBXML_MIN_VERSION@ @LIBXSLT_PC_FILE_COND@ Cflags: @XMLSEC_GNUTLS_CFLAGS@ Cflags.private: -DXMLSEC_STATIC Libs: @XMLSEC_GNUTLS_LIBS@ diff --git a/xmlsec-openssl.pc.in b/xmlsec-openssl.pc.in index af3ae29b3..15a4b2360 100644 --- a/xmlsec-openssl.pc.in +++ b/xmlsec-openssl.pc.in @@ -6,7 +6,7 @@ includedir=@includedir@ Name: xmlsec1-openssl Version: @VERSION@ Description: XML Security Library implements XML Signature and XML Encryption standards -Requires: libxml-2.0 >= @LIBXML_MIN_VERSION@ @LIBXSLT_PC_FILE_COND@ +Requires: openssl, libxml-2.0 >= @LIBXML_MIN_VERSION@ @LIBXSLT_PC_FILE_COND@ Cflags: @XMLSEC_OPENSSL_CFLAGS@ Cflags.private: -DXMLSEC_STATIC Libs: @XMLSEC_OPENSSL_LIBS@ diff --git a/xmlsecConf.sh.in b/xmlsecConf.sh.in index 2f81eda45..91b3fd779 100644 --- a/xmlsecConf.sh.in +++ b/xmlsecConf.sh.in @@ -7,6 +7,7 @@ libdir="@libdir@" includedir="@includedir@" XMLSEC_LIBDIR="@XMLSEC_LIBDIR@" +XMLSEC_CFLAGS="@XMLSEC_CFLAGS@" XMLSEC_INCLUDEDIR="@XMLSEC_CFLAGS@" XMLSEC_LIBS="@XMLSEC_LIBS@" MODULE_VERSION="xmlsec-@VERSION@-@XMLSEC_DEFAULT_CRYPTO@"