diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 830e2d75f7a76048fd73d717112bbc03bd44246a..00be6562451fa7cfb1b2374356fed2d12adc6edb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -251,19 +251,30 @@ jobs: - name: make test run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} - out-of-source-and-install: + # out-of-source-and-install checks multiple things at the same time: + # - That building, testing and installing works from an out-of-source + # build tree + # - That building, testing and installing works with a read-only source + # tree + out-of-readonly-source-and-install: strategy: matrix: os: [ubuntu-latest, macos-latest ] runs-on: ${{matrix.os}} steps: - uses: actions/checkout@v4 - - name: extra preparations + with: + path: ./source + - name: make source read-only + run: chmod -R a-w ./source + - name: create build and install directories run: | mkdir ./build mkdir ./install - name: config - run: ../config --banner=Configured enable-fips enable-acvp-tests --strict-warnings --prefix=$(cd ../install; pwd) && perl configdata.pm --dump + run: | + ../source/config --banner=Configured enable-fips enable-acvp-tests --strict-warnings --prefix=$(cd ../install; pwd) + perl configdata.pm --dump working-directory: ./build - name: make run: make -s -j4 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0117fce16fede75835bb829e51254c8412f72261..15490fd9f620d7fcdfe1e295b23453424cdb3dc1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,19 +9,22 @@ Development is done on GitHub in the [openssl/openssl] repository. [openssl/openssl]: -To request new features or report bugs, please open an issue on GitHub +To request new a feature, ask a question, or report a bug, +please open an [issue on GitHub](https://github.com/openssl/openssl/issues). -To submit a patch, please open a pull request on GitHub. If you are thinking -of making a large contribution, open an issue for it before starting work, -to get comments from the community. Someone may be already working on -the same thing, or there may be reasons why that feature isn't implemented. +To submit a patch or implement a new feature, please open a +[pull request on GitHub](https://github.com/openssl/openssl/pulls). +If you are thinking of making a large contribution, +open an issue for it before starting work, to get comments from the community. +Someone may be already working on the same thing, +or there may be special reasons why a feature is not implemented. To make it easier to review and accept your pull request, please follow these guidelines: 1. Anything other than a trivial contribution requires a [Contributor License Agreement] (CLA), giving us permission to use your code. - If your contribution is too small to require a CLA (e.g. fixing a spelling + If your contribution is too small to require a CLA (e.g., fixing a spelling mistake), then place the text "`CLA: trivial`" on a line by itself below the rest of your commit message separated by an empty line, like this: @@ -64,22 +67,24 @@ guidelines: often. We do not accept merge commits, you will have to remove them (usually by rebasing) before it will be acceptable. - 4. Patches should follow our [coding style] and compile without warnings. + 4. Code provided should follow our [coding style] and compile without warnings. + There is a [Perl tool](util/check-format.pl) that helps + finding code formatting mistakes and other coding style nits. Where `gcc` or `clang` is available, you should use the `--strict-warnings` `Configure` option. OpenSSL compiles on many varied - platforms: try to ensure you only use portable features. Clean builds via - GitHub Actions and AppVeyor are required, and they are started automatically - whenever a PR is created or updated. + platforms: try to ensure you only use portable features. + Clean builds via GitHub Actions are required. They are started automatically + whenever a PR is created or updated by committers. [coding style]: https://www.openssl.org/policies/technical/coding-style.html - 5. When at all possible, patches should include tests. These can + 5. When at all possible, code contributions should include tests. These can either be added to an existing test, or completely new. Please see [test/README.md](test/README.md) for information on the test framework. 6. New features or changed functionality must include - documentation. Please look at the "pod" files in doc/man[1357] for - examples of our style. Run "make doc-nits" to make sure that your + documentation. Please look at the `.pod` files in `doc/man[1357]` for + examples of our style. Run `make doc-nits` to make sure that your documentation changes are clean. 7. For user visible changes (API changes, behaviour changes, ...), @@ -89,7 +94,7 @@ guidelines: Have a look through existing entries for inspiration. Please note that this is NOT simply a copy of git-log one-liners. Also note that security fixes get an entry in [CHANGES.md](CHANGES.md). - This file helps users get more in depth information of what comes + This file helps users get more in-depth information of what comes with a specific release without having to sift through the higher noise ratio in git-log. diff --git a/Configurations/descrip.mms.tmpl b/Configurations/descrip.mms.tmpl index c69a1cc1f814dae64ed71a661ce12889d6a4bc0f..d0b8d42628c7a4731bfe534496aed65312b9da65 100644 --- a/Configurations/descrip.mms.tmpl +++ b/Configurations/descrip.mms.tmpl @@ -478,7 +478,8 @@ build_all_generated : $(GENERATED_MANDATORY) $(GENERATED) build_docs all : build_sw build_docs test : tests -{- dependmagic('tests'); -} : build_programs_nodep, build_modules_nodep run_tests +{- dependmagic('tests'); -} : build_programs_nodep, build_modules_nodep + $(MMS) $(MMSQUALIFIERS) run_tests run_tests : @ ! {- output_off() if $disabled{tests}; "" -} DEFINE SRCTOP "$(SRCDIR)" diff --git a/Configurations/unix-Makefile.tmpl b/Configurations/unix-Makefile.tmpl index a48fae5fb8b8fecbf47d7ebfd4ef289013909268..3754595d38b50aa7c92589781c9f06604dac4f70 100644 --- a/Configurations/unix-Makefile.tmpl +++ b/Configurations/unix-Makefile.tmpl @@ -526,8 +526,9 @@ build_all_generated: $(GENERATED_MANDATORY) $(GENERATED) build_docs all: build_sw build_docs test: tests -{- dependmagic('tests'); -}: build_programs_nodep build_modules_nodep link-utils run_tests -run_tests: +{- dependmagic('tests'); -}: build_programs_nodep build_modules_nodep link-utils + $(MAKE) run_tests +run_tests: FORCE @ : {- output_off() if $disabled{tests}; "" -} ( SRCTOP=$(SRCDIR) \ BLDTOP=$(BLDDIR) \ diff --git a/Configurations/windows-makefile.tmpl b/Configurations/windows-makefile.tmpl index ae6daa225651c03b217fe8bd00764f352dd9a255..504e4bc80314bee1a8ca227247ff3b669083baa9 100644 --- a/Configurations/windows-makefile.tmpl +++ b/Configurations/windows-makefile.tmpl @@ -440,6 +440,8 @@ all: build_sw build_docs test: tests {- dependmagic('tests'); -}: build_programs_nodep build_modules_nodep copy-utils + $(MAKE) /$(MAKEFLAGS) run_tests +run_tests: @{- output_off() if $disabled{tests}; "\@rem" -} cmd /C "set "SRCTOP=$(SRCDIR)" & set "BLDTOP=$(BLDDIR)" & set "PERL=$(PERL)" & set "FIPSKEY=$(FIPSKEY)" & "$(PERL)" "$(SRCDIR)\test\run_tests.pl" $(TESTS)" @{- if ($disabled{tests}) { output_on(); } else { output_off(); } "" -} diff --git a/Configure b/Configure index d058451d8ad95f23a8d7a89e99fb046591571a26..fc044854dd978c4921d8f1d52ec584a7d14b10c5 100755 --- a/Configure +++ b/Configure @@ -1822,11 +1822,12 @@ if ($builder eq "unified") { my $base = shift; my $dir = shift; my $relativeto = shift || "."; + my $no_mkpath = shift // 0; $dir = catdir($base,$dir) unless isabsolute($dir); # Make sure the directories we're building in exists - mkpath($dir); + mkpath($dir) unless $no_mkpath; my $res = abs2rel(absolutedir($dir), rel2abs($relativeto)); #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n"; @@ -1837,6 +1838,7 @@ if ($builder eq "unified") { my $base = shift; my $file = shift; my $relativeto = shift || "."; + my $no_mkpath = shift // 0; $file = catfile($base,$file) unless isabsolute($file); @@ -1844,7 +1846,7 @@ if ($builder eq "unified") { my $f = basename($file); # Make sure the directories we're building in exists - mkpath($d); + mkpath($d) unless $no_mkpath; my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($relativeto)); #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n"; @@ -1874,7 +1876,7 @@ if ($builder eq "unified") { } # Then, look in our standard directory push @build_file_templates, - ( map { cleanfile($srcdir, catfile("Configurations", $_), $blddir) } + ( map { cleanfile($srcdir, catfile("Configurations", $_), $blddir, 1) } @build_file_template_names ); my $build_file_template; @@ -1889,7 +1891,7 @@ if ($builder eq "unified") { } $config{build_file_templates} = [ cleanfile($srcdir, catfile("Configurations", "common0.tmpl"), - $blddir), + $blddir, 1), $build_file_template ]; my @build_dirs = ( [ ] ); # current directory @@ -1898,7 +1900,7 @@ if ($builder eq "unified") { # We want to detect configdata.pm in the source tree, so we # don't use it if the build tree is different. - my $src_configdata = cleanfile($srcdir, "configdata.pm", $blddir); + my $src_configdata = cleanfile($srcdir, "configdata.pm", $blddir, 1); # Any source file that we recognise is placed in this hash table, with # the list of its intended destinations as value. When everything has @@ -2251,7 +2253,7 @@ EOF my $dest = $_; my $ddest = cleanfile($buildd, $_, $blddir); foreach (@{$sources{$dest}}) { - my $s = cleanfile($sourced, $_, $blddir); + my $s = cleanfile($sourced, $_, $blddir, 1); # If it's generated or we simply don't find it in the source # tree, we assume it's in the build tree. @@ -2296,7 +2298,7 @@ EOF my $dest = $_; my $ddest = cleanfile($buildd, $_, $blddir); foreach (@{$shared_sources{$dest}}) { - my $s = cleanfile($sourced, $_, $blddir); + my $s = cleanfile($sourced, $_, $blddir, 1); # If it's generated or we simply don't find it in the source # tree, we assume it's in the build tree. @@ -2351,7 +2353,7 @@ EOF if scalar @{$generate{$_}} > 1; my @generator = split /\s+/, $generate{$dest}->[0]; my $gen = $generator[0]; - $generator[0] = cleanfile($sourced, $gen, $blddir); + $generator[0] = cleanfile($sourced, $gen, $blddir, 1); # If the generator is itself generated, it's in the build tree if ($generate{$gen} || ! -f $generator[0]) { @@ -2377,7 +2379,7 @@ EOF } elsif ($dest eq '') { $ddest = ''; } else { - $ddest = cleanfile($sourced, $_, $blddir); + $ddest = cleanfile($sourced, $_, $blddir, 1); # If the destination doesn't exist in source, it can only be # a generated file in the build tree. @@ -2386,7 +2388,7 @@ EOF } } foreach (@{$depends{$dest}}) { - my $d = cleanfile($sourced, $_, $blddir); + my $d = cleanfile($sourced, $_, $blddir, 1); my $d2 = cleanfile($buildd, $_, $blddir); # If we know it's generated, or assume it is because we can't @@ -2409,7 +2411,7 @@ EOF foreach (keys %includes) { my $dest = $_; - my $ddest = cleanfile($sourced, $_, $blddir); + my $ddest = cleanfile($sourced, $_, $blddir, 1); # If the destination doesn't exist in source, it can only be # a generated file in the build tree. @@ -2417,7 +2419,7 @@ EOF $ddest = cleanfile($buildd, $_, $blddir); } foreach (@{$includes{$dest}}) { - my $is = cleandir($sourced, $_, $blddir); + my $is = cleandir($sourced, $_, $blddir, 1); my $ib = cleandir($buildd, $_, $blddir); push @{$unified_info{includes}->{$ddest}->{source}}, $is unless grep { $_ eq $is } @{$unified_info{includes}->{$ddest}->{source}}; @@ -2430,7 +2432,7 @@ EOF my $ddest; if ($dest ne "") { - $ddest = cleanfile($sourced, $dest, $blddir); + $ddest = cleanfile($sourced, $dest, $blddir, 1); # If the destination doesn't exist in source, it can only # be a generated file in the build tree. @@ -2812,7 +2814,7 @@ my %template_vars = ( my $configdata_outname = 'configdata.pm'; open CONFIGDATA, ">$configdata_outname.new" or die "Trying to create $configdata_outname.new: $!"; -my $configdata_tmplname = cleanfile($srcdir, "configdata.pm.in", $blddir); +my $configdata_tmplname = cleanfile($srcdir, "configdata.pm.in", $blddir, 1); my $configdata_tmpl = OpenSSL::Template->new(TYPE => 'FILE', SOURCE => $configdata_tmplname); $configdata_tmpl->fill_in( diff --git a/apps/cms.c b/apps/cms.c index 12095b9641c8777fcb3e4a9900a16889f2bbd447..3994cb0fcd58cf5eb052ead31f301abbc9a380d8 100644 --- a/apps/cms.c +++ b/apps/cms.c @@ -620,7 +620,8 @@ int cms_main(int argc, char **argv) "recipient certificate file"); if (cert == NULL) goto end; - sk_X509_push(encerts, cert); + if (!sk_X509_push(encerts, cert)) + goto end; cert = NULL; } else { recipfile = opt_arg(); @@ -831,7 +832,8 @@ int cms_main(int argc, char **argv) "recipient certificate file"); if (cert == NULL) goto end; - sk_X509_push(encerts, cert); + if (!sk_X509_push(encerts, cert)) + goto end; cert = NULL; } } diff --git a/apps/errstr.c b/apps/errstr.c index 782705a78a33d27d0139ae7dbaa4fa86b4ad9505..21349d21cb4207436dcfc2db95e193e4e925e0e7 100644 --- a/apps/errstr.c +++ b/apps/errstr.c @@ -62,7 +62,7 @@ int errstr_main(int argc, char **argv) /* All remaining arg are error code. */ ret = 0; for (argv = opt_rest(); *argv != NULL; argv++) { - if (sscanf(*argv, "%lx", &l) == 0) { + if (sscanf(*argv, "%lx", &l) <= 0) { ret++; } else { ERR_error_string_n(l, buf, sizeof(buf)); diff --git a/apps/lib/opt.c b/apps/lib/opt.c index 157367982d2fa9f71a596d927aceda38e5fe35e0..d56964dbe7ba9a391e4ea9516418eefef5116522 100644 --- a/apps/lib/opt.c +++ b/apps/lib/opt.c @@ -696,7 +696,12 @@ int opt_verify(int opt, X509_VERIFY_PARAM *vpm) opt_printf_stderr("%s: Invalid Policy %s\n", prog, opt_arg()); return 0; } - X509_VERIFY_PARAM_add0_policy(vpm, otmp); + if (!X509_VERIFY_PARAM_add0_policy(vpm, otmp)) { + ASN1_OBJECT_free(otmp); + opt_printf_stderr("%s: Internal error adding Policy %s\n", + prog, opt_arg()); + return 0; + } break; case OPT_V_PURPOSE: /* purpose name -> purpose index */ diff --git a/apps/rehash.c b/apps/rehash.c index d63a0909a2bbc98bc85820dd2112abf94bd62619..85eee3857942dd46a240c68cbb818171c38ab5db 100644 --- a/apps/rehash.c +++ b/apps/rehash.c @@ -383,6 +383,7 @@ static int do_dir(const char *dirname, enum Hash h) if ((copy = OPENSSL_strdup(filename)) == NULL || sk_OPENSSL_STRING_push(files, copy) == 0) { OPENSSL_free(copy); + OPENSSL_DIR_end(&d); BIO_puts(bio_err, "out of memory\n"); errs = 1; goto err; diff --git a/apps/smime.c b/apps/smime.c index a2ff0b5be75c834894be863a74155e1f09b39f68..52b4a01c232f9f1d1b44eb5279ec6b929b996602 100644 --- a/apps/smime.c +++ b/apps/smime.c @@ -453,7 +453,8 @@ int smime_main(int argc, char **argv) "recipient certificate file"); if (cert == NULL) goto end; - sk_X509_push(encerts, cert); + if (!sk_X509_push(encerts, cert)) + goto end; cert = NULL; argv++; } diff --git a/crypto/bn/bn_gf2m.c b/crypto/bn/bn_gf2m.c index 304c2ea08d0e950b9ad8d26f5fc8e5b580ffc156..c811ae82d6b15a82fccd2d13eaf581f4d19259b4 100644 --- a/crypto/bn/bn_gf2m.c +++ b/crypto/bn/bn_gf2m.c @@ -734,14 +734,20 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) { BIGNUM *b = NULL; int ret = 0; + int numbits; BN_CTX_start(ctx); if ((b = BN_CTX_get(ctx)) == NULL) goto err; + /* Fail on a non-sensical input p value */ + numbits = BN_num_bits(p); + if (numbits <= 1) + goto err; + /* generate blinding value */ do { - if (!BN_priv_rand_ex(b, BN_num_bits(p) - 1, + if (!BN_priv_rand_ex(b, numbits - 1, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, 0, ctx)) goto err; } while (BN_is_zero(b)); diff --git a/crypto/http/http_lib.c b/crypto/http/http_lib.c index 3164d01d9e48fe1fd4841598f5bb47605eac1d9d..cd0e25c85e4e1f5b1019380b3689c74443bf6cd9 100644 --- a/crypto/http/http_lib.c +++ b/crypto/http/http_lib.c @@ -118,7 +118,7 @@ int OSSL_parse_url(const char *url, char **pscheme, char **puser, char **phost, port = ++p; /* remaining port spec handling is also done for the default values */ /* make sure a decimal port number is given */ - if (!sscanf(port, "%u", &portnum) || portnum > 65535) { + if (sscanf(port, "%u", &portnum) <= 0 || portnum > 65535) { ERR_raise_data(ERR_LIB_HTTP, HTTP_R_INVALID_PORT_NUMBER, "%s", port); goto err; } diff --git a/crypto/md5/asm/md5-aarch64.pl b/crypto/md5/asm/md5-aarch64.pl index 3200a0fa9bff08c6da24129dd0c7e83e49566d95..5a8608069691d13c2470de4dc5710c38f49cc19d 100755 --- a/crypto/md5/asm/md5-aarch64.pl +++ b/crypto/md5/asm/md5-aarch64.pl @@ -28,10 +28,13 @@ open OUT,"| \"$^X\" $xlate $flavour \"$output\"" *STDOUT=*OUT; $code .= < INT_MAX) { + if (bsize > INT_MAX) { ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_STRING_TOO_LONG); return 0; } @@ -260,9 +260,9 @@ int OSSL_PARAM_BLD_push_utf8_ptr(OSSL_PARAM_BLD *bld, const char *key, { OSSL_PARAM_BLD_DEF *pd; - if (bsize == 0) { + if (bsize == 0) bsize = strlen(buf); - } else if (bsize > INT_MAX) { + if (bsize > INT_MAX) { ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_STRING_TOO_LONG); return 0; } diff --git a/crypto/property/property_parse.c b/crypto/property/property_parse.c index 8ba42a0dcb8adea72409841e9d49760c9208ec9d..f94d0d3d41db41b41c65ac52e30a9ad1e56f2ad3 100644 --- a/crypto/property/property_parse.c +++ b/crypto/property/property_parse.c @@ -97,9 +97,18 @@ static int parse_number(const char *t[], OSSL_PROPERTY_DEFINITION *res) const char *s = *t; int64_t v = 0; - if (!ossl_isdigit(*s)) - return 0; do { + if (!ossl_isdigit(*s)) { + ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_A_DECIMAL_DIGIT, + "HERE-->%s", *t); + return 0; + } + /* overflow check */ + if (v > ((INT64_MAX - (*s - '0')) / 10)) { + ERR_raise_data(ERR_LIB_PROP, PROP_R_PARSE_FAILED, + "Property %s overflows", *t); + return 0; + } v = v * 10 + (*s++ - '0'); } while (ossl_isdigit(*s)); if (!ossl_isspace(*s) && *s != '\0' && *s != ',') { @@ -117,15 +126,27 @@ static int parse_hex(const char *t[], OSSL_PROPERTY_DEFINITION *res) { const char *s = *t; int64_t v = 0; + int sval; - if (!ossl_isxdigit(*s)) - return 0; do { + if (ossl_isdigit(*s)) { + sval = *s - '0'; + } else if (ossl_isxdigit(*s)) { + sval = ossl_tolower(*s) - 'a' + 10; + } else { + ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_HEXADECIMAL_DIGIT, + "%s", *t); + return 0; + } + + if (v > ((INT64_MAX - sval) / 16)) { + ERR_raise_data(ERR_LIB_PROP, PROP_R_PARSE_FAILED, + "Property %s overflows", *t); + return 0; + } + v <<= 4; - if (ossl_isdigit(*s)) - v += *s - '0'; - else - v += ossl_tolower(*s) - 'a'; + v += sval; } while (ossl_isxdigit(*++s)); if (!ossl_isspace(*s) && *s != '\0' && *s != ',') { ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_HEXADECIMAL_DIGIT, @@ -143,9 +164,18 @@ static int parse_oct(const char *t[], OSSL_PROPERTY_DEFINITION *res) const char *s = *t; int64_t v = 0; - if (*s == '9' || *s == '8' || !ossl_isdigit(*s)) - return 0; do { + if (*s == '9' || *s == '8' || !ossl_isdigit(*s)) { + ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_OCTAL_DIGIT, + "HERE-->%s", *t); + return 0; + } + if (v > ((INT64_MAX - (*s - '0')) / 8)) { + ERR_raise_data(ERR_LIB_PROP, PROP_R_PARSE_FAILED, + "Property %s overflows", *t); + return 0; + } + v = (v << 3) + (*s - '0'); } while (ossl_isdigit(*++s) && *s != '9' && *s != '8'); if (!ossl_isspace(*s) && *s != '\0' && *s != ',') { diff --git a/crypto/x509/v3_san.c b/crypto/x509/v3_san.c index c081f02e19e41896cd70fbb83c379507a4861499..34ca16a6d72daeb11ada8d6472dddcd9adcf19d0 100644 --- a/crypto/x509/v3_san.c +++ b/crypto/x509/v3_san.c @@ -581,6 +581,8 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, if ((gen->d.ia5 = ASN1_IA5STRING_new()) == NULL || !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value, strlen(value))) { + ASN1_IA5STRING_free(gen->d.ia5); + gen->d.ia5 = NULL; ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } @@ -651,16 +653,21 @@ static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx) */ ASN1_TYPE_free(gen->d.otherName->value); if ((gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)) == NULL) - return 0; + goto err; objlen = p - value; objtmp = OPENSSL_strndup(value, objlen); if (objtmp == NULL) - return 0; + goto err; gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0); OPENSSL_free(objtmp); if (!gen->d.otherName->type_id) - return 0; + goto err; return 1; + + err: + OTHERNAME_free(gen->d.otherName); + gen->d.otherName = NULL; + return 0; } static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx) diff --git a/doc/man3/EVP_EncryptInit.pod b/doc/man3/EVP_EncryptInit.pod index 56b29b52e1185597d75f4fa695c6df21668600c8..a2004e37d70be1d89170fdcaaf80578f7093bbee 100644 --- a/doc/man3/EVP_EncryptInit.pod +++ b/doc/man3/EVP_EncryptInit.pod @@ -373,7 +373,12 @@ exists. =item EVP_EncryptUpdate() Encrypts I bytes from the buffer I and writes the encrypted version to -I. This function can be called multiple times to encrypt successive blocks +I. The pointers I and I may point to the same location, in which +case the encryption will be done in-place. If I and I point to different +locations, the two buffers must be disjoint, otherwise the operation might fail +or the outcome might be undefined. + +This function can be called multiple times to encrypt successive blocks of data. The amount of data written depends on the block alignment of the encrypted data. For most ciphers and modes, the amount of data written can be anything @@ -382,10 +387,9 @@ For wrap cipher modes, the amount of data written can be anything from zero bytes to (inl + cipher_block_size) bytes. For stream ciphers, the amount of data written can be anything from zero bytes to inl bytes. -Thus, I should contain sufficient room for the operation being performed. -The actual number of bytes written is placed in I. It also -checks if I and I are partially overlapping, and if they are -0 is returned to indicate failure. +Thus, the buffer pointed to by I must contain sufficient room for the +operation being performed. +The actual number of bytes written is placed in I. If padding is enabled (the default) then EVP_EncryptFinal_ex() encrypts the "final" data, that is any data that remains in a partial block. diff --git a/doc/man3/OSSL_PARAM_int.pod b/doc/man3/OSSL_PARAM_int.pod index d357818ff14bd969dbf8de82654954885cc33b9e..105fe3241f8788df816a1455d164000501e5cf5c 100644 --- a/doc/man3/OSSL_PARAM_int.pod +++ b/doc/man3/OSSL_PARAM_int.pod @@ -112,7 +112,7 @@ OSSL_PARAM_UNMODIFIED, OSSL_PARAM_modified, OSSL_PARAM_set_all_unmodified A collection of utility functions that simplify and add type safety to the L arrays. The following B> names are supported: -=over 1 +=over 2 =item * diff --git a/doc/man7/provider-cipher.pod b/doc/man7/provider-cipher.pod index 14ff581c72c492f47f3a49fca951eb6b34cd5379..eaad3cf2ff021abeee1c7f44e7e0ec760d59e206 100644 --- a/doc/man7/provider-cipher.pod +++ b/doc/man7/provider-cipher.pod @@ -148,9 +148,13 @@ It is the responsibility of the cipher implementation to handle input lengths that are not multiples of the block length. In such cases a cipher implementation will typically cache partial blocks of input data until a complete block is obtained. -I may be the same location as I but it should not partially overlap. -The same expectations apply to I as documented for -L and L. +The pointers I and I may point to the same location, in which +case the encryption must be done in-place. If I and I point to different +locations, the requirements of L and L +guarantee that the two buffers are disjoint. +Similarly, the requirements of L and L +ensure that the buffer pointed to by I contains sufficient room for the +operation being performed. OSSL_FUNC_cipher_final() completes an encryption or decryption started through previous OSSL_FUNC_cipher_encrypt_init() or OSSL_FUNC_cipher_decrypt_init(), and OSSL_FUNC_cipher_update() diff --git a/doc/man7/provider-storemgmt.pod b/doc/man7/provider-storemgmt.pod index cde95f66e1eee17f11628f24aaf157ae5a0b157f..f39f345fc889700fc99039312d920e1405b5de13 100644 --- a/doc/man7/provider-storemgmt.pod +++ b/doc/man7/provider-storemgmt.pod @@ -162,12 +162,12 @@ fingerprint, computed with the given digest. Indicates that the caller wants to search for an object with the given alias (some call it a "friendly name"). -=item "properties" (B +=item "properties" (B) Property string to use when querying for algorithms such as the B decoder implementations. -=item "input-type" (B +=item "input-type" (B) Type of the input format as a hint to use when decoding the objects in the store. diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c index 2ca3f74ae77102a121169f1abd563c17e8e0254f..ee4f58e75e99ad8c73845856eb9dfb9d1a3369bf 100644 --- a/ssl/s3_enc.c +++ b/ssl/s3_enc.c @@ -225,7 +225,11 @@ int ssl3_change_cipher_state(SSL *s, int which) goto err; } - if (EVP_CIPHER_get0_provider(c) != NULL + /* + * The cipher we actually ended up using in the EVP_CIPHER_CTX may be + * different to that in c if we have an ENGINE in use + */ + if (EVP_CIPHER_get0_provider(EVP_CIPHER_CTX_get0_cipher(dd)) != NULL && !tls_provider_set_tls_params(s, dd, c, m)) { /* SSLfatal already called */ goto err; diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index 91238e6457b8c9a7bee583ca8818dcdab9e73ea6..6cb7baaf7c9c1e5f266338778480be96ab1425a8 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -427,7 +427,12 @@ int tls1_change_cipher_state(SSL *s, int which) SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - if (EVP_CIPHER_get0_provider(c) != NULL + + /* + * The cipher we actually ended up using in the EVP_CIPHER_CTX may be + * different to that in c if we have an ENGINE in use + */ + if (EVP_CIPHER_get0_provider(EVP_CIPHER_CTX_get0_cipher(dd)) != NULL && !tls_provider_set_tls_params(s, dd, c, m)) { /* SSLfatal already called */ goto err; diff --git a/test/bntest.c b/test/bntest.c index e8c8ca4f8de0e12ccc4ccbde1a7b1f30053d6007..f9bde5ef4d603d7fc21604eee7872ddbaed56716 100644 --- a/test/bntest.c +++ b/test/bntest.c @@ -907,6 +907,14 @@ static int test_gf2m_modinv(void) || !TEST_ptr(d = BN_new())) goto err; + /* Test that a non-sensical, too small value causes a failure */ + if (!TEST_true(BN_one(b[0]))) + goto err; + if (!TEST_true(BN_bntest_rand(a, 512, 0, 0))) + goto err; + if (!TEST_false(BN_GF2m_mod_inv(c, a, b[0], ctx))) + goto err; + if (!(TEST_true(BN_GF2m_arr2poly(p0, b[0])) && TEST_true(BN_GF2m_arr2poly(p1, b[1])))) goto err; diff --git a/test/http_test.c b/test/http_test.c index b9f7452744cb92bb6f4f1f82527dfd1ff2d0dcd9..b6897a17fdd8e25e967061e48afb21f2b8599b18 100644 --- a/test/http_test.c +++ b/test/http_test.c @@ -298,7 +298,8 @@ static int test_http_url_invalid_prefix(void) static int test_http_url_invalid_port(void) { - return test_http_url_invalid("https://1.2.3.4:65536/pkix"); + return test_http_url_invalid("https://1.2.3.4:65536/pkix") + && test_http_url_invalid("https://1.2.3.4:"); } static int test_http_url_invalid_path(void) diff --git a/test/property_test.c b/test/property_test.c index bba96fac0a0191613a181805a6c1dfafacb0a7a6..18f8cc8740e0d3d2236a33d8579ac9e55a64e0b7 100644 --- a/test/property_test.c +++ b/test/property_test.c @@ -136,6 +136,10 @@ static const struct { { "n=0x3", "n=3", 1 }, { "n=0x3", "n=-3", -1 }, { "n=0x33", "n=51", 1 }, + { "n=0x123456789abcdef", "n=0x123456789abcdef", 1 }, + { "n=0x7fffffffffffffff", "n=0x7fffffffffffffff", 1 }, /* INT64_MAX */ + { "n=9223372036854775807", "n=9223372036854775807", 1 }, /* INT64_MAX */ + { "n=0777777777777777777777", "n=0777777777777777777777", 1 }, /* INT64_MAX */ { "n=033", "n=27", 1 }, { "n=0", "n=00", 1 }, { "n=0x0", "n=0", 1 }, @@ -198,6 +202,9 @@ static const struct { { 1, "a=2, n=012345678" }, /* Bad octal digit */ { 0, "n=0x28FG, a=3" }, /* Bad hex digit */ { 0, "n=145d, a=2" }, /* Bad decimal digit */ + { 0, "n=0x8000000000000000, a=3" }, /* Hex overflow */ + { 0, "n=922337203000000000d, a=2" }, /* Decimal overflow */ + { 0, "a=2, n=1000000000000000000000" }, /* Octal overflow */ { 1, "@='hello'" }, /* Invalid name */ { 1, "n0123456789012345678901234567890123456789" "0123456789012345678901234567890123456789" diff --git a/test/recipes/01-test_symbol_presence.t b/test/recipes/01-test_symbol_presence.t index 5530ade0addddbfe895554294de20ff713caffd3..3de3d2ccf19bd17561d29796d927a221d339715b 100644 --- a/test/recipes/01-test_symbol_presence.t +++ b/test/recipes/01-test_symbol_presence.t @@ -70,17 +70,35 @@ foreach my $libname (@libnames) { note "Number of lines in \@def_lines before massaging: ", scalar @def_lines; # Massage the nm output to only contain defined symbols + # Common symbols need separate treatment + my %commons; + foreach (@nm_lines) { + if (m|^(.*) C .*|) { + $commons{$1}++; + } + } + foreach (sort keys %commons) { + note "Common symbol: $_"; + } + @nm_lines = sort - map { - # Drop the first space and everything following it - s| .*||; - # Drop OpenSSL dynamic version information if there is any - s|\@\@.+$||; - # Return the result - $_ - } - grep(m|.* [BCDST] .*|, @nm_lines); + ( map { + # Drop the first space and everything following it + s| .*||; + # Drop OpenSSL dynamic version information if there is any + s|\@\@.+$||; + # Return the result + $_ + } + # Drop any symbol starting with a double underscore, they + # are reserved for the compiler / system ABI and are none + # of our business + grep !m|^__|, + # Only look at external definitions + grep m|.* [BDST] .*|, + @nm_lines ), + keys %commons; # Massage the mkdef.pl output to only contain global symbols # The output we got is in Unix .map format, which has a global diff --git a/test/recipes/25-test_req.t b/test/recipes/25-test_req.t index 6ae09c2b8fd271e036dbae2c4f7588e8f4e112af..8035add857bb8d4fc2b5f6193fcfa9042d109c50 100644 --- a/test/recipes/25-test_req.t +++ b/test/recipes/25-test_req.t @@ -15,7 +15,7 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/; setup("test_req"); -plan tests => 46; +plan tests => 48; require_ok(srctop_file('test', 'recipes', 'tconversion.pl')); @@ -40,10 +40,14 @@ my @addext_args = ( "openssl", "req", "-new", "-out", "testreq.pem", "-key", srctop_file("test", "certs", "ee-key.pem"), "-config", srctop_file("test", "test.cnf"), @req_new ); my $val = "subjectAltName=DNS:example.com"; +my $val1 = "subjectAltName=otherName:1.2.3.4;UTF8:test,email:info\@example.com"; my $val2 = " " . $val; my $val3 = $val; $val3 =~ s/=/ =/; ok( run(app([@addext_args, "-addext", $val]))); +ok( run(app([@addext_args, "-addext", $val1]))); +$val1 =~ s/UTF8/XXXX/; # execute the error handling in do_othername +ok(!run(app([@addext_args, "-addext", $val1]))); ok(!run(app([@addext_args, "-addext", $val, "-addext", $val]))); ok(!run(app([@addext_args, "-addext", $val, "-addext", $val2]))); ok(!run(app([@addext_args, "-addext", $val, "-addext", $val3]))); diff --git a/test/sslapitest.c b/test/sslapitest.c index 20e3594613667397f01bcae32c3598a3064e7288..0c62f62e01fa692b03e337479d0efcaa08df10ae 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -10322,6 +10322,27 @@ end: #endif /* OSSL_NO_USABLE_TLS1_3 */ #if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_DYNAMIC_ENGINE) + +static ENGINE *load_dasync(void) +{ + ENGINE *e; + + if (!TEST_ptr(e = ENGINE_by_id("dasync"))) + return NULL; + + if (!TEST_true(ENGINE_init(e))) { + ENGINE_free(e); + return NULL; + } + + if (!TEST_true(ENGINE_register_ciphers(e))) { + ENGINE_free(e); + return NULL; + } + + return e; +} + /* * Test TLSv1.2 with a pipeline capable cipher. TLSv1.3 and DTLS do not * support this yet. The only pipeline capable cipher that we have is in the @@ -10337,6 +10358,8 @@ end: * Test 4: Client has pipelining enabled, server does not: more data than all * the available pipelines can take * Test 5: Client has pipelining enabled, server does not: Maximum size pipeline + * Test 6: Repeat of test 0, but the engine is loaded late (after the SSL_CTX + * is created) */ static int test_pipelining(int idx) { @@ -10349,25 +10372,28 @@ static int test_pipelining(int idx) size_t written, readbytes, offset, msglen, fragsize = 10, numpipes = 5; size_t expectedreads; unsigned char *buf = NULL; - ENGINE *e; - - if (!TEST_ptr(e = ENGINE_by_id("dasync"))) - return 0; + ENGINE *e = NULL; - if (!TEST_true(ENGINE_init(e))) { - ENGINE_free(e); - return 0; + if (idx != 6) { + e = load_dasync(); + if (e == NULL) + return 0; } - if (!TEST_true(ENGINE_register_ciphers(e))) - goto end; - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), TLS_client_method(), 0, TLS1_2_VERSION, &sctx, &cctx, cert, privkey))) goto end; + if (idx == 6) { + e = load_dasync(); + if (e == NULL) + goto end; + /* Now act like test 0 */ + idx = 0; + } + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL))) goto end; @@ -10503,9 +10529,11 @@ end: SSL_free(clientssl); SSL_CTX_free(sctx); SSL_CTX_free(cctx); - ENGINE_unregister_ciphers(e); - ENGINE_finish(e); - ENGINE_free(e); + if (e != NULL) { + ENGINE_unregister_ciphers(e); + ENGINE_finish(e); + ENGINE_free(e); + } OPENSSL_free(buf); if (fragsize == SSL3_RT_MAX_PLAIN_LENGTH) OPENSSL_free(msg); @@ -10903,7 +10931,7 @@ int setup_tests(void) ADD_ALL_TESTS(test_serverinfo_custom, 4); #endif #if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_DYNAMIC_ENGINE) - ADD_ALL_TESTS(test_pipelining, 6); + ADD_ALL_TESTS(test_pipelining, 7); #endif ADD_ALL_TESTS(test_handshake_retry, 16); return 1;