Merge pull request #3337 from ronald-cron-arm/include_directories
CMake build system: Declare include directories at the target level.
diff --git a/ChangeLog.d/bugfix_PR3422.txt b/ChangeLog.d/bugfix_PR3422.txt
new file mode 100644
index 0000000..dfe152c
--- /dev/null
+++ b/ChangeLog.d/bugfix_PR3422.txt
@@ -0,0 +1,2 @@
+Bugfix
+ * Fix building library/net_sockets.c and the ssl_mail_client program on NetBSD. Contributed by Nia Alarie in #3422.
diff --git a/ChangeLog.d/pass-unsupported-policies-to-callback.txt b/ChangeLog.d/pass-unsupported-policies-to-callback.txt
new file mode 100644
index 0000000..d139b4c
--- /dev/null
+++ b/ChangeLog.d/pass-unsupported-policies-to-callback.txt
@@ -0,0 +1,4 @@
+Features
+ * Pass the "certificate policies" extension to the callback supplied to
+ mbedtls_x509_crt_parse_der_with_ext_cb() if it contains unsupported
+ policies (#3419).
diff --git a/ChangeLog.d/sysctl-arnd-support.txt b/ChangeLog.d/sysctl-arnd-support.txt
new file mode 100644
index 0000000..14ad674
--- /dev/null
+++ b/ChangeLog.d/sysctl-arnd-support.txt
@@ -0,0 +1,2 @@
+Features
+ * Added support to entropy_poll for the kern.arandom syscall supported on some BSD systems. Contributed by Nia Alarie in #3423.
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index 9a9b397..ab0d0cd 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -308,7 +308,11 @@
*
* Callbacks of this type are passed to and used by the
* mbedtls_x509_crt_parse_der_with_ext_cb() routine when
- * it encounters an unsupported extension.
+ * it encounters either an unsupported extension or a
+ * "certificate policies" extension containing any
+ * unsupported certificate policies.
+ * Future versions of the library may invoke the callback
+ * in other cases, if and when the need arises.
*
* \param p_ctx An opaque context passed to the callback.
* \param crt The certificate being parsed.
@@ -360,7 +364,9 @@
* mbedtls_x509_crt_parse_der(), and/or
* mbedtls_x509_crt_parse_der_nocopy()
* but it calls the callback with every unsupported
- * certificate extension.
+ * certificate extension and additionally the
+ * "certificate policies" extension if it contains any
+ * unsupported certificate policies.
* The callback must return a negative error code if it
* does not know how to handle such an extension.
* When the callback fails to parse a critical extension
@@ -368,6 +374,8 @@
* When the callback fails to parse a non critical extension
* mbedtls_x509_crt_parse_der_with_ext_cb() simply skips
* the extension and continues parsing.
+ * Future versions of the library may invoke the callback
+ * in other cases, if and when the need arises.
*
* \return \c 0 if successful.
* \return A negative error code on failure.
diff --git a/library/entropy_poll.c b/library/entropy_poll.c
index 8b4a5af..dc62183 100644
--- a/library/entropy_poll.c
+++ b/library/entropy_poll.c
@@ -115,6 +115,41 @@
#endif /* SYS_getrandom */
#endif /* __linux__ || __midipix__ */
+/*
+ * Some BSD systems provide KERN_ARND.
+ * This is equivalent to reading from /dev/urandom, only it doesn't require an
+ * open file descriptor, and provides up to 256 bytes per call (basically the
+ * same as getentropy(), but with a longer history).
+ *
+ * Documentation: https://netbsd.gw.com/cgi-bin/man-cgi?sysctl+7
+ */
+#if (defined(__FreeBSD__) || defined(__NetBSD__)) && !defined(HAVE_GETRANDOM)
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#if defined(KERN_ARND)
+#define HAVE_SYSCTL_ARND
+
+static int sysctl_arnd_wrapper( unsigned char *buf, size_t buflen )
+{
+ int name[2];
+ size_t len;
+
+ name[0] = CTL_KERN;
+ name[1] = KERN_ARND;
+
+ while( buflen > 0 )
+ {
+ len = buflen > 256 ? 256 : buflen;
+ if( sysctl(name, 2, buf, &len, NULL, 0) == -1 )
+ return( -1 );
+ buflen -= len;
+ buf += len;
+ }
+ return( 0 );
+}
+#endif /* KERN_ARND */
+#endif /* __FreeBSD__ || __NetBSD__ */
+
#include <stdio.h>
int mbedtls_platform_entropy_poll( void *data,
@@ -139,6 +174,15 @@
((void) ret);
#endif /* HAVE_GETRANDOM */
+#if defined(HAVE_SYSCTL_ARND)
+ ((void) file);
+ ((void) read_len);
+ if( sysctl_arnd_wrapper( output, len ) == -1 )
+ return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
+ *olen = len;
+ return( 0 );
+#else
+
*olen = 0;
file = fopen( "/dev/urandom", "rb" );
@@ -156,6 +200,7 @@
*olen = len;
return( 0 );
+#endif /* HAVE_SYSCTL_ARND */
}
#endif /* _WIN32 && !EFIX64 && !EFI32 */
#endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */
diff --git a/library/net_sockets.c b/library/net_sockets.c
index 8258aea..b26e858 100644
--- a/library/net_sockets.c
+++ b/library/net_sockets.c
@@ -23,6 +23,7 @@
* be set before config.h, which pulls in glibc's features.h indirectly.
* Harmless on other platforms. */
#define _POSIX_C_SOURCE 200112L
+#define _XOPEN_SOURCE 600 /* sockaddr_storage */
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
@@ -322,7 +323,8 @@
struct sockaddr_storage client_addr;
#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \
- defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t)
+ defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t) || \
+ defined(socklen_t)
socklen_t n = (socklen_t) sizeof( client_addr );
socklen_t type_len = (socklen_t) sizeof( type );
#else
diff --git a/library/x509_crt.c b/library/x509_crt.c
index ee3b48d..04822e8 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -894,7 +894,7 @@
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
- unsigned char *end_ext_data, *end_ext_octet;
+ unsigned char *end_ext_data, *start_ext_octet, *end_ext_octet;
if( *p == end )
return( 0 );
@@ -940,6 +940,7 @@
MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ start_ext_octet = *p;
end_ext_octet = *p + len;
if( end_ext_octet != end_ext_data )
@@ -1025,6 +1026,13 @@
if( ( ret = x509_get_certificate_policies( p, end_ext_octet,
&crt->certificate_policies ) ) != 0 )
{
+ /* Give the callback (if any) a chance to handle the extension
+ * if it contains unsupported policies */
+ if( ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE && cb != NULL &&
+ cb( p_ctx, crt, &extn_oid, is_critical,
+ start_ext_octet, end_ext_octet ) == 0 )
+ break;
+
#if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
if( is_critical )
return( ret );
diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c
index 08ff025..b7458cd 100644
--- a/programs/ssl/ssl_mail_client.c
+++ b/programs/ssl/ssl_mail_client.c
@@ -23,6 +23,7 @@
* be set before config.h, which pulls in glibc's features.h indirectly.
* Harmless on other platforms. */
#define _POSIX_C_SOURCE 200112L
+#define _XOPEN_SOURCE 600
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
diff --git a/tests/git-scripts/pre-push.sh b/tests/git-scripts/pre-push.sh
index d3b4629..b9cdc0e 100755
--- a/tests/git-scripts/pre-push.sh
+++ b/tests/git-scripts/pre-push.sh
@@ -45,18 +45,4 @@
set -eu
-run_test()
-{
- TEST=$1
- echo "running '$TEST'"
- if ! `$TEST > /dev/null 2>&1`; then
- echo "test '$TEST' failed"
- return 1
- fi
-}
-
-run_test ./tests/scripts/check-doxy-blocks.pl
-run_test ./tests/scripts/check-names.sh
-run_test ./tests/scripts/check-generated-files.sh
-run_test ./tests/scripts/check-files.py
-run_test ./tests/scripts/doxygen.sh
+tests/scripts/all.sh -q -k 'check_*'
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 865c73d..01f5910 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -133,8 +133,17 @@
append_outcome=0
MEMORY=0
FORCE=0
+ QUIET=0
KEEP_GOING=0
+ # Seed value used with the --release-test option.
+ #
+ # See also RELEASE_SEED in basic-build-test.sh. Debugging is easier if
+ # both values are kept in sync. If you change the value here because it
+ # breaks some tests, you'll definitely want to change it in
+ # basic-build-test.sh as well.
+ RELEASE_SEED=1
+
: ${MBEDTLS_TEST_OUTCOME_FILE=}
: ${MBEDTLS_TEST_PLATFORM="$(uname -s | tr -c \\n0-9A-Za-z _)-$(uname -m | tr -c \\n0-9A-Za-z _)"}
export MBEDTLS_TEST_OUTCOME_FILE
@@ -213,6 +222,7 @@
--list-components List components supported on this platform and exit.
General options:
+ -q|--quiet Only output component names, and errors if any.
-f|--force Force the tests to overwrite any modified files.
-k|--keep-going Run all tests and report errors at the end.
-m|--memory Additional optional memory tests.
@@ -228,11 +238,12 @@
--no-force Refuse to overwrite modified files (default).
--no-keep-going Stop at the first error (default).
--no-memory No additional memory tests (default).
+ --no-quiet Print full ouput from components.
--out-of-source-dir=<path> Directory used for CMake out-of-source build tests.
--outcome-file=<path> File where test outcomes are written (not done if
empty; default: \$MBEDTLS_TEST_OUTCOME_FILE).
--random-seed Use a random seed value for randomized tests (default).
- -r|--release-test Run this script in release mode. This fixes the seed value to 1.
+ -r|--release-test Run this script in release mode. This fixes the seed value to ${RELEASE_SEED}.
-s|--seed Integer seed value to use for this test run.
Tool path options:
@@ -301,6 +312,11 @@
else
current_section="$1"
fi
+
+ if [ $QUIET -eq 1 ]; then
+ return
+ fi
+
echo ""
echo "******************************************************************"
echo "* $current_section "
@@ -376,13 +392,15 @@
--no-force) FORCE=0;;
--no-keep-going) KEEP_GOING=0;;
--no-memory) MEMORY=0;;
+ --no-quiet) QUIET=0;;
--openssl) shift; OPENSSL="$1";;
--openssl-legacy) shift; OPENSSL_LEGACY="$1";;
--openssl-next) shift; OPENSSL_NEXT="$1";;
--outcome-file) shift; MBEDTLS_TEST_OUTCOME_FILE="$1";;
--out-of-source-dir) shift; OUT_OF_SOURCE_DIR="$1";;
+ --quiet|-q) QUIET=1;;
--random-seed) unset SEED;;
- --release-test|-r) SEED=1;;
+ --release-test|-r) SEED=$RELEASE_SEED;;
--seed|-s) shift; SEED="$1";;
-*)
echo >&2 "Unknown option: $1"
@@ -462,7 +480,7 @@
failure_summary="$failure_summary
$text"
failure_count=$((failure_count + 1))
- echo "${start_red}^^^^$text^^^^${end_color}"
+ echo "${start_red}^^^^$text^^^^${end_color}" >&2
fi
}
make () {
@@ -508,6 +526,24 @@
! "$@"
}
+pre_setup_quiet_redirect () {
+ if [ $QUIET -ne 1 ]; then
+ redirect_out () {
+ "$@"
+ }
+ redirect_err () {
+ "$@"
+ }
+ else
+ redirect_out () {
+ "$@" >/dev/null
+ }
+ redirect_err () {
+ "$@" 2>/dev/null
+ }
+ fi
+}
+
pre_prepare_outcome_file () {
case "$MBEDTLS_TEST_OUTCOME_FILE" in
[!/]*) MBEDTLS_TEST_OUTCOME_FILE="$PWD/$MBEDTLS_TEST_OUTCOME_FILE";;
@@ -518,6 +554,10 @@
}
pre_print_configuration () {
+ if [ $QUIET -eq 1 ]; then
+ return
+ fi
+
msg "info: $0 configuration"
echo "MEMORY: $MEMORY"
echo "FORCE: $FORCE"
@@ -592,6 +632,11 @@
"$ARMC6_CC" "$ARMC6_AR" "$ARMC6_FROMELF";;
esac
+ # past this point, no call to check_tool, only printing output
+ if [ $QUIET -eq 1 ]; then
+ return
+ fi
+
msg "info: output_env.sh"
case $RUN_COMPONENTS in
*_armcc*)
@@ -657,7 +702,13 @@
component_check_test_cases () {
msg "Check: test case descriptions" # < 1s
- record_status tests/scripts/check-test-cases.py
+ if [ $QUIET -eq 1 ]; then
+ opt='--quiet'
+ else
+ opt=''
+ fi
+ record_status tests/scripts/check-test-cases.py $opt
+ unset opt
}
component_check_doxygen_warnings () {
@@ -1911,7 +1962,10 @@
component_check_generate_test_code () {
msg "uint test: generate_test_code.py"
- record_status ./tests/scripts/test_generate_test_code.py
+ # unittest writes out mundane stuff like number or tests run on stderr.
+ # Our convention is to reserve stderr for actual errors, and write
+ # harmless info on stdout so it can be suppress with --quiet.
+ record_status ./tests/scripts/test_generate_test_code.py 2>&1
}
################################################################
@@ -1942,13 +1996,18 @@
# Unconditionally create a seedfile that's sufficiently long.
# Do this before each component, because a previous component may
# have messed it up or shortened it.
- dd if=/dev/urandom of=./tests/seedfile bs=64 count=1
+ redirect_err dd if=/dev/urandom of=./tests/seedfile bs=64 count=1
# Run the component code.
- "$@"
+ if [ $QUIET -eq 1 ]; then
+ # msg() is silenced, so just print the component name here
+ echo "${current_component#component_}"
+ fi
+ redirect_out "$@"
# Restore the build tree to a clean state.
cleanup
+ unset current_component
}
# Preliminary setup
@@ -1966,6 +2025,7 @@
"$@"
}
fi
+pre_setup_quiet_redirect
pre_prepare_outcome_file
pre_print_configuration
pre_check_tools
diff --git a/tests/scripts/basic-build-test.sh b/tests/scripts/basic-build-test.sh
index 4fb9247..83646f3 100755
--- a/tests/scripts/basic-build-test.sh
+++ b/tests/scripts/basic-build-test.sh
@@ -56,6 +56,14 @@
: ${GNUTLS_LEGACY_CLI:="$GNUTLS_CLI"}
: ${GNUTLS_LEGACY_SERV:="$GNUTLS_SERV"}
+# Used to make ssl-opt.sh deterministic.
+#
+# See also RELEASE_SEED in all.sh. Debugging is easier if both values are kept
+# in sync. If you change the value here because it breaks some tests, you'll
+# definitely want to change it in all.sh as well.
+: ${SEED:=1}
+export SEED
+
# To avoid setting OpenSSL and GnuTLS for each call to compat.sh and ssl-opt.sh
# we just export the variables they require
export OPENSSL_CMD="$OPENSSL"
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index 0ba3b2c..d5f538b 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -2032,6 +2032,22 @@
depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
x509parse_crt_cb:"308203353082021da00302010202104d3ebbb8a870f9c78c55a8a7e12fd516300d06092a864886f70d01010b05003010310e300c06035504030c0564756d6d79301e170d3230303432383137343234335a170d3230303632373137343234335a3010310e300c06035504030c0564756d6d7930820122300d06092a864886f70d01010105000382010f003082010a0282010100a51b75b3f7da2d60ea1b0fc077f0dbb2bbb6fe1b474028368af8dc2664672896efff171033b0aede0b323a89d5c6db4d517404bc97b65264e41b9e9e86a6f40ace652498d4b3b859544d1bacfd7f86325503eed046f517406545c0ffb5560f83446dedce0fcafcc41ac8495488a6aa912ae45192ef7e3efa20d0f7403b0baa62c7e2e5404c620c5793623132aa20f624f08d88fbf0985af39433f5a24d0b908e5219d8ba6a404d3ee8418203b62a40c8eb18837354d50281a6a2bf5012e505c419482787b7a81e5935613ceea0c6d93e86f76282b6aa406fb3a1796c56b32e8a22afc3f7a3c9daa8f0e2846ff0d50abfc862a52f6cf0aaece6066c860376f3ed0203010001a3818a308187300c0603551d13040530030101ff30130603551d110101ff04093007820564756d6d79301206082b0601050507011e0101000403040100300e0603551d0f0101ff040403020184301d0603551d0e04160414e6e451ec8d19d9677b2d272a9d73b939fa2d915a301f0603551d23041830168014e6e451ec8d19d9677b2d272a9d73b939fa2d915a300d06092a864886f70d01010b0500038201010056d06047b7f48683e2347ca726997d9700b4f2cf1d8bc0ef17addac8445d38ffd7f8079055ead878b6a74c8384d0e30150c8990aa74f59cda6ebcb49465d8991ffa16a4c927a26e4639d1875a3ac396c7455c7eda40dbe66054a03d27f961c15e86bd5b06db6b26572977bcda93453b6b6a88ef96b31996a7bd17323525b33050d28deec9c33a3f9765a11fb99d0e222bd39a6db3a788474c9ca347377688f837d42f5841667bffcbe6b473e6f229f286a0829963e591a99aa7f67e9d20c36ccd2ac84cb85b7a8b3396a6cbe59a573ffff726f373197c230de5c92a52c5bc87e29c20bdf6e89609764a60c649022aabd768f3557661b083ae00e6afc8a5bf2ed":"cert. version \: 3\nserial number \: 4D\:3E\:BB\:B8\:A8\:70\:F9\:C7\:8C\:55\:A8\:A7\:E1\:2F\:D5\:16\nissuer name \: CN=dummy\nsubject name \: CN=dummy\nissued on \: 2020-04-28 17\:42\:43\nexpires on \: 2020-06-27 17\:42\:43\nsigned using \: RSA with SHA-256\nRSA key size \: 2048 bits\nbasic constraints \: CA=true\nsubject alt name \:\n dNSName \: dummy\nkey usage \: Digital Signature, Key Cert Sign\n":0
+X509 CRT ASN1 (Unsupported critical policy recognized by callback)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
+x509parse_crt_cb:"3081b130819ba0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092a864886f70d010101050003190030160210ffffffffffffffffffffffffffffffff0202ffffa100a200a315301330110603551d20010101040730053003060101300d06092a864886f70d01010b0500030200ff":"cert. version \: 3\nserial number \: DE\:AD\:BE\:EF\nissuer name \: ??=Test\nsubject name \: ??=Test\nissued on \: 2009-01-01 00\:00\:00\nexpires on \: 2009-12-31 23\:59\:59\nsigned using \: RSA with SHA-256\nRSA key size \: 128 bits\ncertificate policies \: ???\n":0
+
+X509 CRT ASN1 (Unsupported critical policy not recognized by callback)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
+x509parse_crt_cb:"3081b130819ba0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092a864886f70d010101050003190030160210ffffffffffffffffffffffffffffffff0202ffffa100a200a315301330110603551d20010101040730053003060100300d06092a864886f70d01010b0500030200ff":"":MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE
+
+X509 CRT ASN1 (Unsupported non critical policy recognized by callback)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
+x509parse_crt_cb:"3081b130819ba0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092a864886f70d010101050003190030160210ffffffffffffffffffffffffffffffff0202ffffa100a200a315301330110603551d20010100040730053003060101300d06092a864886f70d01010b0500030200ff":"cert. version \: 3\nserial number \: DE\:AD\:BE\:EF\nissuer name \: ??=Test\nsubject name \: ??=Test\nissued on \: 2009-01-01 00\:00\:00\nexpires on \: 2009-12-31 23\:59\:59\nsigned using \: RSA with SHA-256\nRSA key size \: 128 bits\ncertificate policies \: ???\n":0
+
+X509 CRT ASN1 (Unsupported non critical policy not recognized by callback)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
+x509parse_crt_cb:"3081b130819ba0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092a864886f70d010101050003190030160210ffffffffffffffffffffffffffffffff0202ffffa100a200a315301330110603551d20010100040730053003060100300d06092a864886f70d01010b0500030200ff":"cert. version \: 3\nserial number \: DE\:AD\:BE\:EF\nissuer name \: ??=Test\nsubject name \: ??=Test\nissued on \: 2009-01-01 00\:00\:00\nexpires on \: 2009-12-31 23\:59\:59\nsigned using \: RSA with SHA-256\nRSA key size \: 128 bits\ncertificate policies \: ???\n":0
+
X509 CRL ASN1 (Incorrect first tag)
x509parse_crl:"":"":MBEDTLS_ERR_X509_INVALID_FORMAT
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
index 54e5156..9cac2ec 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -303,17 +303,92 @@
}
int parse_crt_ext_cb( void *p_ctx, mbedtls_x509_crt const *crt, mbedtls_x509_buf const *oid,
- int critical, const unsigned char *p, const unsigned char *end )
+ int critical, const unsigned char *cp, const unsigned char *end )
{
( void ) crt;
- ( void ) p;
- ( void ) end;
( void ) critical;
mbedtls_x509_buf *new_oid = (mbedtls_x509_buf *)p_ctx;
- if( new_oid == NULL || new_oid->tag != oid->tag || new_oid->len != oid->len ||
- memcmp(new_oid->p, oid->p, oid->len) != 0 )
+ if( oid->tag == MBEDTLS_ASN1_OID &&
+ MBEDTLS_OID_CMP( MBEDTLS_OID_CERTIFICATE_POLICIES, oid ) == 0 )
+ {
+ /* Handle unknown certificate policy */
+ int ret, parse_ret = 0;
+ size_t len;
+ unsigned char **p = (unsigned char **)&cp;
+
+ /* Get main sequence tag */
+ ret = mbedtls_asn1_get_tag( p, end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE );
+ if( ret != 0 )
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+
+ if( *p + len != end )
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+ /*
+ * Cannot be an empty sequence.
+ */
+ if( len == 0 )
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+ while( *p < end )
+ {
+ const unsigned char *policy_end;
+
+ /*
+ * Get the policy sequence
+ */
+ if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+
+ policy_end = *p + len;
+
+ if( ( ret = mbedtls_asn1_get_tag( p, policy_end, &len,
+ MBEDTLS_ASN1_OID ) ) != 0 )
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+
+ /*
+ * Recognize exclusively the policy with OID 1
+ */
+ if( len != 1 || *p[0] != 1 )
+ parse_ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
+
+ *p += len;
+
+ /*
+ * If there is an optional qualifier, then *p < policy_end
+ * Check the Qualifier len to verify it doesn't exceed policy_end.
+ */
+ if( *p < policy_end )
+ {
+ if( ( ret = mbedtls_asn1_get_tag( p, policy_end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ /*
+ * Skip the optional policy qualifiers.
+ */
+ *p += len;
+ }
+
+ if( *p != policy_end )
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ }
+
+ if( *p != end )
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+ return( parse_ret );
+ }
+ else if( new_oid != NULL && new_oid->tag == oid->tag && new_oid->len == oid->len &&
+ memcmp( new_oid->p, oid->p, oid->len ) == 0 )
+ return( 0 );
+ else
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
- return( 0 );
}
#endif /* MBEDTLS_X509_CRT_PARSE_C */
/* END_HEADER */