diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 985a626b3..6d19e992d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,7 @@ jobs: fail-fast: false matrix: os: [ ubuntu-latest, macos-latest ] - ruby: [ head, 2.7, 2.6, 2.5, 2.4, 2.3 ] + ruby: [ head, "3.0", "2.7", "2.6", "2.5", "2.4", "2.3" ] steps: - name: repo checkout uses: actions/checkout@v2 @@ -38,7 +38,7 @@ jobs: fail-fast: false matrix: os: [ windows-latest ] - ruby: [ mswin, mingw, 2.7, 2.6, 2.5, 2.4, 2.3 ] + ruby: [ mswin, mingw, "3.0", "2.7", "2.6", "2.5", "2.4", "2.3" ] steps: - name: repo checkout uses: actions/checkout@v2 @@ -52,10 +52,11 @@ jobs: - name: depends run: rake install_dependencies + # pkg-config is disabled because it can pick up the different OpenSSL installation # SSL_DIR is set as needed by MSP-Greg/setup-ruby-pkgs # only used with mswin - name: compile - run: rake compile -- --enable-debug $env:SSL_DIR + run: rake compile -- --enable-debug --without-pkg-config $env:SSL_DIR - name: test run: rake test TESTOPTS="-v --no-show-detail-immediately" OSSL_MDEBUG=1 @@ -68,21 +69,15 @@ jobs: fail-fast: false matrix: os: [ ubuntu-latest ] - ruby: [ 2.7 ] + ruby: [ "3.0" ] openssl: - openssl-1.0.1u # EOL - openssl-1.0.2u # EOL - openssl-1.1.0l # EOL - - openssl-1.1.1g - # - libressl-2.3.7 # EOL - # - libressl-2.4.5 # EOL - # - libressl-2.5.5 # EOL - # - libressl-2.6.5 # EOL - # - libressl-2.7.5 # EOL - # - libressl-2.8.3 # EOL + - openssl-1.1.1j - libressl-2.9.2 # EOL - - libressl-3.0.2 - - libressl-3.1.1 + - libressl-3.1.5 + - libressl-3.2.0 steps: - name: repo checkout uses: actions/checkout@v2 diff --git a/ext/openssl/ossl_bn.c b/ext/openssl/ossl_bn.c index d94b8e375..bec37299f 100644 --- a/ext/openssl/ossl_bn.c +++ b/ext/openssl/ossl_bn.c @@ -453,7 +453,7 @@ ossl_bn_is_negative(VALUE self) if (!(result = BN_new())) { \ ossl_raise(eBNError, NULL); \ } \ - if (!BN_##func(result, bn, ossl_bn_ctx)) { \ + if (BN_##func(result, bn, ossl_bn_ctx) <= 0) { \ BN_free(result); \ ossl_raise(eBNError, NULL); \ } \ @@ -479,7 +479,7 @@ BIGNUM_1c(sqr) if (!(result = BN_new())) { \ ossl_raise(eBNError, NULL); \ } \ - if (!BN_##func(result, bn1, bn2)) { \ + if (BN_##func(result, bn1, bn2) <= 0) { \ BN_free(result); \ ossl_raise(eBNError, NULL); \ } \ @@ -512,7 +512,7 @@ BIGNUM_2(sub) if (!(result = BN_new())) { \ ossl_raise(eBNError, NULL); \ } \ - if (!BN_##func(result, bn1, bn2, ossl_bn_ctx)) { \ + if (BN_##func(result, bn1, bn2, ossl_bn_ctx) <= 0) { \ BN_free(result); \ ossl_raise(eBNError, NULL); \ } \ @@ -556,11 +556,21 @@ BIGNUM_2c(gcd) BIGNUM_2c(mod_sqr) /* - * Document-method: OpenSSL::BN#mod_inverse * call-seq: - * bn.mod_inverse(bn2) => aBN + * bn.mod_inverse(bn2) => aBN */ -BIGNUM_2c(mod_inverse) +static VALUE +ossl_bn_mod_inverse(VALUE self, VALUE other) +{ + BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; + VALUE obj; + GetBN(self, bn1); + obj = NewBN(rb_obj_class(self)); + if (!(result = BN_mod_inverse(NULL, bn1, bn2, ossl_bn_ctx))) + ossl_raise(eBNError, "BN_mod_inverse"); + SetBN(obj, result); + return obj; +} /* * call-seq: @@ -609,7 +619,7 @@ ossl_bn_div(VALUE self, VALUE other) if (!(result = BN_new())) { \ ossl_raise(eBNError, NULL); \ } \ - if (!BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx)) { \ + if (BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx) <= 0) { \ BN_free(result); \ ossl_raise(eBNError, NULL); \ } \ @@ -651,7 +661,7 @@ BIGNUM_3c(mod_exp) { \ BIGNUM *bn; \ GetBN(self, bn); \ - if (!BN_##func(bn, NUM2INT(bit))) { \ + if (BN_##func(bn, NUM2INT(bit)) <= 0) { \ ossl_raise(eBNError, NULL); \ } \ return self; \ @@ -711,7 +721,7 @@ ossl_bn_is_bit_set(VALUE self, VALUE bit) if (!(result = BN_new())) { \ ossl_raise(eBNError, NULL); \ } \ - if (!BN_##func(result, bn, b)) { \ + if (BN_##func(result, bn, b) <= 0) { \ BN_free(result); \ ossl_raise(eBNError, NULL); \ } \ @@ -741,7 +751,7 @@ BIGNUM_SHIFT(rshift) int b; \ b = NUM2INT(bits); \ GetBN(self, bn); \ - if (!BN_##func(bn, bn, b)) \ + if (BN_##func(bn, bn, b) <= 0) \ ossl_raise(eBNError, NULL); \ return self; \ } @@ -780,7 +790,7 @@ BIGNUM_SELF_SHIFT(rshift) if (!(result = BN_new())) { \ ossl_raise(eBNError, NULL); \ } \ - if (!BN_##func(result, b, top, bottom)) { \ + if (BN_##func(result, b, top, bottom) <= 0) { \ BN_free(result); \ ossl_raise(eBNError, NULL); \ } \ @@ -809,7 +819,7 @@ BIGNUM_RAND(pseudo_rand) if (!(result = BN_new())) { \ ossl_raise(eBNError, NULL); \ } \ - if (!BN_##func##_range(result, bn)) { \ + if (BN_##func##_range(result, bn) <= 0) { \ BN_free(result); \ ossl_raise(eBNError, NULL); \ } \ diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index f4cc6dec7..c38142bfc 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -1647,6 +1647,11 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts) rb_io_wait_readable(fptr->fd); continue; case SSL_ERROR_SYSCALL: +#ifdef __APPLE__ + /* See ossl_ssl_write_internal() */ + if (errno == EPROTOTYPE) + continue; +#endif if (errno) rb_sys_fail(funcname); ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl)); #if defined(SSL_R_CERTIFICATE_VERIFY_FAILED) @@ -1938,6 +1943,16 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts) rb_io_wait_readable(fptr->fd); continue; case SSL_ERROR_SYSCALL: +#ifdef __APPLE__ + /* + * It appears that send syscall can return EPROTOTYPE if the + * socket is being torn down. Retry to get a proper errno to + * make the error handling in line with the socket library. + * [Bug #14713] https://bugs.ruby-lang.org/issues/14713 + */ + if (errno == EPROTOTYPE) + continue; +#endif if (errno) rb_sys_fail(0); default: ossl_raise(eSSLError, "SSL_write"); diff --git a/ext/openssl/ossl_x509store.c b/ext/openssl/ossl_x509store.c index 1eaaf4b3d..5e0ab8d85 100644 --- a/ext/openssl/ossl_x509store.c +++ b/ext/openssl/ossl_x509store.c @@ -546,7 +546,7 @@ static VALUE ossl_x509stctx_set_time(VALUE, VALUE); /* * call-seq: - * StoreContext.new(store, cert = nil, chain = nil) + * StoreContext.new(store, cert = nil, untrusted = nil) * * Sets up a StoreContext for a verification of the X.509 certificate _cert_. */ @@ -558,15 +558,24 @@ ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self) X509_STORE *x509st; X509 *x509 = NULL; STACK_OF(X509) *x509s = NULL; + int state; rb_scan_args(argc, argv, "12", &store, &cert, &chain); GetX509StCtx(self, ctx); GetX509Store(store, x509st); - if(!NIL_P(cert)) x509 = DupX509CertPtr(cert); /* NEED TO DUP */ - if(!NIL_P(chain)) x509s = ossl_x509_ary2sk(chain); - if(X509_STORE_CTX_init(ctx, x509st, x509, x509s) != 1){ + if (!NIL_P(cert)) + x509 = DupX509CertPtr(cert); /* NEED TO DUP */ + if (!NIL_P(chain)) { + x509s = ossl_protect_x509_ary2sk(chain, &state); + if (state) { + X509_free(x509); + rb_jump_tag(state); + } + } + if (X509_STORE_CTX_init(ctx, x509st, x509, x509s) != 1){ + X509_free(x509); sk_X509_pop_free(x509s, X509_free); - ossl_raise(eX509StoreError, NULL); + ossl_raise(eX509StoreError, "X509_STORE_CTX_init"); } if (!NIL_P(t = rb_iv_get(store, "@time"))) ossl_x509stctx_set_time(self, t);