diff --git a/.github/workflows/integrations.yml b/.github/workflows/integrations.yml index c514cbeeb5..66ad8a2347 100644 --- a/.github/workflows/integrations.yml +++ b/.github/workflows/integrations.yml @@ -257,3 +257,24 @@ jobs: - name: Run accp build run: | ./tests/ci/integration/run_accp_integration.sh + ruby-releases: + if: github.repository_owner == 'aws' + strategy: + fail-fast: false + matrix: + fips: + - "0" + - "1" + runs-on: ubuntu-latest + name: Ruby releases (FIPS=${{ matrix.fips}}) + steps: + - name: Install OS Dependencies + run: | + sudo apt-get update + sudo apt-get -y --no-install-recommends install cmake gcc ninja-build golang make autoconf ruby libyaml-dev + - uses: actions/checkout@v3 + - name: Build AWS-LC, build ruby, run tests + run: | + ./tests/ci/integration/run_ruby_integration.sh ruby_3_2 ruby_3_1 + env: + FIPS: ${{ matrix.fips }} diff --git a/tests/ci/common_posix_setup.sh b/tests/ci/common_posix_setup.sh index 82d6a3bf2a..c48120481a 100644 --- a/tests/ci/common_posix_setup.sh +++ b/tests/ci/common_posix_setup.sh @@ -166,7 +166,6 @@ function aws_lc_build() { ${CMAKE_COMMAND} ${AWS_LC_DIR} -GNinja "-B${BUILD_FOLDER}" "-DCMAKE_INSTALL_PREFIX=${INSTALL_FOLDER}" "${@:4}" ${CMAKE_COMMAND} --build ${BUILD_FOLDER} -- install ls -R ${INSTALL_FOLDER} - rm -rf "${BUILD_FOLDER:?}"/* } function print_executable_information { diff --git a/tests/ci/integration/ruby_patch/ruby_3_1/aws-lc-ruby-temp.patch b/tests/ci/integration/ruby_patch/ruby_3_1/aws-lc-ruby-temp.patch new file mode 100644 index 0000000000..63de2bf270 --- /dev/null +++ b/tests/ci/integration/ruby_patch/ruby_3_1/aws-lc-ruby-temp.patch @@ -0,0 +1,634 @@ +diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c +index 6c532ac..b4ca18b 100644 +--- a/ext/openssl/ossl.c ++++ b/ext/openssl/ossl.c +@@ -417,8 +417,7 @@ ossl_debug_set(VALUE self, VALUE val) + static VALUE + ossl_fips_mode_get(VALUE self) + { +- +-#ifdef OPENSSL_FIPS ++#if defined(OPENSSL_FIPS) || defined(OPENSSL_IS_AWSLC) + VALUE enabled; + enabled = FIPS_mode() ? Qtrue : Qfalse; + return enabled; +@@ -443,7 +442,7 @@ static VALUE + ossl_fips_mode_set(VALUE self, VALUE enabled) + { + +-#ifdef OPENSSL_FIPS ++#if defined(OPENSSL_FIPS) || defined(OPENSSL_IS_AWSLC) + if (RTEST(enabled)) { + int mode = FIPS_mode(); + if(!mode && !FIPS_mode_set(1)) /* turning on twice leads to an error */ +@@ -1200,6 +1199,8 @@ Init_openssl(void) + rb_define_const(mOSSL, "OPENSSL_FIPS", + #ifdef OPENSSL_FIPS + Qtrue ++#elif defined(OPENSSL_IS_AWSLC) // AWS-LC FIPS can only be enabled during compile time. ++ FIPS_mode() ? Qtrue : Qfalse + #else + Qfalse + #endif +diff --git a/ext/openssl/ossl_pkcs12.c b/ext/openssl/ossl_pkcs12.c +index fb947df..969aa25 100644 +--- a/ext/openssl/ossl_pkcs12.c ++++ b/ext/openssl/ossl_pkcs12.c +@@ -134,6 +134,12 @@ ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self) + if (!NIL_P(keytype)) + ktype = NUM2INT(keytype); + ++#if defined(OPENSSL_IS_AWSLC) ++ if (ktype != 0) { ++ ossl_raise(rb_eArgError, "Unknown key usage type with AWS-LC %"PRIsVALUE, INT2NUM(ktype)); ++ } ++#endif ++ + obj = NewPKCS12(cPKCS12); + x509s = NIL_P(ca) ? NULL : ossl_x509_ary2sk(ca); + p12 = PKCS12_create(passphrase, friendlyname, key, x509, x509s, +diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c +index 06d59c2..74f41db 100644 +--- a/ext/openssl/ossl_pkey_ec.c ++++ b/ext/openssl/ossl_pkey_ec.c +@@ -589,8 +589,11 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self) + ossl_clear_error(); /* ignore errors in d2i_ECPKParameters_bio() */ + if (nid == NID_undef) + ossl_raise(eEC_GROUP, "unknown curve name (%"PRIsVALUE")", arg1); +- ++#if !defined(OPENSSL_IS_AWSLC) + group = EC_GROUP_new_by_curve_name(nid); ++#else ++ group = EC_GROUP_new_by_curve_name_mutable(nid); ++#endif + if (group == NULL) + ossl_raise(eEC_GROUP, "unable to create curve (%"PRIsVALUE")", arg1); + +@@ -1295,7 +1298,7 @@ static VALUE ossl_ec_point_make_affine(VALUE self) + GetECPointGroup(self, group); + + rb_warn("OpenSSL::PKey::EC::Point#make_affine! is deprecated"); +-#if !OSSL_OPENSSL_PREREQ(3, 0, 0) ++#if !OSSL_OPENSSL_PREREQ(3, 0, 0) && !defined(OPENSSL_IS_AWSLC) + if (EC_POINT_make_affine(group, point, ossl_bn_ctx) != 1) + ossl_raise(cEC_POINT, "EC_POINT_make_affine"); + #endif +@@ -1444,7 +1447,7 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self) + if (EC_POINT_mul(group, point_result, bn_g, point_self, bn, ossl_bn_ctx) != 1) + ossl_raise(eEC_POINT, NULL); + } else { +-#if (defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3) || defined(LIBRESSL_VERSION_NUMBER) ++#if (defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3) || defined(LIBRESSL_VERSION_NUMBER) || defined(OPENSSL_IS_AWSLC) + rb_raise(rb_eNotImpError, "calling #mul with arrays is not" \ + "supported by this OpenSSL version"); + #else +diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c +index 9a0682a..c289055 100644 +--- a/ext/openssl/ossl_ssl.c ++++ b/ext/openssl/ossl_ssl.c +@@ -1139,7 +1139,7 @@ ossl_sslctx_set_security_level(VALUE self, VALUE value) + rb_check_frozen(self); + GetSSLCTX(self, ctx); + +-#if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL) ++#if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL) && !defined(OPENSSL_IS_AWSLC) + SSL_CTX_set_security_level(ctx, NUM2INT(value)); + #else + (void)ctx; +diff --git a/test/openssl/test_asn1.rb b/test/openssl/test_asn1.rb +index 7e5b969..4521e62 100644 +--- a/test/openssl/test_asn1.rb ++++ b/test/openssl/test_asn1.rb +@@ -456,7 +456,8 @@ def test_basic_asn1data + encode_decode_test B(%w{ 81 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 1, :CONTEXT_SPECIFIC) + encode_decode_test B(%w{ C1 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 1, :PRIVATE) + encode_decode_test B(%w{ 1F 20 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 32, :UNIVERSAL) +- encode_decode_test B(%w{ 1F C0 20 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 8224, :UNIVERSAL) ++ # AWS-LC does not support indefinite lengths with the UNIVERSAL tag. ++ encode_decode_test B(%w{ 1F C0 20 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 8224, :UNIVERSAL) if !aws_lc? + encode_decode_test B(%w{ 41 02 AB CD }), OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD }), 1, :APPLICATION) + encode_decode_test B(%w{ 41 81 80 } + %w{ AB CD } * 64), OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD } * 64), 1, :APPLICATION) + encode_decode_test B(%w{ 41 82 01 00 } + %w{ AB CD } * 128), OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD } * 128), 1, :APPLICATION) +diff --git a/test/openssl/test_bn.rb b/test/openssl/test_bn.rb +index 346602d..2552d95 100644 +--- a/test/openssl/test_bn.rb ++++ b/test/openssl/test_bn.rb +@@ -56,10 +56,11 @@ def test_to_str + assert_equal((-(2**107-1)).to_s, @e4.to_s(10)) + assert_equal("999", @e1.to_s) + +- assert_equal("03E7", @e1.to_s(16)) +- assert_equal("-03E7", @e2.to_s(16)) +- assert_equal("07FFFFFFFFFFFFFFFFFFFFFFFFFF", @e3.to_s(16)) +- assert_equal("-07FFFFFFFFFFFFFFFFFFFFFFFFFF", @e4.to_s(16)) ++ # AWS-LC prints hex in lower case. ++ assert_equal("03E7", @e1.to_s(16).upcase) ++ assert_equal("-03E7", @e2.to_s(16).upcase) ++ assert_equal("07FFFFFFFFFFFFFFFFFFFFFFFFFF", @e3.to_s(16).upcase) ++ assert_equal("-07FFFFFFFFFFFFFFFFFFFFFFFFFF", @e4.to_s(16).upcase) + + assert_equal("\x03\xe7", @e1.to_s(2)) + assert_equal("\x03\xe7", @e2.to_s(2)) +@@ -313,6 +314,8 @@ def test_argument_error + end + + def test_get_flags_and_set_flags ++ return if aws_lc? # AWS-LC does not support BN::CONSTTIME. ++ + e = OpenSSL::BN.new(999) + + assert_equal(0, e.get_flags(OpenSSL::BN::CONSTTIME)) +diff --git a/test/openssl/test_config.rb b/test/openssl/test_config.rb +index 24a215a..8f4eb39 100644 +--- a/test/openssl/test_config.rb ++++ b/test/openssl/test_config.rb +@@ -42,6 +42,9 @@ def test_s_parse + end + + def test_s_parse_format ++ # AWS-LC removed support for parsing $foo variables. ++ return if aws_lc? ++ + c = OpenSSL::Config.parse(<<__EOC__) + baz =qx\t # "baz = qx" + +@@ -216,12 +219,12 @@ def test_get_value + @it.get_value(nil, 'HOME') # not allowed unlike Config#value + end + # fallback to 'default' ugly... +- assert_equal('.', @it.get_value('unknown', 'HOME')) ++ assert_equal('.', @it.get_value('unknown', 'HOME')) if !aws_lc? # AWS-LC does not support the fallback + end + + def test_get_value_ENV +- # LibreSSL removed support for NCONF_get_string(conf, "ENV", str) +- return if libressl? ++ # LibreSSL and AWS-LC removed support for NCONF_get_string(conf, "ENV", str) ++ return if libressl? || aws_lc? + + key = ENV.keys.first + assert_not_nil(key) # make sure we have at least one ENV var. +diff --git a/test/openssl/test_fips.rb b/test/openssl/test_fips.rb +index 8cd474f..d811590 100644 +--- a/test/openssl/test_fips.rb ++++ b/test/openssl/test_fips.rb +@@ -5,12 +5,15 @@ + + class OpenSSL::TestFIPS < OpenSSL::TestCase + def test_fips_mode_is_reentrant ++ return if aws_lc? # AWS-LC's FIPS mode is decided at compile time. ++ + OpenSSL.fips_mode = false + OpenSSL.fips_mode = false + end + + def test_fips_mode_get +- return unless OpenSSL::OPENSSL_FIPS ++ return unless OpenSSL::OPENSSL_FIPS and !aws_lc? # AWS-LC's FIPS mode is decided at compile time. ++ + assert_separately([{ "OSSL_MDEBUG" => nil }, "-ropenssl"], <<~"end;") + require #{__FILE__.dump} + +diff --git a/test/openssl/test_pkcs12.rb b/test/openssl/test_pkcs12.rb +index ec67674..be21f47 100644 +--- a/test/openssl/test_pkcs12.rb ++++ b/test/openssl/test_pkcs12.rb +@@ -159,7 +159,6 @@ def test_create_with_mac_itr + DEFAULT_PBE_PKEYS, + DEFAULT_PBE_CERTS, + nil, +- nil, + 2048 + ) + +diff --git a/test/openssl/test_pkcs7.rb b/test/openssl/test_pkcs7.rb +index ba8b93d..7a23104 100644 +--- a/test/openssl/test_pkcs7.rb ++++ b/test/openssl/test_pkcs7.rb +@@ -191,6 +191,8 @@ def test_set_type_encrypted + end + + def test_smime ++ pend "AWS-LC has no current support for SMIME with PKCS7" if aws_lc? ++ + store = OpenSSL::X509::Store.new + store.add_cert(@ca_cert) + ca_certs = [@ca_cert] +@@ -315,12 +317,42 @@ def test_split_content + AwlEke0Uze1367QKgxM0nc3SZDlptY7zPIJC5saWXb8Rt2bw2JxEBOTavrp+ZwJ8 + tcH961onq8Tme2ICaCzk + -----END PKCS7----- ++END ++ # NOTE: below PEM differs very slightly from upstream ruby ++ # in that it encodes the inner EncryptedContent in ++ # definite-length DER OCTET_STRING whereas upstream (i.e. ++ # OpenSSL) encodes EncryptedContent as indefinite-length ++ # BER OCTET_STRING. The discrepancy is due to AWS-LC's lack ++ # of support for indefinite OCTET_STRINGS. ++ pki_message_content_pem_awslc = < ctx { + ctx.ssl_version = :TLSv1_2 + ctx.ciphers = "aNULL" +@@ -1000,7 +1002,7 @@ def test_connect_certificate_verify_failed_exception_message + ctx.set_params + # OpenSSL <= 1.1.0: "self signed certificate in certificate chain" + # OpenSSL >= 3.0.0: "self-signed certificate in certificate chain" +- assert_raise_with_message(OpenSSL::SSL::SSLError, /self.signed/) { ++ assert_raise_with_message(OpenSSL::SSL::SSLError, /self.signed|CERTIFICATE_VERIFY_FAILED/) { + server_connect(port, ctx) + } + } +@@ -1458,20 +1460,22 @@ def test_get_ephemeral_key + end + end + +- # DHE +- # TODO: How to test this with TLS 1.3? +- ctx_proc2 = proc { |ctx| +- ctx.ssl_version = :TLSv1_2 +- ctx.ciphers = "EDH" +- ctx.tmp_dh = Fixtures.pkey("dh-1") +- } +- start_server(ctx_proc: ctx_proc2) do |port| +- ctx = OpenSSL::SSL::SSLContext.new +- ctx.ssl_version = :TLSv1_2 +- ctx.ciphers = "EDH" +- server_connect(port, ctx) { |ssl| +- assert_instance_of OpenSSL::PKey::DH, ssl.tmp_key ++ if !aws_lc? ++ # DHE ++ # TODO: How to test this with TLS 1.3? ++ ctx_proc2 = proc { |ctx| ++ ctx.ssl_version = :TLSv1_2 ++ ctx.ciphers = "EDH" ++ ctx.tmp_dh = Fixtures.pkey("dh-1") + } ++ start_server(ctx_proc: ctx_proc2) do |port| ++ ctx = OpenSSL::SSL::SSLContext.new ++ ctx.ssl_version = :TLSv1_2 ++ ctx.ciphers = "EDH" ++ server_connect(port, ctx) { |ssl| ++ assert_instance_of OpenSSL::PKey::DH, ssl.tmp_key ++ } ++ end + end + + # ECDHE +@@ -1536,11 +1540,11 @@ def test_fallback_scsv + ctx2.max_version = OpenSSL::SSL::TLS1_1_VERSION + s2 = OpenSSL::SSL::SSLSocket.new(sock2, ctx2) + t = Thread.new { +- assert_raise_with_message(OpenSSL::SSL::SSLError, /inappropriate fallback/) { ++ assert_raise_with_message(OpenSSL::SSL::SSLError, /inappropriate fallback|INAPPROPRIATE_FALLBACK/) { + s2.connect + } + } +- assert_raise_with_message(OpenSSL::SSL::SSLError, /inappropriate fallback/) { ++ assert_raise_with_message(OpenSSL::SSL::SSLError, /inappropriate fallback|INAPPROPRIATE_FALLBACK/) { + s1.accept + } + t.join +@@ -1551,6 +1555,8 @@ def test_fallback_scsv + end + + def test_tmp_dh_callback ++ pend "AWS-LC does not support DHE ciphersuites" if aws_lc? ++ + dh = Fixtures.pkey("dh-1") + called = false + ctx_proc = -> ctx { +@@ -1570,6 +1576,8 @@ def test_tmp_dh_callback + end + + def test_connect_works_when_setting_dh_callback_to_nil ++ pend "AWS-LC does not support DHE ciphersuites" if aws_lc? ++ + ctx_proc = -> ctx { + ctx.max_version = :TLS1_2 + ctx.ciphers = "DH:!NULL" # use DH +@@ -1585,6 +1593,8 @@ def test_connect_works_when_setting_dh_callback_to_nil + end + + def test_tmp_dh ++ pend "AWS-LC does not support DHE ciphersuites" if aws_lc? ++ + dh = Fixtures.pkey("dh-1") + ctx_proc = -> ctx { + ctx.max_version = :TLS1_2 +diff --git a/test/openssl/test_ssl_session.rb b/test/openssl/test_ssl_session.rb +index b72b10d..0f376e2 100644 +--- a/test/openssl/test_ssl_session.rb ++++ b/test/openssl/test_ssl_session.rb +@@ -28,9 +28,10 @@ def test_session + end + end + ++ # PEM file updated to use TLS 1.2 with ECDHE-RSA-AES256-SHA. + DUMMY_SESSION = <<__EOS__ + -----BEGIN SSL SESSION PARAMETERS----- +-MIIDzQIBAQICAwEEAgA5BCAF219w9ZEV8dNA60cpEGOI34hJtIFbf3bkfzSgMyad ++MIIDzQIBAQICAwMEAsAUBCAF219w9ZEV8dNA60cpEGOI34hJtIFbf3bkfzSgMyad + MQQwyGLbkCxE4OiMLdKKem+pyh8V7ifoP7tCxhdmwoDlJxI1v6nVCjai+FGYuncy + NNSWoQYCBE4DDWuiAwIBCqOCAo4wggKKMIIBcqADAgECAgECMA0GCSqGSIb3DQEB + BQUAMD0xEzARBgoJkiaJk/IsZAEZFgNvcmcxGTAXBgoJkiaJk/IsZAEZFglydWJ5 +@@ -54,9 +55,10 @@ def test_session + -----END SSL SESSION PARAMETERS----- + __EOS__ + ++ # PEM file updated to use TLS 1.1 with ECDHE-RSA-AES256-SHA. + DUMMY_SESSION_NO_EXT = <<-__EOS__ + -----BEGIN SSL SESSION PARAMETERS----- +-MIIDCAIBAQICAwAEAgA5BCDyAW7rcpzMjDSosH+Tv6sukymeqgq3xQVVMez628A+ ++MIIDCAIBAQICAwIEAsAUBCDyAW7rcpzMjDSosH+Tv6sukymeqgq3xQVVMez628A+ + lAQw9TrKzrIqlHEh6ltuQaqv/Aq83AmaAlogYktZgXAjOGnhX7ifJDNLMuCfQq53 + hPAaoQYCBE4iDeeiBAICASyjggKOMIICijCCAXKgAwIBAgIBAjANBgkqhkiG9w0B + AQUFADA9MRMwEQYKCZImiZPyLGQBGRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVi +@@ -120,7 +122,8 @@ def test_resumption + ctx.options &= ~OpenSSL::SSL::OP_NO_TICKET + # Disable server-side session cache which is enabled by default + ctx.session_cache_mode = OpenSSL::SSL::SSLContext::SESSION_CACHE_OFF +- ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION if libressl?(3, 2, 0) ++ # Session tickets must be retrieved via ctx.session_new_cb in TLS 1.3 in AWS-LC. ++ ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION if libressl?(3, 2, 0) || aws_lc? + } + start_server(ctx_proc: ctx_proc) do |port| + sess1 = server_connect_with_session(port, nil, nil) { |ssl| +@@ -238,10 +241,12 @@ def test_ctx_client_session_cb + end + + server_connect_with_session(port, ctx, nil) { |ssl| +- assert_equal(1, ctx.session_cache_stats[:cache_num]) ++ # AWS-LC doesn't support internal session caching on the client, but ++ # the callback is still enabled as expected. ++ assert_equal(1, ctx.session_cache_stats[:cache_num]) if !aws_lc? + assert_equal(1, ctx.session_cache_stats[:connect_good]) + assert_equal([ssl, ssl.session], called[:new]) +- assert(ctx.session_remove(ssl.session)) ++ assert(ctx.session_remove(ssl.session)) if !aws_lc? + assert(!ctx.session_remove(ssl.session)) + if TEST_SESSION_REMOVE_CB + assert_equal([ctx, ssl.session], called[:remove]) +diff --git a/test/openssl/test_x509store.rb b/test/openssl/test_x509store.rb +index d6c0e70..dad4036 100644 +--- a/test/openssl/test_x509store.rb ++++ b/test/openssl/test_x509store.rb +@@ -331,7 +331,7 @@ def test_verify_with_crl + def test_add_cert_duplicate + # Up until OpenSSL 1.1.0, X509_STORE_add_{cert,crl}() returned an error + # if the given certificate is already in the X509_STORE +- return if openssl?(1, 1, 0) || libressl? ++ return if openssl?(1, 1, 0) || libressl? || aws_lc? + ca1 = OpenSSL::X509::Name.parse_rfc2253("CN=Root CA") + ca1_key = Fixtures.pkey("rsa-1") + ca1_cert = issue_cert(ca1, ca1_key, 1, [], nil, nil) +diff --git a/test/openssl/utils.rb b/test/openssl/utils.rb +index 4ebcb98..b958c48 100644 +--- a/test/openssl/utils.rb ++++ b/test/openssl/utils.rb +@@ -2,10 +2,6 @@ + begin + require "openssl" + +- # Disable FIPS mode for tests for installations +- # where FIPS mode would be enabled by default. +- # Has no effect on all other installations. +- OpenSSL.fips_mode=false + rescue LoadError + end + +@@ -132,7 +128,7 @@ def get_subject_key_id(cert, hex: true) + end + + def openssl?(major = nil, minor = nil, fix = nil, patch = 0) +- return false if OpenSSL::OPENSSL_VERSION.include?("LibreSSL") ++ return false if OpenSSL::OPENSSL_VERSION.include?("LibreSSL") || OpenSSL::OPENSSL_VERSION.include?("AWS-LC") + return true unless major + OpenSSL::OPENSSL_VERSION_NUMBER >= + major * 0x10000000 + minor * 0x100000 + fix * 0x1000 + patch * 0x10 +@@ -143,6 +139,12 @@ def libressl?(major = nil, minor = nil, fix = nil) + return false unless version + !major || (version.map(&:to_i) <=> [major, minor, fix]) >= 0 + end ++ ++ def aws_lc?(major = nil, minor = nil, fix = nil) ++ version = OpenSSL::OPENSSL_VERSION.scan(/AWS-LC (\d+)\.(\d+)\.(\d+).*/)[0] ++ return false unless version ++ !major || (version.map(&:to_i) <=> [major, minor, fix]) >= 0 ++ end + end + + class OpenSSL::TestCase < Test::Unit::TestCase diff --git a/tests/ci/integration/ruby_patch/ruby_3_2/aws-lc-ruby-temp.patch b/tests/ci/integration/ruby_patch/ruby_3_2/aws-lc-ruby-temp.patch new file mode 100644 index 0000000000..26f28199ee --- /dev/null +++ b/tests/ci/integration/ruby_patch/ruby_3_2/aws-lc-ruby-temp.patch @@ -0,0 +1,665 @@ +diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c +index 6c532ac..b4ca18b 100644 +--- a/ext/openssl/ossl.c ++++ b/ext/openssl/ossl.c +@@ -417,8 +417,7 @@ ossl_debug_set(VALUE self, VALUE val) + static VALUE + ossl_fips_mode_get(VALUE self) + { +- +-#ifdef OPENSSL_FIPS ++#if defined(OPENSSL_FIPS) || defined(OPENSSL_IS_AWSLC) + VALUE enabled; + enabled = FIPS_mode() ? Qtrue : Qfalse; + return enabled; +@@ -443,7 +442,7 @@ static VALUE + ossl_fips_mode_set(VALUE self, VALUE enabled) + { + +-#ifdef OPENSSL_FIPS ++#if defined(OPENSSL_FIPS) || defined(OPENSSL_IS_AWSLC) + if (RTEST(enabled)) { + int mode = FIPS_mode(); + if(!mode && !FIPS_mode_set(1)) /* turning on twice leads to an error */ +@@ -1200,6 +1199,8 @@ Init_openssl(void) + rb_define_const(mOSSL, "OPENSSL_FIPS", + #ifdef OPENSSL_FIPS + Qtrue ++#elif defined(OPENSSL_IS_AWSLC) // AWS-LC FIPS can only be enabled during compile time. ++ FIPS_mode() ? Qtrue : Qfalse + #else + Qfalse + #endif +diff --git a/ext/openssl/ossl_pkcs12.c b/ext/openssl/ossl_pkcs12.c +index fb947df..969aa25 100644 +--- a/ext/openssl/ossl_pkcs12.c ++++ b/ext/openssl/ossl_pkcs12.c +@@ -134,6 +134,12 @@ ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self) + if (!NIL_P(keytype)) + ktype = NUM2INT(keytype); + ++#if defined(OPENSSL_IS_AWSLC) ++ if (ktype != 0) { ++ ossl_raise(rb_eArgError, "Unknown key usage type with AWS-LC %"PRIsVALUE, INT2NUM(ktype)); ++ } ++#endif ++ + obj = NewPKCS12(cPKCS12); + x509s = NIL_P(ca) ? NULL : ossl_x509_ary2sk(ca); + p12 = PKCS12_create(passphrase, friendlyname, key, x509, x509s, +diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c +index 92842f9..ad59300 100644 +--- a/ext/openssl/ossl_pkey_ec.c ++++ b/ext/openssl/ossl_pkey_ec.c +@@ -601,8 +601,11 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self) + ossl_clear_error(); /* ignore errors in d2i_ECPKParameters_bio() */ + if (nid == NID_undef) + ossl_raise(eEC_GROUP, "unknown curve name (%"PRIsVALUE")", arg1); +- ++#if !defined(OPENSSL_IS_AWSLC) + group = EC_GROUP_new_by_curve_name(nid); ++#else ++ group = EC_GROUP_new_by_curve_name_mutable(nid); ++#endif + if (group == NULL) + ossl_raise(eEC_GROUP, "unable to create curve (%"PRIsVALUE")", arg1); + +@@ -1311,7 +1314,7 @@ static VALUE ossl_ec_point_make_affine(VALUE self) + GetECPointGroup(self, group); + + rb_warn("OpenSSL::PKey::EC::Point#make_affine! is deprecated"); +-#if !OSSL_OPENSSL_PREREQ(3, 0, 0) ++#if !OSSL_OPENSSL_PREREQ(3, 0, 0) && !defined(OPENSSL_IS_AWSLC) + if (EC_POINT_make_affine(group, point, ossl_bn_ctx) != 1) + ossl_raise(eEC_POINT, "EC_POINT_make_affine"); + #endif +@@ -1460,7 +1463,7 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self) + if (EC_POINT_mul(group, point_result, bn_g, point_self, bn, ossl_bn_ctx) != 1) + ossl_raise(eEC_POINT, NULL); + } else { +-#if (defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3) || defined(LIBRESSL_VERSION_NUMBER) ++#if (defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3) || defined(LIBRESSL_VERSION_NUMBER) || defined(OPENSSL_IS_AWSLC) + rb_raise(rb_eNotImpError, "calling #mul with arrays is not" \ + "supported by this OpenSSL version"); + #else +diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c +index f639926..b6b41d4 100644 +--- a/ext/openssl/ossl_ssl.c ++++ b/ext/openssl/ossl_ssl.c +@@ -1241,7 +1241,7 @@ ossl_sslctx_set_security_level(VALUE self, VALUE value) + rb_check_frozen(self); + GetSSLCTX(self, ctx); + +-#if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL) ++#if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL) && !defined(OPENSSL_IS_AWSLC) + SSL_CTX_set_security_level(ctx, NUM2INT(value)); + #else + (void)ctx; +diff --git a/test/openssl/test_asn1.rb b/test/openssl/test_asn1.rb +index 7b1722e..67bbee0 100644 +--- a/test/openssl/test_asn1.rb ++++ b/test/openssl/test_asn1.rb +@@ -451,7 +451,8 @@ def test_basic_asn1data + encode_decode_test B(%w{ 81 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 1, :CONTEXT_SPECIFIC) + encode_decode_test B(%w{ C1 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 1, :PRIVATE) + encode_decode_test B(%w{ 1F 20 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 32, :UNIVERSAL) +- encode_decode_test B(%w{ 1F C0 20 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 8224, :UNIVERSAL) ++ # AWS-LC does not support indefinite lengths with the UNIVERSAL tag. ++ encode_decode_test B(%w{ 1F C0 20 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 8224, :UNIVERSAL) if !aws_lc? + encode_decode_test B(%w{ 41 02 AB CD }), OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD }), 1, :APPLICATION) + encode_decode_test B(%w{ 41 81 80 } + %w{ AB CD } * 64), OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD } * 64), 1, :APPLICATION) + encode_decode_test B(%w{ 41 82 01 00 } + %w{ AB CD } * 128), OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD } * 128), 1, :APPLICATION) +diff --git a/test/openssl/test_bn.rb b/test/openssl/test_bn.rb +index 77af140..f0a6723 100644 +--- a/test/openssl/test_bn.rb ++++ b/test/openssl/test_bn.rb +@@ -56,10 +56,11 @@ def test_to_str + assert_equal((-(2**107-1)).to_s, @e4.to_s(10)) + assert_equal("999", @e1.to_s) + +- assert_equal("03E7", @e1.to_s(16)) +- assert_equal("-03E7", @e2.to_s(16)) +- assert_equal("07FFFFFFFFFFFFFFFFFFFFFFFFFF", @e3.to_s(16)) +- assert_equal("-07FFFFFFFFFFFFFFFFFFFFFFFFFF", @e4.to_s(16)) ++ # AWS-LC prints hex in lower case. ++ assert_equal("03E7", @e1.to_s(16).upcase) ++ assert_equal("-03E7", @e2.to_s(16).upcase) ++ assert_equal("07FFFFFFFFFFFFFFFFFFFFFFFFFF", @e3.to_s(16).upcase) ++ assert_equal("-07FFFFFFFFFFFFFFFFFFFFFFFFFF", @e4.to_s(16).upcase) + + assert_equal("\x03\xe7", @e1.to_s(2)) + assert_equal("\x03\xe7", @e2.to_s(2)) +@@ -319,6 +320,8 @@ def test_argument_error + end + + def test_get_flags_and_set_flags ++ return if aws_lc? # AWS-LC does not support BN::CONSTTIME. ++ + e = OpenSSL::BN.new(999) + + assert_equal(0, e.get_flags(OpenSSL::BN::CONSTTIME)) +diff --git a/test/openssl/test_config.rb b/test/openssl/test_config.rb +index 24a215a..8f4eb39 100644 +--- a/test/openssl/test_config.rb ++++ b/test/openssl/test_config.rb +@@ -42,6 +42,9 @@ def test_s_parse + end + + def test_s_parse_format ++ # AWS-LC removed support for parsing $foo variables. ++ return if aws_lc? ++ + c = OpenSSL::Config.parse(<<__EOC__) + baz =qx\t # "baz = qx" + +@@ -216,12 +219,12 @@ def test_get_value + @it.get_value(nil, 'HOME') # not allowed unlike Config#value + end + # fallback to 'default' ugly... +- assert_equal('.', @it.get_value('unknown', 'HOME')) ++ assert_equal('.', @it.get_value('unknown', 'HOME')) if !aws_lc? # AWS-LC does not support the fallback + end + + def test_get_value_ENV +- # LibreSSL removed support for NCONF_get_string(conf, "ENV", str) +- return if libressl? ++ # LibreSSL and AWS-LC removed support for NCONF_get_string(conf, "ENV", str) ++ return if libressl? || aws_lc? + + key = ENV.keys.first + assert_not_nil(key) # make sure we have at least one ENV var. +diff --git a/test/openssl/test_fips.rb b/test/openssl/test_fips.rb +index 8cd474f..d811590 100644 +--- a/test/openssl/test_fips.rb ++++ b/test/openssl/test_fips.rb +@@ -5,12 +5,15 @@ + + class OpenSSL::TestFIPS < OpenSSL::TestCase + def test_fips_mode_is_reentrant ++ return if aws_lc? # AWS-LC's FIPS mode is decided at compile time. ++ + OpenSSL.fips_mode = false + OpenSSL.fips_mode = false + end + + def test_fips_mode_get +- return unless OpenSSL::OPENSSL_FIPS ++ return unless OpenSSL::OPENSSL_FIPS and !aws_lc? # AWS-LC's FIPS mode is decided at compile time. ++ + assert_separately([{ "OSSL_MDEBUG" => nil }, "-ropenssl"], <<~"end;") + require #{__FILE__.dump} + +diff --git a/test/openssl/test_pkcs12.rb b/test/openssl/test_pkcs12.rb +index ec67674..be21f47 100644 +--- a/test/openssl/test_pkcs12.rb ++++ b/test/openssl/test_pkcs12.rb +@@ -159,7 +159,6 @@ def test_create_with_mac_itr + DEFAULT_PBE_PKEYS, + DEFAULT_PBE_CERTS, + nil, +- nil, + 2048 + ) + +diff --git a/test/openssl/test_pkcs7.rb b/test/openssl/test_pkcs7.rb +index ba8b93d..7a23104 100644 +--- a/test/openssl/test_pkcs7.rb ++++ b/test/openssl/test_pkcs7.rb +@@ -191,6 +191,8 @@ def test_set_type_encrypted + end + + def test_smime ++ pend "AWS-LC has no current support for SMIME with PKCS7" if aws_lc? ++ + store = OpenSSL::X509::Store.new + store.add_cert(@ca_cert) + ca_certs = [@ca_cert] +@@ -315,12 +317,42 @@ def test_split_content + AwlEke0Uze1367QKgxM0nc3SZDlptY7zPIJC5saWXb8Rt2bw2JxEBOTavrp+ZwJ8 + tcH961onq8Tme2ICaCzk + -----END PKCS7----- ++END ++ # NOTE: below PEM differs very slightly from upstream ruby ++ # in that it encodes the inner EncryptedContent in ++ # definite-length DER OCTET_STRING whereas upstream (i.e. ++ # OpenSSL) encodes EncryptedContent as indefinite-length ++ # BER OCTET_STRING. The discrepancy is due to AWS-LC's lack ++ # of support for indefinite OCTET_STRINGS. ++ pki_message_content_pem_awslc = < ctx { + ctx.ssl_version = :TLSv1_2 + ctx.ciphers = "aNULL" +@@ -1494,20 +1496,22 @@ def test_get_ephemeral_key + end + end + +- # DHE +- # TODO: How to test this with TLS 1.3? +- ctx_proc2 = proc { |ctx| +- ctx.ssl_version = :TLSv1_2 +- ctx.ciphers = "EDH" +- ctx.tmp_dh = Fixtures.pkey("dh-1") +- } +- start_server(ctx_proc: ctx_proc2) do |port| +- ctx = OpenSSL::SSL::SSLContext.new +- ctx.ssl_version = :TLSv1_2 +- ctx.ciphers = "EDH" +- server_connect(port, ctx) { |ssl| +- assert_instance_of OpenSSL::PKey::DH, ssl.tmp_key ++ if !aws_lc? ++ # DHE ++ # TODO: How to test this with TLS 1.3? ++ ctx_proc2 = proc { |ctx| ++ ctx.ssl_version = :TLSv1_2 ++ ctx.ciphers = "EDH" ++ ctx.tmp_dh = Fixtures.pkey("dh-1") + } ++ start_server(ctx_proc: ctx_proc2) do |port| ++ ctx = OpenSSL::SSL::SSLContext.new ++ ctx.ssl_version = :TLSv1_2 ++ ctx.ciphers = "EDH" ++ server_connect(port, ctx) { |ssl| ++ assert_instance_of OpenSSL::PKey::DH, ssl.tmp_key ++ } ++ end + end + + # ECDHE +@@ -1572,11 +1576,11 @@ def test_fallback_scsv + ctx2.max_version = OpenSSL::SSL::TLS1_1_VERSION + s2 = OpenSSL::SSL::SSLSocket.new(sock2, ctx2) + t = Thread.new { +- assert_raise_with_message(OpenSSL::SSL::SSLError, /inappropriate fallback/) { ++ assert_raise_with_message(OpenSSL::SSL::SSLError, /inappropriate fallback|INAPPROPRIATE_FALLBACK/) { + s2.connect + } + } +- assert_raise_with_message(OpenSSL::SSL::SSLError, /inappropriate fallback/) { ++ assert_raise_with_message(OpenSSL::SSL::SSLError, /inappropriate fallback|INAPPROPRIATE_FALLBACK/) { + s1.accept + } + t.join +@@ -1587,6 +1591,8 @@ def test_fallback_scsv + end + + def test_tmp_dh_callback ++ pend "AWS-LC does not support DHE ciphersuites" if aws_lc? ++ + dh = Fixtures.pkey("dh-1") + called = false + ctx_proc = -> ctx { +@@ -1654,7 +1660,7 @@ def test_ciphersuites_method_bogus_csuite + + assert_raise_with_message( + OpenSSL::SSL::SSLError, +- /SSL_CTX_set_ciphersuites: no cipher match/i ++ /SSL_CTX_set_ciphersuites: (no cipher match|NO_CIPHER_MATCH)/i + ) { ssl_ctx.ciphersuites = 'BOGUS' } + end + +@@ -1698,11 +1704,13 @@ def test_ciphers_method_bogus_csuite + + assert_raise_with_message( + OpenSSL::SSL::SSLError, +- /SSL_CTX_set_cipher_list: no cipher match/i ++ /SSL_CTX_set_cipher_list: (no cipher match|NO_CIPHER_MATCH)/i + ) { ssl_ctx.ciphers = 'BOGUS' } + end + + def test_connect_works_when_setting_dh_callback_to_nil ++ pend "AWS-LC does not support DHE ciphersuites" if aws_lc? ++ + ctx_proc = -> ctx { + ctx.max_version = :TLS1_2 + ctx.ciphers = "DH:!NULL" # use DH +@@ -1718,6 +1726,8 @@ def test_connect_works_when_setting_dh_callback_to_nil + end + + def test_tmp_dh ++ pend "AWS-LC does not support DHE ciphersuites" if aws_lc? ++ + dh = Fixtures.pkey("dh-1") + ctx_proc = -> ctx { + ctx.max_version = :TLS1_2 +diff --git a/test/openssl/test_ssl_session.rb b/test/openssl/test_ssl_session.rb +index b243201..ccc764a 100644 +--- a/test/openssl/test_ssl_session.rb ++++ b/test/openssl/test_ssl_session.rb +@@ -28,9 +28,10 @@ def test_session + end + end + ++ # PEM file updated to use TLS 1.2 with ECDHE-RSA-AES256-SHA. + DUMMY_SESSION = <<__EOS__ + -----BEGIN SSL SESSION PARAMETERS----- +-MIIDzQIBAQICAwEEAgA5BCAF219w9ZEV8dNA60cpEGOI34hJtIFbf3bkfzSgMyad ++MIIDzQIBAQICAwMEAsAUBCAF219w9ZEV8dNA60cpEGOI34hJtIFbf3bkfzSgMyad + MQQwyGLbkCxE4OiMLdKKem+pyh8V7ifoP7tCxhdmwoDlJxI1v6nVCjai+FGYuncy + NNSWoQYCBE4DDWuiAwIBCqOCAo4wggKKMIIBcqADAgECAgECMA0GCSqGSIb3DQEB + BQUAMD0xEzARBgoJkiaJk/IsZAEZFgNvcmcxGTAXBgoJkiaJk/IsZAEZFglydWJ5 +@@ -54,9 +55,10 @@ def test_session + -----END SSL SESSION PARAMETERS----- + __EOS__ + ++ # PEM file updated to use TLS 1.1 with ECDHE-RSA-AES256-SHA. + DUMMY_SESSION_NO_EXT = <<-__EOS__ + -----BEGIN SSL SESSION PARAMETERS----- +-MIIDCAIBAQICAwAEAgA5BCDyAW7rcpzMjDSosH+Tv6sukymeqgq3xQVVMez628A+ ++MIIDCAIBAQICAwIEAsAUBCDyAW7rcpzMjDSosH+Tv6sukymeqgq3xQVVMez628A+ + lAQw9TrKzrIqlHEh6ltuQaqv/Aq83AmaAlogYktZgXAjOGnhX7ifJDNLMuCfQq53 + hPAaoQYCBE4iDeeiBAICASyjggKOMIICijCCAXKgAwIBAgIBAjANBgkqhkiG9w0B + AQUFADA9MRMwEQYKCZImiZPyLGQBGRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVi +@@ -120,7 +122,8 @@ def test_resumption + ctx.options &= ~OpenSSL::SSL::OP_NO_TICKET + # Disable server-side session cache which is enabled by default + ctx.session_cache_mode = OpenSSL::SSL::SSLContext::SESSION_CACHE_OFF +- ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION if libressl?(3, 2, 0) ++ # Session tickets must be retrieved via ctx.session_new_cb in TLS 1.3 in AWS-LC. ++ ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION if libressl?(3, 2, 0) || aws_lc? + } + start_server(ctx_proc: ctx_proc) do |port| + sess1 = server_connect_with_session(port, nil, nil) { |ssl| +@@ -238,10 +241,12 @@ def test_ctx_client_session_cb + end + + server_connect_with_session(port, ctx, nil) { |ssl| +- assert_equal(1, ctx.session_cache_stats[:cache_num]) ++ # AWS-LC doesn't support internal session caching on the client, but ++ # the callback is still enabled as expected. ++ assert_equal(1, ctx.session_cache_stats[:cache_num]) if !aws_lc? + assert_equal(1, ctx.session_cache_stats[:connect_good]) + assert_equal([ssl, ssl.session], called[:new]) +- assert(ctx.session_remove(ssl.session)) ++ assert(ctx.session_remove(ssl.session)) if !aws_lc? + assert(!ctx.session_remove(ssl.session)) + if TEST_SESSION_REMOVE_CB + assert_equal([ctx, ssl.session], called[:remove]) +diff --git a/test/openssl/test_x509store.rb b/test/openssl/test_x509store.rb +index d6c0e70..dad4036 100644 +--- a/test/openssl/test_x509store.rb ++++ b/test/openssl/test_x509store.rb +@@ -331,7 +331,7 @@ def test_verify_with_crl + def test_add_cert_duplicate + # Up until OpenSSL 1.1.0, X509_STORE_add_{cert,crl}() returned an error + # if the given certificate is already in the X509_STORE +- return if openssl?(1, 1, 0) || libressl? ++ return if openssl?(1, 1, 0) || libressl? || aws_lc? + ca1 = OpenSSL::X509::Name.parse_rfc2253("CN=Root CA") + ca1_key = Fixtures.pkey("rsa-1") + ca1_cert = issue_cert(ca1, ca1_key, 1, [], nil, nil) +diff --git a/test/openssl/utils.rb b/test/openssl/utils.rb +index 4ebcb98..b958c48 100644 +--- a/test/openssl/utils.rb ++++ b/test/openssl/utils.rb +@@ -2,10 +2,6 @@ + begin + require "openssl" + +- # Disable FIPS mode for tests for installations +- # where FIPS mode would be enabled by default. +- # Has no effect on all other installations. +- OpenSSL.fips_mode=false + rescue LoadError + end + +@@ -132,7 +128,7 @@ def get_subject_key_id(cert, hex: true) + end + + def openssl?(major = nil, minor = nil, fix = nil, patch = 0) +- return false if OpenSSL::OPENSSL_VERSION.include?("LibreSSL") ++ return false if OpenSSL::OPENSSL_VERSION.include?("LibreSSL") || OpenSSL::OPENSSL_VERSION.include?("AWS-LC") + return true unless major + OpenSSL::OPENSSL_VERSION_NUMBER >= + major * 0x10000000 + minor * 0x100000 + fix * 0x1000 + patch * 0x10 +@@ -143,6 +139,12 @@ def libressl?(major = nil, minor = nil, fix = nil) + return false unless version + !major || (version.map(&:to_i) <=> [major, minor, fix]) >= 0 + end ++ ++ def aws_lc?(major = nil, minor = nil, fix = nil) ++ version = OpenSSL::OPENSSL_VERSION.scan(/AWS-LC (\d+)\.(\d+)\.(\d+).*/)[0] ++ return false unless version ++ !major || (version.map(&:to_i) <=> [major, minor, fix]) >= 0 ++ end + end + + class OpenSSL::TestCase < Test::Unit::TestCase diff --git a/tests/ci/integration/run_ruby_integration.sh b/tests/ci/integration/run_ruby_integration.sh new file mode 100755 index 0000000000..cd13116add --- /dev/null +++ b/tests/ci/integration/run_ruby_integration.sh @@ -0,0 +1,90 @@ +#!/bin/bash -exu +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 OR ISC + +source tests/ci/common_posix_setup.sh + +set -exuo pipefail + +# Set up environment. + +# Default env parameters to "off" +FIPS=${FIPS:-"0"} + +# SYS_ROOT +# - SRC_ROOT(aws-lc) +# - SCRATCH_FOLDER +# - RUBY_SRC_FOLDER +# - ruby_3_1 +# - RUBY_PATCH_FOLDER +# - ruby_3_1 +# - AWS_LC_BUILD_FOLDER +# - AWS_LC_INSTALL_FOLDER + +# Assumes script is executed from the root of aws-lc directory +SCRATCH_FOLDER="${SRC_ROOT}/RUBY_BUILD_ROOT" +RUBY_SRC_FOLDER="${SCRATCH_FOLDER}/ruby-src" +RUBY_PATCH_FOLDER="${SRC_ROOT}/tests/ci/integration/ruby_patch" +AWS_LC_BUILD_FOLDER="${SCRATCH_FOLDER}/aws-lc-build" +AWS_LC_INSTALL_FOLDER="${SCRATCH_FOLDER}/aws-lc-install" + +function ruby_build() { + local branch=${1} + pushd "${RUBY_SRC_FOLDER}/${branch}" + ./autogen.sh + mkdir -p install + ./configure --disable-install-doc \ + --prefix="$PWD/install" \ + --with-openssl-dir=${AWS_LC_INSTALL_FOLDER} + make V=1 -j ${NUM_CPU_THREADS} + make install + # Check that AWS-LC was used. + ./install/bin/ruby -e 'require "openssl"; puts OpenSSL::OPENSSL_VERSION' | grep -q "AWS-LC" && echo "AWS-LC found!" || exit 1 + ./miniruby ./tool/runruby.rb -e 'require "openssl"; puts OpenSSL::OPENSSL_VERSION' | grep -q "AWS-LC" && echo "AWS-LC found!" || exit 1 + + ldd "$(find "$PWD/install" -name "openssl.so")" | grep "${AWS_LC_INSTALL_FOLDER}/lib/libcrypto.so" || exit 1 + ldd "$(find "$PWD/install" -name "openssl.so")" | grep "${AWS_LC_INSTALL_FOLDER}/lib/libssl.so" || exit 1 + + #TODO: add more relevant tests here + make test-all TESTS="test/openssl/*.rb" + + popd +} + +function ruby_patch() { + local branch=${1} + local src_dir="${RUBY_SRC_FOLDER}/${branch}" + local patch_dir="${RUBY_PATCH_FOLDER}/${branch}" + if [[ ! $(find -L ${patch_dir} -type f -name '*.patch') ]]; then + echo "No patch for ${branch}!" + exit 1 + fi + git clone https://github.com/ruby/ruby.git ${src_dir} \ + --depth 1 \ + --branch ${branch} + for patchfile in $(find -L ${patch_dir} -type f -name '*.patch'); do + echo "Apply patch ${patchfile}..." + cat ${patchfile} | patch -p1 --quiet -d ${src_dir} + done +} + +if [[ "$#" -eq "0" ]]; then + echo "No ruby branches provided for testing" + exit 1 +fi + +mkdir -p ${SCRATCH_FOLDER} +rm -rf ${SCRATCH_FOLDER}/* +cd ${SCRATCH_FOLDER} + +mkdir -p ${AWS_LC_BUILD_FOLDER} ${AWS_LC_INSTALL_FOLDER} +aws_lc_build ${SRC_ROOT} ${AWS_LC_BUILD_FOLDER} ${AWS_LC_INSTALL_FOLDER} -DBUILD_TESTING=OFF -DFIPS=${FIPS} -DBUILD_SHARED_LIBS=1 + +mkdir -p ${RUBY_SRC_FOLDER} + +# NOTE: As we add more versions to support, we may want to parallelize here +for branch in "$@"; do + ruby_patch ${branch} + ruby_build ${branch} +done +