Skip to content

Commit fa2ef92

Browse files
authored
Fixed build files; fixed time verification for certs in xmlsec-gnutls; resolved other minor issues (#1360)
1 parent b6bbc7b commit fa2ef92

18 files changed

Lines changed: 239 additions & 75 deletions

‎apps/cmdline.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ xmlSecAppCmdLineParamsListParse(xmlSecAppCmdLineParamPtr* params,
115115

116116
/* check that all parameters at the end are filenames */
117117
for(ii = pos; (ii < argc); ++ii) {
118-
if((argv[ii][0] == '-') && (strcmp(argv[pos], XMLSEC_STDOUT_FILENAME) != 0)) {
118+
if((argv[ii][0] == '-') && (strcmp(argv[ii], XMLSEC_STDOUT_FILENAME) != 0)) {
119119
fprintf(stderr, "Error: filename is expected instead of parameter \"%s\".\n", argv[ii]);
120120
return(-1);
121121
}

‎configure.ac‎

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,7 +1024,7 @@ dnl seamonkey-nspr and seamonkey-nss
10241024
dnl mozilla-nspr and mozilla-nss
10251025
dnl xulrunner-nspr and xulrunner-nss
10261026
dnl nspr and nss
1027-
if test "z$NSPR_FOUND" = "zno" -a "z$PKGCONFIG_FOUND" = "zyes" -a "z$with_mozilla_ver" = "z" -a "z$with_seamonkey_ver" ; then
1027+
if test "z$NSPR_FOUND" = "zno" -a "z$PKGCONFIG_FOUND" = "zyes" -a "z$with_mozilla_ver" = "z" ; then
10281028
if test "z$NSPR_FOUND" = "zno" ; then
10291029
PKG_CHECK_MODULES(NSPR, seamonkey-nspr >= $NSPR_MIN_VERSION,
10301030
[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
10461046
[NSPR_FOUND=no])
10471047
fi
10481048
fi
1049-
if test "z$NSS_FOUND" = "zno" -a "z$PKGCONFIG_FOUND" = "zyes" -a "z$with_mozilla_ver" = "z" -a "z$with_seamonkey_ver" ; then
1049+
if test "z$NSS_FOUND" = "zno" -a "z$PKGCONFIG_FOUND" = "zyes" -a "z$with_mozilla_ver" = "z" ; then
10501050
if test "z$NSS_FOUND" = "zno" ; then
10511051
PKG_CHECK_MODULES(NSS, seamonkey-nss >= $SEAMONKEY_MIN_VERSION,
10521052
[NSS_FOUND=yes NSS_PACKAGE=seamonkey-nss],
@@ -1263,6 +1263,7 @@ GCRYPT_INCLUDE_MARKER="gcrypt.h"
12631263
GCRYPT_LIB_MARKER="libgcrypt$shrext"
12641264
GCRYPT_CRYPTO_LIB="$XMLSEC_PACKAGE-gcrypt"
12651265
GCRYPT_LIBS_LIST="-lgcrypt"
1266+
GCRYPT_PACKAGE=libgcrypt
12661267

12671268
XMLSEC_NO_GCRYPT="1"
12681269
GCRYPT_VERSION=
@@ -1302,22 +1303,22 @@ dnl Priority 3: Guess with pkg_config
13021303
if test "z$GCRYPT_FOUND" = "zno" -a "z$PKGCONFIG_FOUND" = "zyes" ; then
13031304
if test "z$GCRYPT_FOUND" = "zno" ; then
13041305
PKG_CHECK_MODULES(GCRYPT, gcrypt >= $GCRYPT_MIN_VERSION,
1305-
[GCRYPT_FOUND=yes],
1306+
[GCRYPT_FOUND=yes GCRYPT_PACKAGE=gcrypt],
13061307
[GCRYPT_FOUND=no])
13071308
fi
13081309
if test "z$GCRYPT_FOUND" = "zno" ; then
13091310
PKG_CHECK_MODULES(GCRYPT, libgcrypt20 >= $GCRYPT_MIN_VERSION,
1310-
[GCRYPT_FOUND=yes],
1311+
[GCRYPT_FOUND=yes GCRYPT_PACKAGE=libgcrypt20],
13111312
[GCRYPT_FOUND=no])
13121313
fi
13131314
if test "z$GCRYPT_FOUND" = "zno" ; then
13141315
PKG_CHECK_MODULES(GCRYPT, libgcrypt11 >= $GCRYPT_MIN_VERSION,
1315-
[GCRYPT_FOUND=yes],
1316+
[GCRYPT_FOUND=yes GCRYPT_PACKAGE=libgcrypt11],
13161317
[GCRYPT_FOUND=no])
13171318
fi
13181319
if test "z$GCRYPT_FOUND" = "zno" ; then
13191320
PKG_CHECK_MODULES(GCRYPT, libgcrypt >= $GCRYPT_MIN_VERSION,
1320-
[GCRYPT_FOUND=yes],
1321+
[GCRYPT_FOUND=yes GCRYPT_PACKAGE=libgcrypt],
13211322
[GCRYPT_FOUND=no])
13221323
fi
13231324
fi
@@ -1434,6 +1435,7 @@ AC_SUBST(GCRYPT_CFLAGS)
14341435
AC_SUBST(GCRYPT_LIBS)
14351436
AC_SUBST(GCRYPT_CRYPTO_LIB)
14361437
AC_SUBST(GCRYPT_MIN_VERSION)
1438+
AC_SUBST(GCRYPT_PACKAGE)
14371439

14381440
dnl ==========================================================================
14391441
dnl See if we can find GnuTLS
@@ -1445,6 +1447,7 @@ GNUTLS_INCLUDE_MARKER="gnutls/gnutls.h"
14451447
GNUTLS_LIB_MARKER="libgnutls$shrext"
14461448
GNUTLS_CRYPTO_LIB="$XMLSEC_PACKAGE-gnutls"
14471449
GNUTLS_LIBS_LIST="-lgnutls"
1450+
GNUTLS_PACKAGE=gnutls
14481451

14491452
XMLSEC_NO_GNUTLS="1"
14501453
GNUTLS_INCLUDE_PATH=
@@ -1479,12 +1482,12 @@ dnl Priority 3: Guess with pkg_config
14791482
if test "z$GNUTLS_FOUND" = "zno" -a "z$PKGCONFIG_FOUND" = "zyes" ; then
14801483
if test "z$GNUTLS_FOUND" = "zno" ; then
14811484
PKG_CHECK_MODULES(GNUTLS, gnutls >= $GNUTLS_MIN_VERSION,
1482-
[GNUTLS_FOUND=yes],
1485+
[GNUTLS_FOUND=yes GNUTLS_PACKAGE=gnutls],
14831486
[GNUTLS_FOUND=no])
14841487
fi
14851488
if test "z$GNUTLS_FOUND" = "zno" ; then
14861489
PKG_CHECK_MODULES(GNUTLS, libgnutls >= $GNUTLS_MIN_VERSION,
1487-
[GNUTLS_FOUND=yes],
1490+
[GNUTLS_FOUND=yes GNUTLS_PACKAGE=libgnutls],
14881491
[GNUTLS_FOUND=no])
14891492
fi
14901493
fi
@@ -1587,6 +1590,7 @@ AC_SUBST(GNUTLS_CFLAGS)
15871590
AC_SUBST(GNUTLS_LIBS)
15881591
AC_SUBST(GNUTLS_CRYPTO_LIB)
15891592
AC_SUBST(GNUTLS_MIN_VERSION)
1593+
AC_SUBST(GNUTLS_PACKAGE)
15901594

15911595

15921596
dnl ==========================================================================
@@ -2396,8 +2400,10 @@ dnl ==========================================================================
23962400
dnl See do we need templates tests
23972401
dnl ==========================================================================
23982402
AC_MSG_CHECKING(for templates testing)
2399-
AC_ARG_ENABLE([tmpl_tests], [AS_HELP_STRING([--enable-tmpl-tests],[enable templates testing in xmlsec utility (yes)])])
2400-
if test "z$enable_tmpl_tests" = "zyes" ; then
2403+
AC_ARG_ENABLE([tmpl_tests], [AS_HELP_STRING([--enable-tmpl-tests],[enable templates testing in xmlsec utility (yes)]),
2404+
[enable_tmpl_tests=$enableval],
2405+
[enable_tmpl_tests=yes]])
2406+
if test "z$enable_tmpl_tests" = "zno" ; then
24012407
XMLSEC_DEFINES="$XMLSEC_DEFINES -DXMLSEC_NO_TMPL_TEST=1"
24022408
AC_MSG_RESULT([disabled])
24032409
else

‎src/gnutls/x509vfy.c‎

Lines changed: 102 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,49 @@ xmlSecGnuTLSX509CheckTime(const gnutls_x509_crt_t * cert_list,
249249
return(1);
250250
}
251251

252+
/* For custom verification time, check only trusted certs that could act as
253+
* issuer for @p cert. This avoids rejecting valid chains because of unrelated
254+
* expired certs in the trust store. */
255+
static int
256+
xmlSecGnuTLSX509StoreCheckTrustedAnchorTime(xmlSecGnuTLSX509StoreCtxPtr ctx,
257+
gnutls_x509_crt_t cert,
258+
time_t verification_time) {
259+
xmlSecSize ca_list_size, ii;
260+
261+
xmlSecAssert2(ctx != NULL, -1);
262+
xmlSecAssert2(cert != NULL, -1);
263+
264+
ca_list_size = xmlSecPtrListGetSize(&(ctx->certsTrusted));
265+
for(ii = 0; ii < ca_list_size; ++ii) {
266+
gnutls_x509_crt_t trusted_cert;
267+
unsigned int is_issuer;
268+
int ret;
269+
270+
trusted_cert = xmlSecPtrListGetItem(&(ctx->certsTrusted), ii);
271+
if(trusted_cert == NULL) {
272+
xmlSecInternalError("xmlSecPtrListGetItem(certsTrusted)", NULL);
273+
return(-1);
274+
}
275+
276+
is_issuer = gnutls_x509_crt_check_issuer(cert, trusted_cert);
277+
if(is_issuer == 0) {
278+
continue;
279+
}
280+
281+
ret = xmlSecGnuTLSX509CheckTime(&trusted_cert, 1, verification_time);
282+
if(ret < 0) {
283+
xmlSecInternalError("xmlSecGnuTLSX509CheckTime(trusted_cert)", NULL);
284+
return(-1);
285+
} else if(ret == 1) {
286+
/* found a matching trusted cert that is valid at the requested time */
287+
return(1);
288+
}
289+
}
290+
291+
/* no valid matching trusted cert found at the requested verification time */
292+
return(0);
293+
}
294+
252295
static int
253296
xmlSecGnuTLSX509GetVerificationFlags(const xmlSecKeyInfoCtx* keyInfoCtx,
254297
unsigned int* flags) {
@@ -258,8 +301,13 @@ xmlSecGnuTLSX509GetVerificationFlags(const xmlSecKeyInfoCtx* keyInfoCtx,
258301
(*flags) = 0;
259302

260303
/* gnutls doesn't allow to specify "verification" timestamp so
261-
we have to do it ourselves */
262-
(*flags) |= GNUTLS_VERIFY_DISABLE_TIME_CHECKS;
304+
we have to do it ourselves; disable the gnutls time checks only
305+
in this case, otherwise gnutls checks the validity periods of
306+
all certificates (including the trusted ones) against the
307+
current time */
308+
if(keyInfoCtx->certsVerificationTime > 0) {
309+
(*flags) |= GNUTLS_VERIFY_DISABLE_TIME_CHECKS;
310+
}
263311

264312
if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_SKIP_STRICT_CHECKS) != 0) {
265313
(*flags) |= GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2;
@@ -471,12 +519,32 @@ xmlSecGnuTLSX509StoreVerify(xmlSecKeyDataStorePtr store,
471519
}
472520

473521
/* gnutls doesn't allow to specify "verification" timestamp so
474-
we have to do it ourselves */
475-
ret = xmlSecGnuTLSX509CheckTime(cert_list, cert_list_cur_size, verification_time);
476-
if(ret != 1) {
477-
xmlSecInternalError("xmlSecGnuTLSX509CheckTime", NULL);
478-
/* ignore error, don't stop, continue! */
479-
continue;
522+
we have to do it ourselves (gnutls only checks the time against
523+
the current time, which is not the custom verification time) */
524+
if(keyInfoCtx->certsVerificationTime > 0) {
525+
ret = xmlSecGnuTLSX509CheckTime(cert_list, cert_list_cur_size, verification_time);
526+
if(ret < 0) {
527+
xmlSecInternalError("xmlSecGnuTLSX509CheckTime", NULL);
528+
/* ignore error, don't stop, continue! */
529+
continue;
530+
} else if(ret != 1) {
531+
/* cert in the candidate chain is not valid at verification time */
532+
continue;
533+
}
534+
535+
/* GNUTLS_VERIFY_DISABLE_TIME_CHECKS disables time checks for trusted
536+
certs too, so check only the trust anchor candidates for this
537+
chain instead of all trusted certs in the store. */
538+
ret = xmlSecGnuTLSX509StoreCheckTrustedAnchorTime(ctx,
539+
cert_list[cert_list_cur_size - 1], verification_time);
540+
if(ret < 0) {
541+
xmlSecInternalError("xmlSecGnuTLSX509StoreCheckTrustedAnchorTime", NULL);
542+
/* ignore error, don't stop, continue! */
543+
continue;
544+
} else if(ret != 1) {
545+
/* trusted cert candidate not valid at the verification time */
546+
continue;
547+
}
480548
}
481549

482550
/* DONE! */
@@ -598,18 +666,32 @@ xmlSecGnuTLSX509StoreVerifyIssuerCert(xmlSecGnuTLSX509StoreCtxPtr ctx,
598666
}
599667

600668
/* gnutls doesn't allow to specify "verification" timestamp so
601-
we have to do it ourselves */
602-
verification_time = (keyInfoCtx->certsVerificationTime > 0) ?
603-
keyInfoCtx->certsVerificationTime :
604-
time(0);
605-
ret = xmlSecGnuTLSX509CheckTime(chain, chain_cur_size, verification_time);
606-
if(ret < 0) {
607-
xmlSecInternalError("xmlSecGnuTLSX509CheckTime", NULL);
608-
goto done;
609-
} else if(ret != 1) {
610-
/* issuer cert not valid at the verification time */
611-
res = 0;
612-
goto done;
669+
we have to do it ourselves; GNUTLS_VERIFY_DISABLE_TIME_CHECKS makes
670+
gnutls skip the time checks for the trusted certs as well, so they
671+
have to be checked here too */
672+
if(keyInfoCtx->certsVerificationTime > 0) {
673+
verification_time = keyInfoCtx->certsVerificationTime;
674+
675+
ret = xmlSecGnuTLSX509CheckTime(chain, chain_cur_size, verification_time);
676+
if(ret < 0) {
677+
xmlSecInternalError("xmlSecGnuTLSX509CheckTime", NULL);
678+
goto done;
679+
} else if(ret != 1) {
680+
/* issuer cert not valid at the verification time */
681+
res = 0;
682+
goto done;
683+
}
684+
685+
ret = xmlSecGnuTLSX509StoreCheckTrustedAnchorTime(ctx,
686+
chain[chain_cur_size - 1], verification_time);
687+
if(ret < 0) {
688+
xmlSecInternalError("xmlSecGnuTLSX509StoreCheckTrustedAnchorTime", NULL);
689+
goto done;
690+
} else if(ret != 1) {
691+
/* trusted cert candidate not valid at the verification time */
692+
res = 0;
693+
goto done;
694+
}
613695
}
614696

615697
/* done! */

‎src/keyinfo.c‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1429,6 +1429,10 @@ xmlSecKeyDataEncryptedKeyXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key, xmlNodeP
14291429
}
14301430
xmlSecAssert2(keyInfoCtx->encCtx != NULL, -1);
14311431

1432+
/* setup current recursion levels for the write context */
1433+
keyInfoCtx->encCtx->keyInfoWriteCtx.curRetrievalMethodLevel = keyInfoCtx->curRetrievalMethodLevel;
1434+
keyInfoCtx->encCtx->keyInfoWriteCtx.curEncryptedKeyLevel = keyInfoCtx->curEncryptedKeyLevel + 1;
1435+
14321436
/* encrypt */
14331437
ret = xmlSecEncCtxBinaryEncrypt(keyInfoCtx->encCtx, node, keyBuf, keySize);
14341438
if(ret < 0) {

‎src/kw_aes_des.c‎

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "globals.h"
1717

18+
#include <stdint.h>
1819
#include <stdlib.h>
1920
#include <string.h>
2021

@@ -763,6 +764,21 @@ static const xmlSecByte xmlSecKWAesMagicBlock[XMLSEC_KW_AES_MAGIC_BLOCK_SIZE] =
763764
0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6
764765
};
765766

767+
/* XORs the full 64-bit counter @p counter into the 8-byte A register @p block
768+
* (big-endian), as required by RFC 3394. Only the low byte is not enough: for
769+
* N >= 43 the counter t exceeds 255 and the high bytes must be mixed in too. */
770+
static void
771+
xmlSecKWAesXorCounter(xmlSecByte* block, uint64_t counter) {
772+
xmlSecSize ii;
773+
774+
xmlSecAssert(block != NULL);
775+
776+
for(ii = 0; ii < XMLSEC_KW_AES_MAGIC_BLOCK_SIZE; ++ii) {
777+
/* the shift (up to 56) is well-defined */
778+
block[ii] ^= (xmlSecByte)(counter >> (8 * (XMLSEC_KW_AES_MAGIC_BLOCK_SIZE - 1 - ii)));
779+
}
780+
}
781+
766782
int
767783
xmlSecKWAesEncode(xmlSecKWAesId kwAesId, xmlSecTransformPtr transform,
768784
const xmlSecByte *in, xmlSecSize inSize,
@@ -818,7 +834,7 @@ xmlSecKWAesEncode(xmlSecKWAesId kwAesId, xmlSecTransformPtr transform,
818834
"outWritten2=" XMLSEC_SIZE_FMT, outWritten2);
819835
return(-1);
820836
}
821-
block[7] ^= (xmlSecByte)tt;
837+
xmlSecKWAesXorCounter(block, tt);
822838
memcpy(out, block, 8);
823839
memcpy(p, block + 8, 8);
824840
}
@@ -844,11 +860,19 @@ xmlSecKWAesDecode(xmlSecKWAesId kwAesId, xmlSecTransformPtr transform,
844860
xmlSecAssert2(kwAesId->decrypt != NULL, -1);
845861
xmlSecAssert2(transform != NULL, -1);
846862
xmlSecAssert2(in != NULL, -1);
847-
xmlSecAssert2(inSize >= XMLSEC_KW_AES_MAGIC_BLOCK_SIZE, -1);
848863
xmlSecAssert2(out != NULL, -1);
849864
xmlSecAssert2(outSize >= inSize, -1);
850865
xmlSecAssert2(outWritten != NULL, -1);
851866

867+
/* a valid wrapped key is at least the magic block plus one data block;
868+
* reject a bare magic block (NN == 0) which would otherwise "unwrap" to a
869+
* zero-length key without any decryption or integrity check */
870+
if(inSize < 2 * XMLSEC_KW_AES_MAGIC_BLOCK_SIZE) {
871+
xmlSecInvalidSizeLessThanError("Input data", inSize,
872+
2 * XMLSEC_KW_AES_MAGIC_BLOCK_SIZE, NULL);
873+
return(-1);
874+
}
875+
852876
/* copy input */
853877
if(in != out) {
854878
memcpy(out, in, inSize);
@@ -872,7 +896,7 @@ xmlSecKWAesDecode(xmlSecKWAesId kwAesId, xmlSecTransformPtr transform,
872896

873897
memcpy(block, out, 8);
874898
memcpy(block + 8, p, 8);
875-
block[7] ^= (xmlSecByte)tt;
899+
xmlSecKWAesXorCounter(block, tt);
876900

877901
outWritten2 = 0;
878902
ret = kwAesId->decrypt(transform, block, sizeof(block),

‎src/nss/ciphers.c‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,16 +152,15 @@ xmlSecNssBlockCipherCtxInit(xmlSecNssBlockCipherCtxPtr ctx,
152152
}
153153

154154
symKey = PK11_ImportSymKey(slot, ctx->cipher, PK11_OriginDerive,
155-
CKA_ENCRYPT, &keyItem, NULL);
155+
(encrypt) ? CKA_ENCRYPT : CKA_DECRYPT, &keyItem, NULL);
156156
if(symKey == NULL) {
157157
xmlSecNssError("PK11_ImportSymKey", cipherName);
158158
PK11_FreeSlot(slot);
159159
return(-1);
160160
}
161161

162162
ctx->cipherCtx = PK11_CreateContextBySymKey(ctx->cipher,
163-
(encrypt) ? CKA_ENCRYPT : CKA_DECRYPT,
164-
symKey, &ivItem);
163+
(encrypt) ? CKA_ENCRYPT : CKA_DECRYPT, symKey, &ivItem);
165164
if(ctx->cipherCtx == NULL) {
166165
xmlSecNssError("PK11_CreateContextBySymKey", cipherName);
167166
PK11_FreeSymKey(symKey);

‎src/nss/keytrans.c‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,11 @@ xmlSecNssKeyTransportCtxFinal(xmlSecNssKeyTransportCtxPtr ctx, xmlSecBufferPtr i
449449
SECItem* keyItem;
450450

451451
/* pay attention to mechanism */
452-
symKey = PK11_PubUnwrapSymKey(ctx->prikey, &oriskv, ctx->cipher, CKA_UNWRAP, 0);
452+
/* target is the mechanism of the unwrapped symmetric key, which is
453+
* unknown here (passing ctx->cipher, e.g. CKM_RSA_PKCS, would make
454+
* NSS mark the unwrapped session key as CKK_RSA), so pass
455+
* CKM_GENERIC_SECRET_KEY_GEN */
456+
symKey = PK11_PubUnwrapSymKey(ctx->prikey, &oriskv, CKM_GENERIC_SECRET_KEY_GEN, CKA_UNWRAP, 0);
453457
if(symKey == NULL) {
454458
xmlSecNssError("PK11_PubUnwrapSymKey", NULL);
455459
xmlSecBufferDestroy(result);

0 commit comments

Comments
 (0)