Full Code of ruby/openssl for AI

master 8a7c9b8f2869 cached
139 files
1.3 MB
424.5k tokens
1858 symbols
1 requests
Download .txt
Showing preview only (1,412K chars total). Download the full file or copy to clipboard to get everything.
Repository: ruby/openssl
Branch: master
Commit: 8a7c9b8f2869
Files: 139
Total size: 1.3 MB

Directory structure:
gitextract_bnbciiwa/

├── .git-blame-ignore-revs
├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       ├── github-pages.yml
│       ├── push_gem.yml
│       ├── sync-ruby.yml
│       └── test.yml
├── .gitignore
├── BSDL
├── CONTRIBUTING.md
├── COPYING
├── Gemfile
├── History.md
├── README.md
├── Rakefile
├── ext/
│   └── openssl/
│       ├── extconf.rb
│       ├── openssl_missing.h
│       ├── ossl.c
│       ├── ossl.h
│       ├── ossl_asn1.c
│       ├── ossl_asn1.h
│       ├── ossl_bio.c
│       ├── ossl_bio.h
│       ├── ossl_bn.c
│       ├── ossl_bn.h
│       ├── ossl_cipher.c
│       ├── ossl_cipher.h
│       ├── ossl_config.c
│       ├── ossl_config.h
│       ├── ossl_digest.c
│       ├── ossl_digest.h
│       ├── ossl_engine.c
│       ├── ossl_engine.h
│       ├── ossl_hmac.c
│       ├── ossl_hmac.h
│       ├── ossl_kdf.c
│       ├── ossl_kdf.h
│       ├── ossl_ns_spki.c
│       ├── ossl_ns_spki.h
│       ├── ossl_ocsp.c
│       ├── ossl_ocsp.h
│       ├── ossl_pkcs12.c
│       ├── ossl_pkcs12.h
│       ├── ossl_pkcs7.c
│       ├── ossl_pkcs7.h
│       ├── ossl_pkey.c
│       ├── ossl_pkey.h
│       ├── ossl_pkey_dh.c
│       ├── ossl_pkey_dsa.c
│       ├── ossl_pkey_ec.c
│       ├── ossl_pkey_rsa.c
│       ├── ossl_provider.c
│       ├── ossl_provider.h
│       ├── ossl_rand.c
│       ├── ossl_rand.h
│       ├── ossl_ssl.c
│       ├── ossl_ssl.h
│       ├── ossl_ssl_session.c
│       ├── ossl_ts.c
│       ├── ossl_ts.h
│       ├── ossl_x509.c
│       ├── ossl_x509.h
│       ├── ossl_x509attr.c
│       ├── ossl_x509cert.c
│       ├── ossl_x509crl.c
│       ├── ossl_x509ext.c
│       ├── ossl_x509name.c
│       ├── ossl_x509req.c
│       ├── ossl_x509revoked.c
│       └── ossl_x509store.c
├── lib/
│   ├── openssl/
│   │   ├── bn.rb
│   │   ├── buffering.rb
│   │   ├── cipher.rb
│   │   ├── digest.rb
│   │   ├── hmac.rb
│   │   ├── marshal.rb
│   │   ├── pkcs5.rb
│   │   ├── pkey.rb
│   │   ├── ssl.rb
│   │   ├── version.rb
│   │   └── x509.rb
│   └── openssl.rb
├── openssl.gemspec
├── sample/
│   ├── c_rehash.rb
│   ├── cert2text.rb
│   ├── certstore.rb
│   ├── cipher.rb
│   ├── crlstore.rb
│   ├── echo_cli.rb
│   ├── echo_svr.rb
│   ├── gen_csr.rb
│   ├── smime_read.rb
│   ├── smime_write.rb
│   └── wget.rb
├── test/
│   └── openssl/
│       ├── fixtures/
│       │   └── pkey/
│       │       ├── dh-1.pem
│       │       ├── dh2048_ffdhe2048.pem
│       │       ├── dsa2048.pem
│       │       ├── mldsa65-1.pem
│       │       ├── mldsa65-2.pem
│       │       ├── p256.pem
│       │       ├── rsa-1.pem
│       │       ├── rsa-2.pem
│       │       ├── rsa-3.pem
│       │       └── rsa2048.pem
│       ├── test_asn1.rb
│       ├── test_bn.rb
│       ├── test_buffering.rb
│       ├── test_cipher.rb
│       ├── test_config.rb
│       ├── test_digest.rb
│       ├── test_engine.rb
│       ├── test_fips.rb
│       ├── test_hmac.rb
│       ├── test_kdf.rb
│       ├── test_ns_spki.rb
│       ├── test_ocsp.rb
│       ├── test_ossl.rb
│       ├── test_pair.rb
│       ├── test_pkcs12.rb
│       ├── test_pkcs7.rb
│       ├── test_pkey.rb
│       ├── test_pkey_dh.rb
│       ├── test_pkey_dsa.rb
│       ├── test_pkey_ec.rb
│       ├── test_pkey_rsa.rb
│       ├── test_provider.rb
│       ├── test_random.rb
│       ├── test_ssl.rb
│       ├── test_ssl_session.rb
│       ├── test_ts.rb
│       ├── test_x509attr.rb
│       ├── test_x509cert.rb
│       ├── test_x509crl.rb
│       ├── test_x509ext.rb
│       ├── test_x509name.rb
│       ├── test_x509req.rb
│       ├── test_x509store.rb
│       ├── ut_eof.rb
│       └── utils.rb
└── tool/
    └── openssl_fips.cnf.tmpl

================================================
FILE CONTENTS
================================================

================================================
FILE: .git-blame-ignore-revs
================================================
# This is a file used by GitHub to ignore the following commits on `git blame`.
#
# You can also do the same thing in your local repository with:
# $ git config --local blame.ignoreRevsFile .git-blame-ignore-revs

# Expand tabs in C source files
4d6214f50758ea1738bc45e25776ba852321f513


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  - package-ecosystem: 'github-actions'
    directory: '/'
    schedule:
      interval: 'weekly'


================================================
FILE: .github/workflows/github-pages.yml
================================================
name: GitHub Pages

on:
  push:
    branches:
      - master
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: ruby
          bundler-cache: true # 'bundle install' and cache gems
      - run: bundle exec rake rdoc
      - name: Upload GitHub Pages artifact
        uses: actions/upload-pages-artifact@v5
        with:
          path: html

  deploy:
    needs: build
    permissions:
      pages: write
      id-token: write
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v5


================================================
FILE: .github/workflows/push_gem.yml
================================================
name: Publish gem to rubygems.org

on:
  push:
    tags:
      - 'v*'

permissions:
  contents: read

jobs:
  push:
    if: github.repository == 'ruby/openssl'
    runs-on: ubuntu-latest

    environment:
      name: rubygems.org
      url: https://rubygems.org/gems/openssl

    permissions:
      contents: write
      id-token: write

    strategy:
      matrix:
        ruby: [ 'ruby', 'jruby' ]

    steps:
      - name: Harden Runner
        uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0
        with:
          egress-policy: audit

      - uses: actions/checkout@v6

      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          bundler-cache: true
          ruby-version: ${{ matrix.ruby }}

      - name: Publish to RubyGems
        uses: rubygems/release-gem@v1

      - name: Create GitHub release
        run: |
          tag_name="$(git describe --tags --abbrev=0)"
          gh release create "${tag_name}" --verify-tag --draft --generate-notes pkg/*.gem
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        if: matrix.ruby == 'ruby'


================================================
FILE: .github/workflows/sync-ruby.yml
================================================
name: Sync ruby
on:
  push:
    branches: [master]
jobs:
  sync:
    name: Sync ruby
    runs-on: ubuntu-latest
    if: ${{ github.repository_owner == 'ruby' }}
    steps:
      - uses: actions/checkout@v6

      - name: Create GitHub App token
        id: app-token
        uses: actions/create-github-app-token@v3
        with:
          app-id: 2060836
          private-key: ${{ secrets.RUBY_SYNC_DEFAULT_GEMS_PRIVATE_KEY }}
          owner: ruby
          repositories: ruby

      - name: Sync to ruby/ruby
        uses: convictional/trigger-workflow-and-wait@v1.6.5
        with:
          owner: ruby
          repo: ruby
          workflow_file_name: sync_default_gems.yml
          github_token: ${{ steps.app-token.outputs.token }}
          ref: master
          client_payload: |
            {"gem":"${{ github.event.repository.name }}","before":"${{ github.event.before }}","after":"${{ github.event.after }}"}
          propagate_failure: true
          wait_interval: 10


================================================
FILE: .github/workflows/test.yml
================================================
name: CI

on: [push, pull_request, workflow_dispatch]

jobs:
  ruby-versions:
    uses: ruby/actions/.github/workflows/ruby_versions.yml@master
    with:
      engine: cruby-truffleruby
      min_version: 2.7

  test:
    needs: ruby-versions
    name: >-
      ${{ matrix.os }} ${{ matrix.ruby }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ ubuntu-latest, macos-latest, windows-latest ]
        ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }}
        exclude:
          - { os: windows-latest, ruby: truffleruby }
          - { os: windows-latest, ruby: truffleruby-head }
        include:
          - { os: windows-latest, ruby: ucrt }
          - { os: windows-latest, ruby: mswin }

    steps: &test-steps
      - name: repo checkout
        uses: actions/checkout@v6

      - name: load ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: ${{ matrix.ruby }}
          bundler-cache: true # `bundle install` and cache
        if: ${{ !endsWith(matrix.os, 'ppc64le') && !endsWith(matrix.os, 's390x') }}

      - name: load ruby from deb package
        run: |
          sudo apt update
          sudo apt install ruby-full bundler
          sudo bundle install --jobs $(nproc)
        if: ${{ endsWith(matrix.os, 'ppc64le') || endsWith(matrix.os, 's390x') }}

      # See https://github.com/oneclick/rubyinstaller2/issues/60
      # The builtin DLLs are preferred over the mingw-w64/vcpkg DLLs. This is a
      # temporary workaround until they update the DLLs to OpenSSL 3.5.x.
      - name: Update RI2/mswin builtin DLLs
        run: |
          $dst = "$((Get-Item (Get-Command ruby).Definition).DirectoryName)\ruby_builtin_dlls"
          if ("${{ matrix.ruby }}" -eq "mswin") {
            $src = "C:\vcpkg\installed\x64-windows\bin"
          } else {
            $src = "$((Get-Item (Get-Command ruby).Definition).DirectoryName)\..\msys64\ucrt64\bin"
          }
          Copy-Item "$src\libcrypto-3-x64.dll", "$src\libssl-3-x64.dll" $dst
        if: ${{ matrix.os == 'windows-latest' && (matrix.ruby == '3.2' || matrix.ruby == '3.3' || matrix.ruby == 'mswin') }}

      # Enable the verbose option in mkmf.rb to print the compiling commands.
      - name: enable mkmf verbose
        run:  echo "MAKEFLAGS=V=1" >> $GITHUB_ENV
        if: runner.os == 'Linux' || runner.os == 'macOS'

      - name: set flags to check compiler warnings
        run:  echo "RUBY_OPENSSL_EXTCFLAGS=-Werror" >> $GITHUB_ENV
        if: ${{ !matrix.skip-warnings }}

      - name: rake compile
        run:  bundle exec rake debug_compiler compile

      - name: rake debug
        run:  bundle exec rake debug

      - name: rake test
        run:  bundle exec rake test TESTOPTS="-v --no-show-detail-immediately" OSSL_TEST_ALL=1
        timeout-minutes: 5

  test-ibm:
    if: github.repository == 'ruby/openssl'
    name: ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-24.04-ppc64le
          - os: ubuntu-24.04-s390x

    steps: *test-steps

  test-openssls:
    name: >-
      ${{ matrix.openssl }} ${{ matrix.name-extra }}
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        name-extra: [ '' ]
        openssl:
          # https://openssl-library.org/source/
          - openssl-1.1.1w # EOL 2023-09-11, still used by RHEL 8 and Ubuntu 20.04
          - openssl-3.0.20 # Supported until 2026-09-07 (LTS)
          - openssl-3.1.8 # EOL 2025-03-14
          - openssl-3.2.6 # EOL 2025-11-23
          - openssl-3.3.7 # EOL 2026-04-09
          - openssl-3.4.5 # Supported until 2026-10-22
          - openssl-3.5.6 # Supported until 2030-04-08 (LTS)
          - openssl-3.6.2 # Supported until 2026-11-01
          - openssl-4.0.0 # Supported until 2027-05-14
          - openssl-master
          # http://www.libressl.org/releases.html
          - libressl-3.9.2 # EOL 2025-04-05
          - libressl-4.0.1 # EOL 2025-10-08
          - libressl-4.1.2 # Supported until 2026-04-28
          - libressl-4.2.1 # Supported until 2026-10-22
          # https://github.com/aws/aws-lc/tags
          - aws-lc-latest
        include:
          - { name-extra: 'without legacy provider', openssl: openssl-4.0.0, append-configure: 'no-legacy' }
          - { openssl: aws-lc-latest, skip-warnings: true }
    steps:
      - name: repo checkout
        uses: actions/checkout@v6

      - id: cache-openssl
        uses: actions/cache@v5
        with:
          path: ~/openssl
          key: openssl-${{ runner.os }}-${{ matrix.openssl }}-${{ matrix.append-configure || 'default' }}
        if: matrix.openssl != 'openssl-master' && matrix.openssl != 'libressl-master' && matrix.openssl != 'aws-lc-latest'

      - name: Compile OpenSSL library
        if: steps.cache-openssl.outputs.cache-hit != 'true'
        run: |
          # Enable Bash debugging option temporarily for debugging use.
          set -x
          mkdir -p tmp/build-openssl && cd tmp/build-openssl
          case ${{ matrix.openssl }} in
          openssl-1.*)
            OPENSSL_COMMIT=$(echo ${{ matrix.openssl }} | sed -e 's/^openssl-/OpenSSL_/' | sed -e 's/\./_/g')
            git clone -b $OPENSSL_COMMIT --depth 1 https://github.com/openssl/openssl.git .
            echo "Git commit: $(git rev-parse HEAD)"
            # shared is required for 1.0.x.
            ./Configure --prefix=$HOME/openssl --libdir=lib shared linux-x86_64
            make depend && make -j4 && make install_sw
            ;;
          openssl-*)
            OPENSSL_COMMIT=${{ matrix.openssl == 'openssl-master' && 'master' || matrix.openssl }}
            git clone -b $OPENSSL_COMMIT --depth 1 https://github.com/openssl/openssl.git .
            echo "Git commit: $(git rev-parse HEAD)"
            ./Configure --prefix=$HOME/openssl --libdir=lib enable-fips no-tests ${{ matrix.append-configure }}
            make -j4 && make install_sw && make install_fips
            ;;
          libressl-*)
            curl -L https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/${{ matrix.openssl }}.tar.gz | \
              tar xzf - --strip-components=1
            ./configure --prefix=$HOME/openssl
            make -j4 && make install
            ;;
          aws-lc-*)
            git clone https://github.com/aws/aws-lc.git .
            AWS_LC_RELEASE=$(git tag --sort=-creatordate --list "v*"  | head -1)
            git checkout $AWS_LC_RELEASE
            cmake -DCMAKE_INSTALL_PREFIX=$HOME/openssl -DCMAKE_INSTALL_LIBDIR=lib
            make -j4 && make install
            ;;
          *)
            false
            ;;
          esac

      - name: load ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.0'
          bundler-cache: true

      - name: enable mkmf verbose
        run:  echo "MAKEFLAGS=V=1" >> $GITHUB_ENV

      - name: set flags to check compiler warnings
        run:  echo "RUBY_OPENSSL_EXTCFLAGS=-Werror" >> $GITHUB_ENV
        if: ${{ !matrix.skip-warnings }}

      - name: rake compile
        run:  bundle exec rake debug_compiler compile -- --with-openssl-dir=$HOME/openssl

      - name: rake debug
        run:  bundle exec rake debug

      - name: rake test
        run:  bundle exec rake test TESTOPTS="-v --no-show-detail-immediately" OSSL_TEST_ALL=1
        timeout-minutes: 5

      # Run only the passing tests on the FIPS module as a temporary workaround.
      # TODO Fix other tests, and run all the tests on FIPS module.
      - name: rake test_fips
        run: |
          sed -e "s|OPENSSL_DIR|$HOME/openssl|" tool/openssl_fips.cnf.tmpl > tmp/openssl_fips.cnf
          export OPENSSL_CONF=$(pwd)/tmp/openssl_fips.cnf
          bundle exec rake debug
          bundle exec rake test_fips TESTOPTS="-v --no-show-detail-immediately" OSSL_TEST_ALL=1
        timeout-minutes: 5
        if: ${{ startsWith(matrix.openssl, 'openssl-3') || matrix.openssl == 'openssl-master' }}


================================================
FILE: .gitignore
================================================
/.bundle
/Gemfile.lock
/doc/
/pkg/
/tmp/
/html/
*.bundle
*.so
*.o
ext/openssl/mkmf.log
ext/openssl/Makefile
ext/openssl/extconf.h


================================================
FILE: BSDL
================================================
Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to Ruby OpenSSL

Thank you for your interest in contributing to Ruby OpenSSL!

This documentation provides an overview how you can contribute.

## Bugs and feature requests

Bugs and feature requests are tracked on [GitHub].

If you think you found a bug, file a ticket on GitHub. Please DO NOT report
security issues here, there is a separate procedure which is described on
["Security at ruby-lang.org"][Ruby Security].

When reporting a bug, please make sure you include:

* Ruby version (`ruby -v`)
* `openssl` gem version (`gem list openssl` and `OpenSSL::VERSION`)
* OpenSSL library version (`OpenSSL::OPENSSL_VERSION`)
* A sample file that illustrates the problem or link to the repository or
  gem that is associated with the bug.

There are a number of unresolved issues and feature requests for openssl that
need review. Before submitting a new ticket, it is recommended to check
[known issues][Issues].

## Submitting patches

Patches are also very welcome!

Please submit a [pull request][Compare changes] with your changes.

Make sure that your branch does:

* Have good commit messages
* Follow Ruby's coding style ([Developer-How-To][Ruby Developer-How-To])
* Pass the test suite successfully (see "Testing")

## Testing

We have a test suite!

Test cases are located under the [`test/openssl`][GitHub test/openssl]
directory.

You can run it with the following three commands:

```
$ bundle install # installs rake-compiler, test-unit, ...
$ bundle exec rake compile
$ bundle exec rake test
```

### With different versions of OpenSSL

Ruby OpenSSL supports various versions of the OpenSSL library. The test suite
needs to pass on all supported combinations.

If you want to test, debug, report an issue, or contribute to the Ruby OpenSSL
or [the OpenSSL project][OpenSSL] in the non-FIPS or the
[FIPS][OpenSSL README-FIPS] case, compiling OpenSSL from the source by yourself
is a good practice.

The following steps are tested in Linux and GCC environment. You can adjust the
commands in the steps for a different environment.

To download the OpenSSL source from the Git repository, you can run the following
commands:

```
$ git clone https://github.com/openssl/openssl.git
$ cd openssl
```

You see the `master` branch used as a development branch. Testing against the
latest OpenSSL master branch is a good practice to report an issue to the
OpenSSL project.

```
$ git branch | grep '^*'
* master
```

If you test against the latest stable branch, you can run the following command.
In this example, the `openssl-3.1` branch is the stable branch of OpenSSL 3.1
series.

```
$ git checkout openssl-3.1
```

To configure OpenSSL, you can run the following commands.

In this example, we use the `OPENSSL_DIR` environment variable to specify the
OpenSSL installed directory for convenience. Including the commit hash in the
directory name is a good practice.

```
$ git rev-parse --short HEAD
0bf18140f4

$ OPENSSL_DIR=$HOME/.openssl/openssl-fips-debug-0bf18140f4
```

The following configuration options are useful in this case.
You can check [OpenSSL installation document][OpenSSL INSTALL] for details.

* `enable-fips`: Add an option to run with the OpenSSL FIPS module.
* `enable-trace`: Add an option to enabling tracing log. You can trace logs by
  implementing a code. See the man page [OSSL_TRACE(3)][OpenSSL OSSL_TRACE] for
  details.
* compiler flags
  * `-Wl,-rpath,$(LIBRPATH)`: Set the runtime shared library path to run the
    `openssl` command without the `LD_LIBRARY_PATH`. You can check
    [this document][OpenSSL NOTES-UNIX] for details.
  * `-O0 -g3 -ggdb3 -gdwarf-5`: You can set debugging compiler flags.

```
$ ./Configure \
  --prefix=$OPENSSL_DIR \
  --libdir=lib \
  enable-fips \
  enable-trace \
  '-Wl,-rpath,$(LIBRPATH)' \
  -O0 -g3 -ggdb3 -gdwarf-5
$ make -j4
$ make install
```

To print installed OpenSSL version, you can run the following command:

```
$ $OPENSSL_DIR/bin/openssl version
OpenSSL 3.2.0-alpha3-dev  (Library: OpenSSL 3.2.0-alpha3-dev )
```

Change the current working directory into Ruby OpenSSL's source directory.

To compile Ruby OpenSSL, you can run the following commands:

Similarly to when installing `openssl` gem via the `gem` command, you can pass a
`--with-openssl-dir` argument to `rake compile` to specify the OpenSSL library
 to build against.

* `MAKEFLAGS="V=1"`: Enable the compiler command lines to print in
  the log.
* `RUBY_OPENSSL_EXTCFLAGS`: Set extra compiler flags to compile Ruby OpenSSL.

```
$ bundle exec rake clean
$ MAKEFLAGS="V=1" \
  RUBY_OPENSSL_EXTCFLAGS="-O0 -g3 -ggdb3 -gdwarf-5" \
  bundle exec rake compile -- --with-openssl-dir=$OPENSSL_DIR
```

#### Testing normally in non-FIPS case

To test Ruby OpenSSL, you can run the following command:

```
$ bundle exec rake test
```

#### Testing in FIPS case

To use OpenSSL 3.0 or later versions in a FIPS-approved manner, you must load the
`fips` and `base` providers, and also use the property query `fips=yes`. The
property query is used when fetching cryptographic algorithm implementations.
This must be done at the startup of a process to avoid implicitly loading the
`default` provider which has the non-FIPS cryptographic algorithm
implementations. See also the man page [fips_module(7)][OpenSSL fips_module].

You can set this in your OpenSSL configuration file by either appropriately
modifying the default OpenSSL configuration file located at
`OpenSSL::Config::DEFAULT_CONFIG_FILE` or temporarily overriding it with the
`OPENSSL_CONF` environment variable.

In this example, we explain on the latter way.

You can create a OpenSSL FIPS config `openssl_fips.cnf` file based on the
`openssl_fips.cnf.tmpl` file in this repository, and replacing the placeholder
`OPENSSL_DIR` with your OpenSSL installed directory.

```
$ sed -e "s|OPENSSL_DIR|$OPENSSL_DIR|" tool/openssl_fips.cnf.tmpl | \
  tee $OPENSSL_DIR/ssl/openssl_fips.cnf
```

You can see the base and fips providers by running the following command if you
setup the OpenSSL FIPS config file properly.

```
$ OPENSSL_CONF=$OPENSSL_DIR/ssl/openssl_fips.cnf \
  $OPENSSL_DIR/bin/openssl list -providers
Providers:
  base
    name: OpenSSL Base Provider
    version: 3.2.0
    status: active
  fips
    name: OpenSSL FIPS Provider
    version: 3.2.0
    status: active
```

You can run the current tests in the FIPS module case used in the GitHub
Actions file `test.yml` explained in a later sentence.

```
$ OPENSSL_CONF=$OPENSSL_DIR/ssl/openssl_fips.cnf \
  bundle exec rake test_fips
```

You can also run the all the tests in the FIPS module case. You see many
failures. We are working in progress to fix the failures. Your contribution is
welcome.

```
$ OPENSSL_CONF=$OPENSSL_DIR/ssl/openssl_fips.cnf \
  TEST_RUBY_OPENSSL_FIPS_ENABLED=true \
  bundle exec rake test
```

The GitHub Actions workflow file [`test.yml`][GitHub test.yml] contains useful
information for building OpenSSL/LibreSSL and testing against them.

## Debugging

You can use the `OpenSSL.debug = true` to print additional error strings.

## Relation with Ruby source tree

After Ruby 2.3, `ext/openssl` was converted into a "default gem", a library
which ships with standard Ruby builds but can be upgraded via RubyGems. This
means the development of this gem has migrated to a [separate
repository][GitHub] and will be released independently.

The version included in the Ruby source tree (trunk branch) is synchronized with
the latest release.

## Release policy

Bug fixes (including security fixes) will be made only for the version series
included in a stable Ruby release.

## Security

If you discovered a security issue, please send us in private, using the
security issue handling procedure for Ruby core.

You can either use [HackerOne] or send an email to security@ruby-lang.org.

Please see [Security][Ruby Security] page on ruby-lang.org website for details.

Reported problems will be published after a fix is released.

_Thanks for your contributions!_

  _\- The Ruby OpenSSL team_

[GitHub]: https://github.com/ruby/openssl
[Issues]: https://github.com/ruby/openssl/issues
[Compare changes]: https://github.com/ruby/openssl/compare
[GitHub test/openssl]: https://github.com/ruby/openssl/tree/master/test/openssl
[GitHub test.yml]: https://github.com/ruby/openssl/tree/master/.github/workflows/test.yml
[Ruby Developer-How-To]: https://github.com/ruby/ruby/wiki/Developer-How-To
[Ruby Security]: https://www.ruby-lang.org/en/security/
[HackerOne]: https://hackerone.com/ruby
[OpenSSL]: https://www.openssl.org/
[OpenSSL INSTALL]: https://github.com/openssl/openssl/blob/master/INSTALL.md
[OpenSSL README-FIPS]: https://github.com/openssl/openssl/blob/master/README-FIPS.md
[OpenSSL NOTES-UNIX]: https://github.com/openssl/openssl/blob/master/NOTES-UNIX.md
[OpenSSL OSSL_TRACE]: https://www.openssl.org/docs/manmaster/man3/OSSL_TRACE.html
[OpenSSL fips_module]: https://www.openssl.org/docs/manmaster/man7/fips_module.html


================================================
FILE: COPYING
================================================
Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.
You can redistribute it and/or modify it under either the terms of the
2-clause BSDL (see the file BSDL), or the conditions below:

  1. You may make and give away verbatim copies of the source form of the
     software without restriction, provided that you duplicate all of the
     original copyright notices and associated disclaimers.

  2. You may modify your copy of the software in any way, provided that
     you do at least ONE of the following:

       a) place your modifications in the Public Domain or otherwise
          make them Freely Available, such as by posting said
	  modifications to Usenet or an equivalent medium, or by allowing
	  the author to include your modifications in the software.

       b) use the modified software only within your corporation or
          organization.

       c) give non-standard binaries non-standard names, with
          instructions on where to get the original software distribution.

       d) make other distribution arrangements with the author.

  3. You may distribute the software in object code or binary form,
     provided that you do at least ONE of the following:

       a) distribute the binaries and library files of the software,
	  together with instructions (in the manual page or equivalent)
	  on where to get the original distribution.

       b) accompany the distribution with the machine-readable source of
	  the software.

       c) give non-standard binaries non-standard names, with
          instructions on where to get the original software distribution.

       d) make other distribution arrangements with the author.

  4. You may modify and include the part of the software into any other
     software (possibly commercial).  But some files in the distribution
     are not written by the author, so that they are not under these terms.

     For the list of those files and their copying conditions, see the
     file LEGAL.

  5. The scripts and library files supplied as input to or produced as
     output from the software do not automatically fall under the
     copyright of the software, but belong to whomever generated them,
     and may be sold commercially, and may be aggregated with this
     software.

  6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
     IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     PURPOSE.


================================================
FILE: Gemfile
================================================
source "https://rubygems.org"

gem "rake"
gem "rake-compiler"
gem "test-unit", "~> 3.0", ">= 3.4.6"
gem "test-unit-ruby-core"
gem "prime"
gem "rdoc"

# Pulled in by test-unit. power_assert 3.x requires Ruby >= 3.1
gem "power_assert", "< 3" if RUBY_VERSION < "3.1"


================================================
FILE: History.md
================================================
Version 4.0.1
=============

Notable changes
---------------

* Add `sync_close` keyword argument to `OpenSSL::SSL::SSLSocket.new` as a
  short-hand for setting `sync_close` attribute on the created `SSLSocket`
  instance.
  [[GitHub #955]](https://github.com/ruby/openssl/issues/955)
  [[GitHub #996]](https://github.com/ruby/openssl/pull/996)


Bug fixes
---------

* Fix uninitialized variables in `OpenSSL::OCSP::BasicResponse#status`.
  [[GitHub #1004]](https://github.com/ruby/openssl/pull/1004)


Version 4.0.0
=============

Compatibility
-------------

* Ruby >= 2.7
* OpenSSL >= 1.1.1, LibreSSL >= 3.9, and AWS-LC 1.66.0
  - Removed support for OpenSSL 1.0.2-1.1.0 and LibreSSL 3.1-3.8.
    [[GitHub #835]](https://github.com/ruby/openssl/issues/835)
  - Added support for AWS-LC.
    [[GitHub #833]](https://github.com/ruby/openssl/issues/833)


Notable changes
---------------

* `OpenSSL::SSL`
  - Reduce overhead when writing to `OpenSSL::SSL::SSLSocket`. `#syswrite` no
    longer creates a temporary String object.
    [[GitHub #831]](https://github.com/ruby/openssl/pull/831)
  - Make `OpenSSL::SSL::SSLContext#min_version=` and `#max_version=` wrap the
    corresponding OpenSSL APIs directly, and remove the fallback to SSL options.
    [[GitHub #849]](https://github.com/ruby/openssl/pull/849)
  - Add `OpenSSL::SSL::SSLContext#sigalgs=` and `#client_sigalgs=` for
    specifying signature algorithms to use for connections.
    [[GitHub #895]](https://github.com/ruby/openssl/pull/895)
  - Rename `OpenSSL::SSL::SSLContext#ecdh_curves=` to `#groups=` following
    the underlying OpenSSL API rename. This method is no longer specific to
    ECDHE. The old method remains as an alias.
    [[GitHub #900]](https://github.com/ruby/openssl/pull/900)
  - Add `OpenSSL::SSL::SSLSocket#sigalg`, `#peer_sigalg`, and `#group` for
    getting the signature algorithm and the key agreement group used in the
    current connection.
    [[GitHub #908]](https://github.com/ruby/openssl/pull/908)
  - Enable `SSL_CTX_set_dh_auto()` for servers by default.
    [[GitHub #924]](https://github.com/ruby/openssl/pull/924)
  - Improve Ractor compatibility. Note that the internal-use constant
    `OpenSSL::SSL::SSLContext::DEFAULT_PARAMS` is now frozen.
    [[GitHub #925]](https://github.com/ruby/openssl/pull/925)
* `OpenSSL::PKey`
  - Remove `OpenSSL::PKey::EC::Point#mul` support with array arguments. The
    underlying OpenSSL API has been removed, and the method has been deprecated
    since ruby/openssl v3.0.0.
    [[GitHub #843]](https://github.com/ruby/openssl/pull/843)
  - `OpenSSL::PKey::{RSA,DSA,DH}#params` uses `nil` to indicate missing fields
    instead of the number `0`.
    [[GitHub #774]](https://github.com/ruby/openssl/pull/774)
  - Unify `OpenSSL::PKey::PKeyError` classes. The former subclasses
    `OpenSSL::PKey::DHError`, `OpenSSL::PKey::DSAError`,
    `OpenSSL::PKey::ECError`, and `OpenSSL::PKey::RSAError` have been merged
    into a single class.
    [[GitHub #929]](https://github.com/ruby/openssl/pull/929)
* `OpenSSL::Cipher`
  - `OpenSSL::Cipher#encrypt` and `#decrypt` no longer accept arguments.
    Passing passwords has been deprecated since Ruby 1.8.2 (released in 2004).
    [[GitHub #887]](https://github.com/ruby/openssl/pull/887)
  - `OpenSSL::Cipher#final` raises `OpenSSL::Cipher::AuthTagError` when the
    integrity check fails for AEAD ciphers. `OpenSSL::Cipher::AuthTagError` is a
    new subclass of `OpenSSL::Cipher::CipherError`, which was previously raised.
    [[GitHub #939]](https://github.com/ruby/openssl/pull/939)
  - `OpenSSL::Cipher.new` now raises `OpenSSL::Cipher::CipherError` instead of
    `RuntimeError` when OpenSSL does not recognize the algorithm.
    [[GitHub #958]](https://github.com/ruby/openssl/pull/958)
  - Add support for "fetched" cipher algorithms with OpenSSL 3.0 or later.
    [[GitHub #958]](https://github.com/ruby/openssl/pull/958)
* `OpenSSL::Digest`
  - `OpenSSL::Digest.new` now raises `OpenSSL::Digest::DigestError` instead of
    `RuntimeError` when OpenSSL does not recognize the algorithm.
    [[GitHub #958]](https://github.com/ruby/openssl/pull/958)
  - Add support for "fetched" digest algorithms with OpenSSL 3.0 or later.
    [[GitHub #958]](https://github.com/ruby/openssl/pull/958)
* `OpenSSL::ASN1.decode` now assumes a 1950-2049 year range for `UTCTime`
  according to RFC 5280. It previously used a 1969-2068 range. The encoder
  has always used the 1950-2049 range.
  [[GitHub #909]](https://github.com/ruby/openssl/pull/909)
* `OpenSSL::OpenSSLError`, the base class for all ruby/openssl errors, carry
  an additional attribute `#errors` to keep the content of OpenSSL's error
  queue. Also, add `#detailed_message` for Ruby 3.2 or later.
  [[GitHub #976]](https://github.com/ruby/openssl/pull/976)
* `OpenSSL::PKCS7.new` raises `OpenSSL::PKCS7::PKCS7Error` instead of
  `ArgumentError` on error to be consistent with other constructors.
  [[GitHub #983]](https://github.com/ruby/openssl/pull/983)


Version 3.3.2
=============

Merged changes in 3.1.3 and 3.2.3.


Version 3.3.1
=============

Merged changes in 3.1.2 and 3.2.2.


Version 3.3.0
=============

Compatibility
-------------

* Ruby version: 2.7 or later
* OpenSSL version: OpenSSL 1.0.2 or later, and LibreSSL 3.1 or later

Notable changes
---------------

* `OpenSSL::SSL`
  - `OpenSSL::SSL::SSLSocket#set_params` no longer sets `#min_version=` to TLS
    1.0 except when OpenSSL 1.0.2 is used. This has been done to disable
    SSL 3.0, which is not supported by default in OpenSSL 1.1.0 or later, or in
    LibreSSL. This lets it respect the system default if the system-wide
    configuration file specifies a higher minimum protocol version.
    [[GitHub #710]](https://github.com/ruby/openssl/pull/710)
  - `OpenSSL::SSL::SSLSocket.new` no longer enables the `OpenSSL::SSL::OP_ALL`
    SSL options by default and follows the system default.
    [[GitHub #767]](https://github.com/ruby/openssl/pull/767)
  - Add the following IO methods to `OpenSSL::SSL::SSLSocket`, which will pass
    along to the underlying socket: `#local_address`, `#remote_address`,
    `#close_on_exec=`, `#close_on_exec?`, `#wait`, `#wait_readable`, and
    `#wait_writable`.
    [[GitHub #708]](https://github.com/ruby/openssl/pull/708)
  - Update `OpenSSL::SSL::SSLSocket#gets` to take the `chomp` keyword argument.
    [[GitHub #708]](https://github.com/ruby/openssl/pull/708)
  - Make `OpenSSL::SSL::SSLSocket` respect the `IO#timeout` value of the
    underlying socket on Ruby 3.2 or later. `#timeout` and `#timeout=` methods
    are also added.
    [[GitHub #714]](https://github.com/ruby/openssl/pull/714)
  - Add `OpenSSL::SSL::SSLSocket#close_read` and `#close_write`.
    [[GitHub #743]](https://github.com/ruby/openssl/pull/743)
  - Add `OpenSSL::Digest.digests` to get a list of all available digest
    algorithms.
    [[GitHub #726]](https://github.com/ruby/openssl/pull/726)
  - Fix `OpenSSL::SSL::SSLSocket#read_nonblock` clearing the passed String
    buffer when nothing can be read from the connection.
    [[GitHub #739]](https://github.com/ruby/openssl/pull/739)
* Add `#to_text` methods to `OpenSSL::Timestamp::Response`,
  `OpenSSL::Timestamp::Request`, `OpenSSL::Timestamp::TokenInfo`, and
  `OpenSSL::PKCS7` to get a human-readable representation of the object.
  [[GitHub #756]](https://github.com/ruby/openssl/pull/756)
* Add `OpenSSL::X509::Certificate#tbs_bytes` to get the DER encoding of the
  TBSCertificate.
  [[GitHub #753]](https://github.com/ruby/openssl/pull/753)
* Allow passing `nil` as the digest algorithm to `#sign` methods on
  `OpenSSL::X509::Certificate`, `OpenSSL::X509::Request`, and
  `OpenSSL::X509::CRL`. This adds supports for signing with EdDSA keys.
  [[GitHub #761]](https://github.com/ruby/openssl/pull/761)
  [[GitHub #804]](https://github.com/ruby/openssl/pull/804)
* Add `OpenSSL::SSL::SSLSocket#readbyte`.
  [[GitHub #771]](https://github.com/ruby/openssl/pull/771)
* Change `OpenSSL::X509::Store#time=` to set the time to the `X509_VERIFY_PARAM`
  in the `X509_STORE`. This allows `OpenSSL::Timestamp::Response#verify` to
  verify a signature with the specified timestamp.
  [[GitHub #770]](https://github.com/ruby/openssl/pull/770)
* Make `OpenSSL::PKCS7.encrypt`'s third parameter `cipher` mandatory. It had
  an undocumented default value "RC2-40-CBC", which is not only insecure, but
  also not supported in OpenSSL 3.0 or later.
  [[GitHub #796]](https://github.com/ruby/openssl/pull/796)
* Make `OpenSSL::BN` shareable between ractors when frozen.
  [[GitHub #808]](https://github.com/ruby/openssl/pull/808)
* Make `OpenSSL::Config` instances frozen by default, and make it shareable
  between ractors. `OpenSSL::Config::DEFAULT_CONFIG_FILE` is also frozen.
  [[GitHub #809]](https://github.com/ruby/openssl/pull/809)
* Add `OpenSSL::PKCS12#set_mac` to configure the MAC parameters and recalculate
  a MAC for the content.
  [[GitHub #788]](https://github.com/ruby/openssl/pull/788)

And various non-user-visible changes and bug fixes. Please see the commit
history for more details.


Version 3.2.3
=============

Merged changes in 3.1.3.


Version 3.2.2
=============

Merged changes in 3.1.2.


Version 3.2.1
=============

Merged changes in 3.0.3.


Version 3.2.0
=============

Compatibility
-------------

* Ruby >= 2.7
  - Support for Ruby 2.6 has been removed. Note that Ruby 2.6 reached the
    end-of-life in 2022-04.
    [[GitHub #639]](https://github.com/ruby/openssl/pull/639)
* OpenSSL >= 1.0.2 or LibreSSL >= 3.1

Notable changes
---------------

* Add a stub gemspec for JRuby, which depends on the `jruby-openssl` gem.
  [[GitHub #598]](https://github.com/ruby/openssl/pull/598)
* Add support for the FIPS module in OpenSSL 3.0/3.1.
  [[GitHub #608]](https://github.com/ruby/openssl/pull/608)
* Rework `OpenSSL::PKey` routines for loading DER or PEM encoded keys for better
  compatibility with OpenSSL 3.0/3.1 with the FIPS module.
  [[GitHub #615]](https://github.com/ruby/openssl/pull/615)
  [[GitHub #669]](https://github.com/ruby/openssl/pull/669)
* Add `OpenSSL::Provider` module for loading and unloading OpenSSL 3 providers.
  [[GitHub #635]](https://github.com/ruby/openssl/pull/635)
* Add `OpenSSL::PKey.new_raw_private_key`, `.new_raw_public_key`,
  `OpenSSL::PKey::PKey#raw_private_key`, and `#raw_public_key` for public key
  algorithms that use "raw private/public key", such as X25519 and Ed25519.
  [[GitHub #646]](https://github.com/ruby/openssl/pull/646)
* Improve OpenSSL error messages to include additional information when
  it is available in OpenSSL's error queue.
  [[GitHub #648]](https://github.com/ruby/openssl/pull/648)
* Change `OpenSSL::SSL::SSLContext#ca_file=` and `#ca_path=` to raise
  `OpenSSL::SSL::SSLError` instead of printing a warning message.
  [[GitHub #659]](https://github.com/ruby/openssl/pull/659)
* Allow `OpenSSL::X509::ExtensionFactory#create_extension` to take OIDs in the
  dotted-decimal notation.
  [[GitHub #141]](https://github.com/ruby/openssl/pull/141)


Version 3.1.3
=============

Bug fixes
---------

* Fix missing NULL check for `EVP_PKEY_get0()` functions with OpenSSL 3.x.
  [[GitHub #957]](https://github.com/ruby/openssl/pull/957)


Version 3.1.2
=============

Bug fixes
---------

* Fix crash when attempting to export an incomplete `OpenSSL::PKey::DSA` key.
  [[GitHub #845]](https://github.com/ruby/openssl/issues/845)
  [[GitHub #847]](https://github.com/ruby/openssl/pull/847)
* Remove the `OpenSSL::X509::V_FLAG_CRL_CHECK_ALL` flag from the default store
  used by `OpenSSL::SSL::SSLContext#set_params`. It causes certificate
  verification to fail with OpenSSL 3.6.0. It has no effect with any other
  OpenSSL versions.
  [[GitHub #949]](https://github.com/ruby/openssl/issues/949)
  [[GitHub #950]](https://github.com/ruby/openssl/pull/950)


Version 3.1.1
=============

Merged changes in 3.0.3.


Version 3.1.0
=============

Ruby/OpenSSL 3.1 will be maintained for the lifetime of Ruby 3.2.

Merged bug fixes in 2.2.3 and 3.0.2. Among the new features and changes are:

Notable changes
---------------

* Add `OpenSSL::SSL::SSLContext#ciphersuites=` to allow setting TLS 1.3 cipher
  suites.
  [[GitHub #493]](https://github.com/ruby/openssl/pull/493)
* Add `OpenSSL::SSL::SSLSocket#export_keying_material` for exporting keying
  material of the session, as defined in RFC 5705.
  [[GitHub #530]](https://github.com/ruby/openssl/pull/530)
* Add `OpenSSL::SSL::SSLContext#keylog_cb=` for setting the TLS key logging
  callback, which is useful for supporting NSS's SSLKEYLOGFILE debugging output.
  [[GitHub #536]](https://github.com/ruby/openssl/pull/536)
* Remove the default digest algorithm from `OpenSSL::OCSP::BasicResponse#sign`
  and `OpenSSL::OCSP::Request#sign`. Omitting the 5th parameter of these
  methods used to be equivalent of specifying SHA-1. This default value is now
  removed and we will let the underlying OpenSSL library decide instead.
  [[GitHub #507]](https://github.com/ruby/openssl/pull/507)
* Add `OpenSSL::BN#mod_sqrt`.
  [[GitHub #553]](https://github.com/ruby/openssl/pull/553)
* Allow calling `OpenSSL::Cipher#update` with an empty string. This was
  prohibited to workaround an ancient bug in OpenSSL.
  [[GitHub #568]](https://github.com/ruby/openssl/pull/568)
* Fix build on platforms without socket support, such as WASI. `OpenSSL::SSL`
  will not be defined if OpenSSL is compiled with `OPENSSL_NO_SOCK`.
  [[GitHub #558]](https://github.com/ruby/openssl/pull/558)
* Improve support for recent LibreSSL versions. This includes HKDF support in
  LibreSSL 3.6 and Ed25519 support in LibreSSL 3.7.


Version 3.0.3
=============

Bug fixes
---------

* Fix a performance regression introduced in v2.1.3 on a buffered write to
  `SSLSocket`.
  [[GitHub #706]](https://github.com/ruby/openssl/pull/706)
* Fix `OpenSSL::PKCS7` to handle PKCS#7 structures without content.
  [[GitHub #690]](https://github.com/ruby/openssl/pull/690)
  [[GitHub #752]](https://github.com/ruby/openssl/pull/752)
* Fix `OpenSSL::ASN1::ObjectId#==` with OIDs without a known name.
  [[GitHub #791]](https://github.com/ruby/openssl/issues/791)
  [[GitHub #792]](https://github.com/ruby/openssl/pull/792)
* Fix `OpenSSL::X509::Certificate#crl_uris` to handle CDP with multiple CRL
  URIs.
  [[GitHub #775]](https://github.com/ruby/openssl/issues/775)
  [[GitHub #776]](https://github.com/ruby/openssl/pull/776)
* Fix `OpenSSL::Cipher#update` to always make the output buffer `String`
  independent.
  [[Bug #20937]](https://bugs.ruby-lang.org/issues/20937)
  [[GitHub #824]](https://github.com/ruby/openssl/pull/824)


Version 3.0.2
=============

Merged changes in 2.2.3. Additionally, the following issues are fixed by this
release.

Bug fixes
---------

* Fix OpenSSL::PKey::EC#check_key not working correctly on OpenSSL 3.0.
  [[GitHub #563]](https://github.com/ruby/openssl/issues/563)
  [[GitHub #580]](https://github.com/ruby/openssl/pull/580)


Version 3.0.1
=============

Merged changes in 2.1.4 and 2.2.2. Additionally, the following issues are fixed
by this release.

Bug fixes
---------

* Add missing type check in OpenSSL::PKey::PKey#sign's optional parameters.
  [[GitHub #531]](https://github.com/ruby/openssl/pull/531)
* Work around OpenSSL 3.0's HMAC issues with a zero-length key.
  [[GitHub #538]](https://github.com/ruby/openssl/pull/538)
* Fix a regression in OpenSSL::PKey::DSA.generate's default of 'q' size.
  [[GitHub #483]](https://github.com/ruby/openssl/issues/483)
  [[GitHub #539]](https://github.com/ruby/openssl/pull/539)
* Restore OpenSSL::PKey.read's ability to decode "openssl ecparam -genkey"
  output when linked against OpenSSL 3.0.
  [[GitHub #535]](https://github.com/ruby/openssl/pull/535)
  [[GitHub #540]](https://github.com/ruby/openssl/pull/540)
* Restore error checks in OpenSSL::PKey::EC#{to_der,to_pem}.
  [[GitHub #541]](https://github.com/ruby/openssl/pull/541)


Version 3.0.0
=============

Compatibility notes
-------------------

* OpenSSL 1.0.1 and Ruby 2.3-2.5 are no longer supported.
  [[GitHub #396]](https://github.com/ruby/openssl/pull/396)
  [[GitHub #466]](https://github.com/ruby/openssl/pull/466)

* OpenSSL 3.0 support is added. It is the first major version bump from OpenSSL
  1.1 and contains incompatible changes that affect Ruby/OpenSSL.
  Note that OpenSSL 3.0 support is preliminary and not all features are
  currently available:
  [[GitHub #369]](https://github.com/ruby/openssl/issues/369)

  - Deprecate the ability to modify `OpenSSL::PKey::PKey` instances. OpenSSL 3.0
    made EVP_PKEY structure immutable, and hence the following methods are not
    available when Ruby/OpenSSL is linked against OpenSSL 3.0.
    [[GitHub #480]](https://github.com/ruby/openssl/pull/480)

    - `OpenSSL::PKey::RSA#set_key`, `#set_factors`, `#set_crt_params`
    - `OpenSSL::PKey::DSA#set_pqg`, `#set_key`
    - `OpenSSL::PKey::DH#set_pqg`, `#set_key`, `#generate_key!`
    - `OpenSSL::PKey::EC#private_key=`, `#public_key=`, `#group=`, `#generate_key!`

  - Deprecate `OpenSSL::Engine`. The ENGINE API has been deprecated in OpenSSL 3.0
    in favor of the new "provider" concept and will be removed in a future
    version.
    [[GitHub #481]](https://github.com/ruby/openssl/pull/481)

* `OpenSSL::SSL::SSLContext#tmp_ecdh_callback` has been removed. It has been
  deprecated since v2.0.0 because it is incompatible with modern OpenSSL
  versions.
  [[GitHub #394]](https://github.com/ruby/openssl/pull/394)

* `OpenSSL::SSL::SSLSocket#read` and `#write` now raise `OpenSSL::SSL::SSLError`
  if called before a TLS connection is established. Historically, they
  read/wrote unencrypted data to the underlying socket directly in that case.
  [[GitHub #9]](https://github.com/ruby/openssl/issues/9)
  [[GitHub #469]](https://github.com/ruby/openssl/pull/469)


Notable changes
---------------

* Enhance OpenSSL::PKey's common interface.
  [[GitHub #370]](https://github.com/ruby/openssl/issues/370)

  - Key deserialization: Enhance `OpenSSL::PKey.read` to handle PEM encoding of
    DH parameters, which used to be only deserialized by `OpenSSL::PKey::DH.new`.
    [[GitHub #328]](https://github.com/ruby/openssl/issues/328)
  - Key generation: Add `OpenSSL::PKey.generate_parameters` and
    `OpenSSL::PKey.generate_key`.
    [[GitHub #329]](https://github.com/ruby/openssl/issues/329)
  - Public key signing: Enhance `OpenSSL::PKey::PKey#sign` and `#verify` to use
    the new EVP_DigestSign() family to enable PureEdDSA support on OpenSSL 1.1.1
    or later. They also now take optional algorithm-specific parameters for more
    control.
    [[GitHub #329]](https://github.com/ruby/openssl/issues/329)
  - Low-level public key signing and verification: Add
    `OpenSSL::PKey::PKey#sign_raw`, `#verify_raw`, and `#verify_recover`.
    [[GitHub #382]](https://github.com/ruby/openssl/issues/382)
  - Public key encryption: Add `OpenSSL::PKey::PKey#encrypt` and `#decrypt`.
    [[GitHub #382]](https://github.com/ruby/openssl/issues/382)
  - Key agreement: Add `OpenSSL::PKey::PKey#derive`.
    [[GitHub #329]](https://github.com/ruby/openssl/issues/329)
  - Key comparison: Add `OpenSSL::PKey::PKey#compare?` to conveniently check
    that two keys have common parameters and a public key.
    [[GitHub #383]](https://github.com/ruby/openssl/issues/383)

* Add `OpenSSL::BN#set_flags` and `#get_flags`. This can be used in combination
  with `OpenSSL::BN::CONSTTIME` to force constant-time computation.
  [[GitHub #417]](https://github.com/ruby/openssl/issues/417)

* Add `OpenSSL::BN#abs` to get the absolute value of the BIGNUM.
  [[GitHub #430]](https://github.com/ruby/openssl/issues/430)

* Add `OpenSSL::SSL::SSLSocket#getbyte`.
  [[GitHub #438]](https://github.com/ruby/openssl/issues/438)

* Add `OpenSSL::SSL::SSLContext#tmp_dh=`.
  [[GitHub #459]](https://github.com/ruby/openssl/pull/459)

* Add `OpenSSL::X509::Certificate.load` to load a PEM-encoded and concatenated
  list of X.509 certificates at once.
  [[GitHub #441]](https://github.com/ruby/openssl/pull/441)

* Change `OpenSSL::X509::Certificate.new` to attempt to deserialize the given
  string first as DER encoding first and then as PEM encoding to ensure the
  round-trip consistency.
  [[GitHub #442]](https://github.com/ruby/openssl/pull/442)

* Update various part of the code base to use the modern API. No breaking
  changes are intended with this. This includes:

  - `OpenSSL::HMAC` uses the EVP API.
    [[GitHub #371]](https://github.com/ruby/openssl/issues/371)
  - `OpenSSL::Config` uses native OpenSSL API to parse config files.
    [[GitHub #342]](https://github.com/ruby/openssl/issues/342)


Version 2.2.3
=============

Bug fixes
---------

* Fix serveral methods in OpenSSL::PKey::EC::Point attempting to raise an error
  with an incorrect class, which would end up with a TypeError.
  [[GitHub #570]](https://github.com/ruby/openssl/pull/570)
* Fix OpenSSL::PKey::EC::Point#eql? and OpenSSL::PKey::EC::Group#eql?
  incorrectly treated OpenSSL's internal errors as "not equal".
  [[GitHub #564]](https://github.com/ruby/openssl/pull/564)
* Fix build with LibreSSL 3.5 or later.


Version 2.2.2
=============

Merged changes in 2.1.4.


Version 2.2.1
=============

Merged changes in 2.1.3. Additionally, the following issues are fixed by this
release.

Bug fixes
---------

* Fix crash in `OpenSSL::Timestamp::{Request,Response,TokenInfo}.new` when
  invalid arguments are given.
  [[GitHub #407]](https://github.com/ruby/openssl/pull/407)
* Fix `OpenSSL::Timestamp::Factory#create_timestamp` with LibreSSL on platforms
  where `time_t` has a different size from `long`.
  [[GitHub #454]](https://github.com/ruby/openssl/pull/454)


Version 2.2.0
=============

Compatibility notes
-------------------

* Remove unsupported MDC2, DSS, DSS1, and SHA algorithms.
* Remove `OpenSSL::PKCS7::SignerInfo#name` alias for `#issuer`.
  [[GitHub #266]](https://github.com/ruby/openssl/pull/266)
* Deprecate `OpenSSL::Config#add_value` and `#[]=` for future removal.
  [[GitHub #322]](https://github.com/ruby/openssl/pull/322)


Notable changes
---------------

* Change default `OpenSSL::SSL::SSLServer#listen` backlog argument from
  5 to `Socket::SOMAXCONN`.
  [[GitHub #286]](https://github.com/ruby/openssl/issues/286)
* Make `OpenSSL::HMAC#==` use a timing safe string comparison.
  [[GitHub #284]](https://github.com/ruby/openssl/pull/284)
* Add support for SHA3 and BLAKE digests.
  [[GitHub #282]](https://github.com/ruby/openssl/pull/282)
* Add `OpenSSL::SSL::SSLSocket.open` for opening a `TCPSocket` and
  returning an `OpenSSL::SSL::SSLSocket` for it.
  [[GitHub #225]](https://github.com/ruby/openssl/issues/225)
* Support marshalling of `OpenSSL::X509` and `OpenSSL::PKey` objects.
  [[GitHub #281]](https://github.com/ruby/openssl/pull/281)
  [[GitHub #363]](https://github.com/ruby/openssl/pull/363)
* Add `OpenSSL.secure_compare` for timing safe string comparison for
  strings of possibly unequal length.
  [[GitHub #280]](https://github.com/ruby/openssl/pull/280)
* Add `OpenSSL.fixed_length_secure_compare` for timing safe string
  comparison for strings of equal length.
  [[GitHub #269]](https://github.com/ruby/openssl/pull/269)
* Add `OpenSSL::SSL::SSLSocket#{finished_message,peer_finished_message}`
  for last finished message sent and received.
  [[GitHub #250]](https://github.com/ruby/openssl/pull/250)
* Add `OpenSSL::Timestamp` module for handing timestamp requests and
  responses.
  [[GitHub #204]](https://github.com/ruby/openssl/pull/204)
* Add helper methods for `OpenSSL::X509::Certificate`:
  `find_extension`, `subject_key_identifier`,
  `authority_key_identifier`, `crl_uris`, `ca_issuer_uris` and
  `ocsp_uris`, and for `OpenSSL::X509::CRL`:
  `find_extension` and `subject_key_identifier`.
  [[GitHub #260]](https://github.com/ruby/openssl/pull/260)
  [[GitHub #275]](https://github.com/ruby/openssl/pull/275)
  [[GitHub #293]](https://github.com/ruby/openssl/pull/293)
* Add `OpenSSL::ECPoint#add` for performing elliptic curve point addition.
  [[GitHub #261]](https://github.com/ruby/openssl/pull/261)
* Make `OpenSSL::PKey::RSA#{export,to_der}` check `key`, `factors`, and
  `crt_params` to do proper private key serialization.
  [[GitHub #258]](https://github.com/ruby/openssl/pull/258)
* Add `OpenSSL::SSL::{SSLSocket,SSLServer}#fileno`, returning the
  underlying socket file descriptor number.
  [[GitHub #247]](https://github.com/ruby/openssl/pull/247)
* Support client certificates with TLS 1.3, and support post-handshake
  authentication with OpenSSL 1.1.1+.
  [[GitHub #239]](https://github.com/ruby/openssl/pull/239)
* Add `OpenSSL::ASN1::ObjectId#==` for equality testing.
* Add `OpenSSL::X509::Extension#value_der` for the raw value of
  the extension.
  [[GitHub #234]](https://github.com/ruby/openssl/pull/234)
* Significantly reduce allocated memory in `OpenSSL::Buffering#do_write`.
  [[GitHub #212]](https://github.com/ruby/openssl/pull/212)
* Ensure all valid IPv6 addresses are considered valid as elements
  of subjectAlternativeName in certificates.
  [[GitHub #185]](https://github.com/ruby/openssl/pull/185)
* Allow recipient's certificate to be omitted in PCKS7#decrypt.
  [[GitHub #183]](https://github.com/ruby/openssl/pull/183)
* Add support for reading keys in PKCS #8 format and export via instance methods
  added to `OpenSSL::PKey` classes: `private_to_der`, `private_to_pem`,
  `public_to_der` and `public_to_pem`.
  [[GitHub #297]](https://github.com/ruby/openssl/pull/297)


Version 2.1.4
=============

Bug fixes
---------

* Do not use pkg-config if --with-openssl-dir option is specified.
 [[GitHub #486]](https://github.com/ruby/openssl/pull/486)


Version 2.1.3
=============

Bug fixes
---------

* Fix deprecation warnings on Ruby 3.0.
* Add ".include" directive support in `OpenSSL::Config`.
  [[GitHub #216]](https://github.com/ruby/openssl/pull/216)
* Fix handling of IPv6 address SANs.
  [[GitHub #185]](https://github.com/ruby/openssl/pull/185)
* Hostname verification failure with `OpenSSL::SSL::SSLContext#verify_hostname=`
  sets a proper error code.
  [[GitHub #350]](https://github.com/ruby/openssl/pull/350)
* Fix crash with `OpenSSL::BN.new(nil, 2)`.
  [[Bug #15760]](https://bugs.ruby-lang.org/issues/15760)
* `OpenSSL::SSL::SSLSocket#sys{read,write}` prevent internal string buffers from
  being modified by another thread.
  [[GitHub #453]](https://github.com/ruby/openssl/pull/453)
* Fix misuse of input record separator in `OpenSSL::Buffering` where it was
  for output.
* Fix wrong integer casting in `OpenSSL::PKey::EC#dsa_verify_asn1`.
  [[GitHub #460]](https://github.com/ruby/openssl/pull/460)
* `extconf.rb` explicitly checks that OpenSSL's version number is 1.0.1 or
  newer but also less than 3.0. Ruby/OpenSSL v2.1.x and v2.2.x will not support
  OpenSSL 3.0 API.
  [[GitHub #458]](https://github.com/ruby/openssl/pull/458)
* Activate `digest` gem correctly. `digest` library could go into an
  inconsistent state if there are multiple versions of `digest` is installed
  and `openssl` is `require`d before `digest`.
  [[GitHub #463]](https://github.com/ruby/openssl/pull/463)
* Fix GC.compact compatibility.
  [[GitHub #464]](https://github.com/ruby/openssl/issues/464)
  [[GitHub #465]](https://github.com/ruby/openssl/pull/465)


Version 2.1.2
=============

Merged changes in 2.0.9.


Version 2.1.1
=============

Merged changes in 2.0.8.


Version 2.1.0
=============

Notable changes
---------------

* Support for OpenSSL versions before 1.0.1 and LibreSSL versions before 2.5
  is removed.
  [[GitHub #86]](https://github.com/ruby/openssl/pull/86)
* OpenSSL::BN#negative?, #+@, and #-@ are added.
* OpenSSL::SSL::SSLSocket#connect raises a more informative exception when
  certificate verification fails.
  [[GitHub #99]](https://github.com/ruby/openssl/pull/99)
* OpenSSL::KDF module is newly added. In addition to PBKDF2-HMAC that has moved
  from OpenSSL::PKCS5, scrypt and HKDF are supported.
  [[GitHub #109]](https://github.com/ruby/openssl/pull/109)
  [[GitHub #173]](https://github.com/ruby/openssl/pull/173)
* OpenSSL.fips_mode is added. We had the setter, but not the getter.
  [[GitHub #125]](https://github.com/ruby/openssl/pull/125)
* OpenSSL::OCSP::Request#signed? is added.
* OpenSSL::ASN1 handles the indefinite length form better. OpenSSL::ASN1.decode
  no longer wrongly treats the end-of-contents octets as part of the content.
  OpenSSL::ASN1::ASN1Data#infinite_length is renamed to #indefinite_length.
  [[GitHub #98]](https://github.com/ruby/openssl/pull/98)
* OpenSSL::X509::Name#add_entry now accepts two additional keyword arguments
  'loc' and 'set'.
  [[GitHub #94]](https://github.com/ruby/openssl/issues/94)
* OpenSSL::SSL::SSLContext#min_version= and #max_version= are added to replace
  #ssl_version= that was built on top of the deprecated OpenSSL C API. Use of
  that method and the constant OpenSSL::SSL::SSLContext::METHODS is now
  deprecated.
  [[GitHub #142]](https://github.com/ruby/openssl/pull/142)
* OpenSSL::X509::Name#to_utf8 is added.
  [[GitHub #26]](https://github.com/ruby/openssl/issues/26)
  [[GitHub #143]](https://github.com/ruby/openssl/pull/143)
* OpenSSL::X509::{Extension,Attribute,Certificate,CRL,Revoked,Request} can be
  compared with == operator.
  [[GitHub #161]](https://github.com/ruby/openssl/pull/161)
* TLS Fallback Signaling Cipher Suite Value (SCSV) support is added.
  [[GitHub #165]](https://github.com/ruby/openssl/pull/165)
* Build failure with OpenSSL 1.1 built with no-deprecated is fixed.
  [[GitHub #160]](https://github.com/ruby/openssl/pull/160)
* OpenSSL::Buffering#write accepts an arbitrary number of arguments.
  [[Feature #9323]](https://bugs.ruby-lang.org/issues/9323)
  [[GitHub #162]](https://github.com/ruby/openssl/pull/162)
* OpenSSL::PKey::RSA#sign_pss and #verify_pss are added. They perform RSA-PSS
  signature and verification.
  [[GitHub #75]](https://github.com/ruby/openssl/issues/75)
  [[GitHub #76]](https://github.com/ruby/openssl/pull/76)
  [[GitHub #169]](https://github.com/ruby/openssl/pull/169)
* OpenSSL::SSL::SSLContext#add_certificate is added.
  [[GitHub #167]](https://github.com/ruby/openssl/pull/167)
* OpenSSL::PKey::EC::Point#to_octet_string is added.
  OpenSSL::PKey::EC::Point.new can now take String as the second argument.
  [[GitHub #177]](https://github.com/ruby/openssl/pull/177)


Version 2.0.9
=============

Security fixes
--------------

* OpenSSL::X509::Name#<=> could incorrectly return 0 (= equal) for non-equal
  objects. CVE-2018-16395 is assigned for this issue.
  https://hackerone.com/reports/387250

Bug fixes
---------

* Fixed OpenSSL::PKey::\*.{new,generate} immediately aborting if the thread is
  interrupted.
  [[Bug #14882]](https://bugs.ruby-lang.org/issues/14882)
  [[GitHub #205]](https://github.com/ruby/openssl/pull/205)
* Fixed OpenSSL::X509::Name#to_s failing with OpenSSL::X509::NameError if
  called against an empty instance.
  [[GitHub #200]](https://github.com/ruby/openssl/issues/200)
  [[GitHub #211]](https://github.com/ruby/openssl/pull/211)


Version 2.0.8
=============

Bug fixes
---------

* OpenSSL::Cipher#pkcs5_keyivgen raises an error when a negative iteration
  count is given.
  [[GitHub #184]](https://github.com/ruby/openssl/pull/184)
* Fixed build with LibreSSL 2.7.
  [[GitHub #192]](https://github.com/ruby/openssl/issues/192)
  [[GitHub #193]](https://github.com/ruby/openssl/pull/193)


Version 2.0.7
=============

Bug fixes
---------

* OpenSSL::Cipher#auth_data= could segfault if called against a non-AEAD cipher.
  [[Bug #14024]](https://bugs.ruby-lang.org/issues/14024)
* OpenSSL::X509::Certificate#public_key= (and similar methods) could segfault
  when an instance of OpenSSL::PKey::PKey with no public key components is
  passed.
  [[Bug #14087]](https://bugs.ruby-lang.org/issues/14087)
  [[GitHub #168]](https://github.com/ruby/openssl/pull/168)


Version 2.0.6
=============

Bug fixes
---------

* The session_remove_cb set to an OpenSSL::SSL::SSLContext is no longer called
  during GC.
* A possible deadlock in OpenSSL::SSL::SSLSocket#sysread is fixed.
  [[GitHub #139]](https://github.com/ruby/openssl/pull/139)
* OpenSSL::BN#hash could return an unnormalized fixnum value on Windows.
  [[Bug #13877]](https://bugs.ruby-lang.org/issues/13877)
* OpenSSL::SSL::SSLSocket#sysread and #sysread_nonblock set the length of the
  destination buffer String to 0 on error.
  [[GitHub #153]](https://github.com/ruby/openssl/pull/153)
* Possible deadlock is fixed. This happened only when built with older versions
  of OpenSSL (before 1.1.0) or LibreSSL.
  [[GitHub #155]](https://github.com/ruby/openssl/pull/155)


Version 2.0.5
=============

Bug fixes
---------

* Reading a PEM/DER-encoded private key or certificate from an IO object did
  not work properly on mswin platforms.
  [[ruby/openssl#128]](https://github.com/ruby/openssl/issues/128)
* Broken length check in the PEM passphrase callback is fixed.
* It failed to compile when OpenSSL is configured without TLS 1.0 support.


Version 2.0.4
=============

Bug fixes
---------

* It now compiles with LibreSSL without renaming on Windows (mswin).
* A workaround for the error queue leak of X509_load_cert_crl_file() that
  causes random errors is added.
  [[Bug #11033]](https://bugs.ruby-lang.org/issues/11033)


Version 2.0.3
=============

Bug fixes
---------

* OpenSSL::ASN1::Constructive#each which was broken by 2.0.0 is fixed.
  [[ruby/openssl#96]](https://github.com/ruby/openssl/pull/96)
* Fixed build with static OpenSSL libraries on Windows.
  [[Bug #13080]](https://bugs.ruby-lang.org/issues/13080)
* OpenSSL::X509::Name#eql? which was broken by 2.0.0 is fixed.


Version 2.0.2
=============

Bug fixes
---------

* Fix build with early 0.9.8 series which did not have SSL_CTX_clear_options().
  [ruby-core:78693]


Version 2.0.1
=============

Bug fixes
---------

* A GC issue around OpenSSL::BN is fixed.
  [[ruby/openssl#87]](https://github.com/ruby/openssl/issues/87)
* OpenSSL::ASN1 now parses BER encoding of GeneralizedTime without seconds.
  [[ruby/openssl#88]](https://github.com/ruby/openssl/pull/88)


Version 2.0.0
=============

This is the first release of openssl gem, formerly a standard library of Ruby,
ext/openssl. This is the successor of the version included in Ruby 2.3.

Compatibility notes
-------------------

* Support for OpenSSL version 0.9.6 and 0.9.7 is completely removed. openssl gem
  still works with OpenSSL 0.9.8, but users are strongly encouraged to upgrade
  to at least 1.0.1, as OpenSSL < 1.0.1 will not receive any security fixes from
  the OpenSSL development team.

Supported platforms
-------------------

* OpenSSL 1.0.0, 1.0.1, 1.0.2, 1.1.0
* OpenSSL < 0.9.8 is no longer supported.
* LibreSSL 2.3, 2.4, 2.5
* Ruby 2.3, 2.4

Notable changes
---------------

* Add support for OpenSSL 1.1.0.
  [[Feature #12324]](https://bugs.ruby-lang.org/issues/12324)
* Add support for LibreSSL

* OpenSSL::Cipher

  - OpenSSL::Cipher#key= and #iv= reject too long inputs. They used to truncate
    silently. [[Bug #12561]](https://bugs.ruby-lang.org/issues/12561)

  - OpenSSL::Cipher#iv_len= is added. It allows changing IV (nonce) length if
    using AEAD ciphers.
    [[Bug #8667]](https://bugs.ruby-lang.org/issues/8667),
    [[Bug #10420]](https://bugs.ruby-lang.org/issues/10420),
    [[GH ruby/ruby#569]](https://github.com/ruby/ruby/pull/569),
    [[GH ruby/openssl#58]](https://github.com/ruby/openssl/pull/58)

  - OpenSSL::Cipher#auth_tag_len= is added. This sets the authentication tag
    length to be generated by an AEAD cipher.

* OpenSSL::OCSP

  - Accessor methods are added to OpenSSL::OCSP::CertificateId.
    [[Feature #7181]](https://bugs.ruby-lang.org/issues/7181)

  - OpenSSL::OCSP::Request and BasicResponse can be signed with non-SHA-1 hash
    algorithm. [[Feature #11552]](https://bugs.ruby-lang.org/issues/11552)

  - OpenSSL::OCSP::CertificateId and BasicResponse can be encoded into DER.

  - A new class OpenSSL::OCSP::SingleResponse is added for convenience.

  - OpenSSL::OCSP::BasicResponse#add_status accepts absolute times. They used to
    accept only relative seconds from the current time.

* OpenSSL::PKey

  - OpenSSL::PKey::EC follows the general PKey interface.
    [[Bug #6567]](https://bugs.ruby-lang.org/issues/6567)

  - OpenSSL::PKey.read raises OpenSSL::PKey::PKeyError instead of ArgumentError
    for consistency with OpenSSL::PKey::{DH,DSA,RSA,EC}#new.
    [[Bug #11774]](https://bugs.ruby-lang.org/issues/11774),
    [[GH ruby/openssl#55]](https://github.com/ruby/openssl/pull/55)

  - OpenSSL::PKey::EC::Group retrieved by OpenSSL::PKey::EC#group is no longer
    linked with the EC key. Modifications to the EC::Group have no effect on the
    key. [[GH ruby/openssl#71]](https://github.com/ruby/openssl/pull/71)

  - OpenSSL::PKey::EC::Point#to_bn allows specifying the point conversion form
    by the optional argument.

* OpenSSL::SSL

  - OpenSSL::SSL::SSLSocket#tmp_key is added. A client can call it after the
    connection is established to retrieve the ephemeral key.
    [[GH ruby/ruby#1318]](https://github.com/ruby/ruby/pull/1318)

  - The automatic ephemeral ECDH curve selection is enabled by default when
    built with OpenSSL >= 1.0.2 or LibreSSL.

  - OpenSSL::SSL::SSLContext#security_level= is added. You can set the "security
    level" of the SSL context. This is effective only when built with OpenSSL
    1.1.0.

  - A new option 'verify_hostname' is added to OpenSSL::SSL::SSLContext. When it
    is enabled, and the SNI hostname is also set, the hostname verification on
    the server certificate is automatically performed. It is now enabled by
    OpenSSL::SSL::SSLContext#set_params.
    [[GH ruby/openssl#60]](https://github.com/ruby/openssl/pull/60)

Removals
--------

* OpenSSL::Engine

  - OpenSSL::Engine.cleanup does nothing when built with OpenSSL 1.1.0.

* OpenSSL::SSL

  - OpenSSL::PKey::DH::DEFAULT_512 is removed. Hence servers no longer use
    512-bit DH group by default. It is considered too weak nowadays.
    [[Bug #11968]](https://bugs.ruby-lang.org/issues/11968),
    [[GH ruby/ruby#1196]](https://github.com/ruby/ruby/pull/1196)

  - RC4 cipher suites are removed from OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.
    RC4 is now considered to be weak.
    [[GH ruby/openssl#50]](https://github.com/ruby/openssl/pull/50)

Deprecations
------------

* OpenSSL::PKey

  - OpenSSL::PKey::RSA#n=, #e=, #d=, #p=, #q=, #dmp1=, #dmq1=, #iqmp=,
    OpenSSL::PKey::DSA#p=, #q=, #g=, #priv_key=, #pub_key=,
    OpenSSL::PKey::DH#p=, #g=, #priv_key= and #pub_key= are deprecated. They are
    disabled when built with OpenSSL 1.1.0, due to its API change. Instead,
    OpenSSL::PKey::RSA#set_key, #set_factors, #set_crt_params,
    OpenSSL::PKey::DSA#set_pqg, #set_key, OpenSSL::PKey::DH#set_pqg and #set_key
    are added.

* OpenSSL::Random

  - OpenSSL::Random.pseudo_bytes is deprecated, and not defined when built with
    OpenSSL 1.1.0. Use OpenSSL::Random.random_bytes instead.

* OpenSSL::SSL

  - OpenSSL::SSL::SSLContext#tmp_ecdh_callback is deprecated, as the underlying
    API SSL_CTX_set_tmp_ecdh_callback() is removed in OpenSSL 1.1.0. It was
    first added in Ruby 2.3.0. To specify the curve to be used in ephemeral
    ECDH, use OpenSSL::SSL::SSLContext#ecdh_curves=. The automatic curve
    selection is also now enabled by default when built with a capable OpenSSL.


================================================
FILE: README.md
================================================
# OpenSSL for Ruby

[![Actions Status](https://github.com/ruby/openssl/workflows/CI/badge.svg)](https://github.com/ruby/openssl/actions?workflow=CI)

**OpenSSL for Ruby** provides access to SSL/TLS and general-purpose
cryptography based on the OpenSSL library.

OpenSSL for Ruby is sometimes referred to as **openssl** in all lowercase
or **Ruby/OpenSSL** for disambiguation.

## Compatibility and maintenance policy

OpenSSL for Ruby is released as a RubyGems gem. At the same time, it is part of
the standard library of Ruby. This is called a [default gem].

Each stable branch of OpenSSL for Ruby will remain supported as long as it is
included as a default gem in [supported Ruby branches][Ruby Maintenance Branches].

|Version|Minimum Ruby|OpenSSL compatibility                    |Bundled with|Maintenance  |
|-------|------------|-----------------------------------------|------------|-------------|
|4.0.x  |Ruby 2.7    |OpenSSL 1.1.1-3.x, LibreSSL 3.9+, AWS-LC |Ruby 4.0    |bug fixes    |
|3.3.x  |Ruby 2.7    |OpenSSL 1.0.2-3.x, LibreSSL 3.1+         |Ruby 3.4    |bug fixes    |
|3.2.x  |Ruby 2.7    |OpenSSL 1.0.2-3.x, LibreSSL 3.1+         |Ruby 3.3    |bug fixes    |
|3.1.x  |Ruby 2.6    |OpenSSL 1.0.2-3.x, LibreSSL 3.1+         |Ruby 3.2    |security only|
|3.0.x  |Ruby 2.6    |OpenSSL 1.0.2-3.x, LibreSSL 3.1+         |Ruby 3.1    |end-of-life  |
|2.2.x  |Ruby 2.3    |OpenSSL 1.0.1-1.1.1, LibreSSL 2.9+       |Ruby 3.0    |end-of-life  |
|2.1.x  |Ruby 2.3    |OpenSSL 1.0.1-1.1.1, LibreSSL 2.5+       |Ruby 2.5-2.7|end-of-life  |
|2.0.x  |Ruby 2.3    |OpenSSL 0.9.8-1.1.1, LibreSSL 2.3+       |Ruby 2.4    |end-of-life  |

[default gem]: https://docs.ruby-lang.org/en/master/standard_library_md.html
[Ruby Maintenance Branches]: https://www.ruby-lang.org/en/downloads/branches/

## Installation

> **Note**
> The openssl gem is included with Ruby by default, but you may wish to upgrade
> it to a newer version available at [rubygems.org][RubyGems.org openssl].

To upgrade it, you can use RubyGems:

```
gem install openssl
```

In some cases, it may be necessary to specify the path to the installation
directory of the OpenSSL library.

```
gem install openssl -- --with-openssl-dir=/opt/openssl
```

Alternatively, you can install the gem with Bundler:

```ruby
# Gemfile
gem 'openssl'
# or specify git master
gem 'openssl', git: 'https://github.com/ruby/openssl'
```

After running `bundle install`, you should have the gem installed in your bundle.

[RubyGems.org openssl]: https://rubygems.org/gems/openssl

## Usage

Once installed, you can require "openssl" in your application.

```ruby
require "openssl"
```

## Documentation

See https://ruby.github.io/openssl/.

## Contributing

Please read our [CONTRIBUTING.md] for instructions.

[CONTRIBUTING.md]: https://github.com/ruby/openssl/tree/master/CONTRIBUTING.md

## Security

Security issues should be reported to ruby-core by following the process
described on ["Security at ruby-lang.org"][Security].

[Security]: https://www.ruby-lang.org/en/security/


================================================
FILE: Rakefile
================================================
require 'rake/testtask'
require 'rdoc/task'
require 'bundler/gem_tasks'

begin
  require 'rake/extensiontask'
  Rake::ExtensionTask.new('openssl')
rescue LoadError
  warn "rake-compiler not installed. Run 'bundle install' to " \
    "install testing dependency gems."
end

task :test => :compile
Rake::TestTask.new do |t|
  t.test_files = FileList["test/**/test_*.rb"]
  t.warning = true
end

desc 'Run tests for fips'
task :test_fips => :compile do
  ENV['TEST_RUBY_OPENSSL_FIPS_ENABLED'] = 'true'
  Rake::Task['test_fips_internal'].invoke
end

Rake::TestTask.new(:test_fips_internal) do |t|
  # Exclude failing test files in FIPS for this task to pass.
  # TODO: Fix failing test files.
  t.test_files = FileList['test/**/test_*.rb'] - FileList[
    'test/openssl/test_hmac.rb',
    'test/openssl/test_kdf.rb',
    'test/openssl/test_ts.rb',
  ]
  t.warning = true
end

RDoc::Task.new do |rdoc|
  rdoc.main = "README.md"
  rdoc.rdoc_files.include("*.md", "lib/**/*.rb", "ext/**/*.c")
end

# Print Ruby and compiler info for debugging purpose.
task :debug_compiler do
  compiler = RbConfig::CONFIG['CC']
  case compiler
  when 'gcc', 'clang'
    sh "#{compiler} --version"
  else
    Rake.rake_output_message "Compiler: #{RbConfig::CONFIG['CC']}"
  end
end

task :debug do
  ruby_code = <<~'EOF'
    openssl_version_number_str = OpenSSL::OPENSSL_VERSION_NUMBER.to_s(16)
    libressl_version_number_str = (defined? OpenSSL::LIBRESSL_VERSION_NUMBER) ?
      OpenSSL::LIBRESSL_VERSION_NUMBER.to_s(16) : "undefined"
    providers_str = (defined? OpenSSL::Provider) ?
      OpenSSL::Provider.provider_names.join(", ") : "undefined"
    puts <<~MESSAGE
      OpenSSL::OPENSSL_VERSION: #{OpenSSL::OPENSSL_VERSION}
      OpenSSL::OPENSSL_LIBRARY_VERSION: #{OpenSSL::OPENSSL_LIBRARY_VERSION}
      OpenSSL::OPENSSL_VERSION_NUMBER: #{openssl_version_number_str}
      OpenSSL::LIBRESSL_VERSION_NUMBER: #{libressl_version_number_str}
      FIPS enabled: #{OpenSSL.fips_mode}
      Providers: #{providers_str}
    MESSAGE
  EOF
  ruby %Q(-I./lib -ropenssl.so -e'#{ruby_code}'), verbose: false
end

task :default => :test


================================================
FILE: ext/openssl/extconf.rb
================================================
# -*- coding: us-ascii -*-
# frozen_string_literal: true
=begin
= Info
  'OpenSSL for Ruby 2' project
  Copyright (C) 2002  Michal Rokos <m.rokos@sh.cvut.cz>
  All rights reserved.

= Licence
  This program is licensed under the same licence as Ruby.
  (See the file 'COPYING'.)
=end

require "mkmf"

ssl_dirs = dir_config("openssl")
dir_config_given = ssl_dirs.any?

_, ssl_ldir = ssl_dirs
if ssl_ldir&.split(File::PATH_SEPARATOR)&.none? { |dir| File.directory?(dir) }
  # According to the `mkmf.rb#dir_config`, the `--with-openssl-dir=<dir>` uses
  # the value of the `File.basename(RbConfig::MAKEFILE_CONFIG["libdir"])` as a
  # loaded library directory name.
  ruby_ldir_name = File.basename(RbConfig::MAKEFILE_CONFIG["libdir"])

  raise "OpenSSL library directory could not be found in '#{ssl_ldir}'. " \
    "You might want to fix this error in one of the following ways.\n" \
    "  * Recompile OpenSSL by configuring it with --libdir=#{ruby_ldir_name} " \
    " to specify the OpenSSL library directory.\n" \
    "  * Recompile Ruby by configuring it with --libdir=<dir> to specify the " \
    "Ruby library directory.\n" \
    "  * Compile this openssl gem with --with-openssl-include=<dir> and " \
    "--with-openssl-lib=<dir> options to specify the OpenSSL include and " \
    "library directories."
end

Logging::message "=== OpenSSL for Ruby configurator ===\n"

$defs.push("-D""OPENSSL_SUPPRESS_DEPRECATED")

# Missing in TruffleRuby
have_func("rb_call_super_kw(0, NULL, 0)", "ruby.h")
# Ruby 3.1
have_func("rb_io_descriptor", "ruby/io.h")
have_func("rb_io_maybe_wait(0, Qnil, Qnil, Qnil)", "ruby/io.h")
# Ruby 3.2
have_func("rb_io_timeout", "ruby/io.h")

Logging::message "=== Checking for system dependent stuff... ===\n"
have_library("nsl", "t_open")
have_library("socket", "socket")
if $mswin || $mingw
  have_library("ws2_32")
end

if $mingw
  append_cflags '-D_FORTIFY_SOURCE=2'
  append_ldflags '-fstack-protector'
  have_library 'ssp'
end

def find_openssl_library
  if $mswin || $mingw
    # required for static OpenSSL libraries
    have_library("crypt32")
  end

  return false unless have_header("openssl/ssl.h")

  ret = have_library("crypto", "CRYPTO_malloc") &&
    have_library("ssl", "SSL_new")
  return ret if ret

  if $mswin
    # OpenSSL >= 1.1.0: libcrypto.lib and libssl.lib.
    if have_library("libcrypto", "CRYPTO_malloc") &&
        have_library("libssl", "SSL_new")
      return true
    end

    # LibreSSL: libcrypto-##.lib and libssl-##.lib, where ## is the ABI version
    # number. We have to find the version number out by scanning libpath.
    libpath = $LIBPATH.dup
    libpath |= ENV["LIB"].split(File::PATH_SEPARATOR)
    libpath.map! { |d| d.tr(File::ALT_SEPARATOR, File::SEPARATOR) }

    ret = [
      ["crypto", "CRYPTO_malloc"],
      ["ssl", "SSL_new"]
    ].all? do |base, func|
      result = false
      libs = ["lib#{base}-[0-9][0-9]", "lib#{base}-[0-9][0-9][0-9]"]
      libs = Dir.glob(libs.map{|l| libpath.map{|d| File.join(d, l + ".*")}}.flatten).map{|path| File.basename(path, ".*")}.uniq
      libs.each do |lib|
        result = have_library(lib, func)
        break if result
      end
      result
    end
    return ret if ret
  end
  return false
end

Logging::message "=== Checking for required stuff... ===\n"
pkg_config_found = !dir_config_given && pkg_config("openssl") && have_header("openssl/ssl.h")

if !pkg_config_found && !find_openssl_library
  Logging::message "=== Checking for required stuff failed. ===\n"
  Logging::message "Makefile wasn't created. Fix the errors above.\n"
  raise "OpenSSL library could not be found. You might want to use " \
    "--with-openssl-dir=<dir> option to specify the prefix where OpenSSL " \
    "is installed."
end

version_ok = if have_macro("LIBRESSL_VERSION_NUMBER", "openssl/opensslv.h")
  is_libressl = true
  checking_for("LibreSSL version >= 3.9.0") {
    try_static_assert("LIBRESSL_VERSION_NUMBER >= 0x30900000L", "openssl/opensslv.h") }
else
  is_openssl = true
  checking_for("OpenSSL version >= 1.1.1") {
    try_static_assert("OPENSSL_VERSION_NUMBER >= 0x10101000L", "openssl/opensslv.h") }
end
unless version_ok
  raise "OpenSSL >= 1.1.1 or LibreSSL >= 3.9.0 is required"
end

# Prevent wincrypt.h from being included, which defines conflicting macro with openssl/x509.h
if is_libressl && ($mswin || $mingw)
  $defs.push("-DNOCRYPT")
end

Logging::message "=== Checking for OpenSSL features... ===\n"
evp_h = "openssl/evp.h".freeze
ts_h = "openssl/ts.h".freeze
ssl_h = "openssl/ssl.h".freeze

# compile options
have_func("RAND_egd()", "openssl/rand.h")

# added in OpenSSL 1.0.2, not in LibreSSL yet
have_func("SSL_CTX_set1_sigalgs_list(NULL, NULL)", ssl_h)
# added in OpenSSL 1.0.2, not in LibreSSL or AWS-LC yet
have_func("SSL_CTX_set1_client_sigalgs_list(NULL, NULL)", ssl_h)

# added in 1.1.0, currently not in LibreSSL
have_func("EVP_PBE_scrypt(\"\", 0, (unsigned char *)\"\", 0, 0, 0, 0, 0, NULL, 0)", evp_h)

# added in OpenSSL 1.1.1 and LibreSSL 3.5.0, then removed in LibreSSL 4.0.0
have_func("EVP_PKEY_check(NULL)", evp_h)

# added in 3.0.0
have_func("SSL_CTX_set0_tmp_dh_pkey(NULL, NULL)", ssl_h)
have_func("ERR_get_error_all(NULL, NULL, NULL, NULL, NULL)", "openssl/err.h")
have_func("SSL_CTX_load_verify_file(NULL, \"\")", ssl_h)
have_func("BN_check_prime(NULL, NULL, NULL)", "openssl/bn.h")
have_func("EVP_MD_CTX_get0_md(NULL)", evp_h)
have_func("EVP_MD_CTX_get_pkey_ctx(NULL)", evp_h)
have_func("EVP_PKEY_eq(NULL, NULL)", evp_h)
have_func("EVP_PKEY_dup(NULL)", evp_h)

# added in 3.2.0
have_func("SSL_get0_group_name(NULL)", ssl_h)

# added in 3.4.0
have_func("TS_VERIFY_CTX_set0_certs(NULL, NULL)", ts_h)

# added in 3.5.0
have_func("SSL_get0_peer_signature_name(NULL, NULL)", ssl_h)

# added in 4.0.0
have_func("ASN1_BIT_STRING_set1(NULL, NULL, 0, 0)", "openssl/asn1.h")

Logging::message "=== Checking done. ===\n"

# Append flags from environment variables.
extcflags = ENV["RUBY_OPENSSL_EXTCFLAGS"]
append_cflags(extcflags.split) if extcflags
extldflags = ENV["RUBY_OPENSSL_EXTLDFLAGS"]
append_ldflags(extldflags.split) if extldflags

create_header
create_makefile("openssl")
Logging::message "Done.\n"


================================================
FILE: ext/openssl/openssl_missing.h
================================================
/*
 * 'OpenSSL for Ruby' project
 * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
 * All rights reserved.
 */
/*
 * This program is licensed under the same licence as Ruby.
 * (See the file 'COPYING'.)
 */
#if !defined(_OSSL_OPENSSL_MISSING_H_)
#define _OSSL_OPENSSL_MISSING_H_

#include "ruby/config.h"

/* added in 3.0.0 */
#ifndef HAVE_EVP_MD_CTX_GET0_MD
#  define EVP_MD_CTX_get0_md(ctx) EVP_MD_CTX_md(ctx)
#endif

/*
 * OpenSSL 1.1.0 added EVP_MD_CTX_pkey_ctx(), and then it was renamed to
 * EVP_MD_CTX_get_pkey_ctx(x) in OpenSSL 3.0.
 */
#ifndef HAVE_EVP_MD_CTX_GET_PKEY_CTX
#  define EVP_MD_CTX_get_pkey_ctx(x) EVP_MD_CTX_pkey_ctx(x)
#endif

#ifndef HAVE_EVP_PKEY_EQ
#  define EVP_PKEY_eq(a, b) EVP_PKEY_cmp(a, b)
#endif

/* added in 4.0.0 */
#ifndef HAVE_ASN1_BIT_STRING_SET1
static inline int
ASN1_BIT_STRING_set1(ASN1_BIT_STRING *bitstr, const uint8_t *data,
                     size_t length, int unused_bits)
{
    if (length > INT_MAX || !ASN1_STRING_set(bitstr, data, (int)length))
        return 0;
    bitstr->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
    bitstr->flags |= ASN1_STRING_FLAG_BITS_LEFT | unused_bits;
    return 1;
}

static inline int
ASN1_BIT_STRING_get_length(const ASN1_BIT_STRING *bitstr, size_t *length,
                           int *unused_bits)
{
    *length = bitstr->length;
    *unused_bits = bitstr->flags & 0x07;
    return 1;
}
#endif

#endif /* _OSSL_OPENSSL_MISSING_H_ */


================================================
FILE: ext/openssl/ossl.c
================================================
/*
 * 'OpenSSL for Ruby' project
 * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
 * All rights reserved.
 */
/*
 * This program is licensed under the same licence as Ruby.
 * (See the file 'COPYING'.)
 */
#include "ossl.h"
#include <stdarg.h> /* for ossl_raise */

/*
 * Data Conversion
 */
#define OSSL_IMPL_ARY2SK(name, type, expected_class, dup)       \
VALUE                                                           \
ossl_##name##_ary2sk0(VALUE ary)                                \
{                                                               \
    STACK_OF(type) *sk;                                         \
    VALUE val;                                                  \
    type *x;                                                    \
    int i;                                                      \
                                                                \
    Check_Type(ary, T_ARRAY);                                   \
    sk = sk_##type##_new_null();                                \
    if (!sk) ossl_raise(eOSSLError, NULL);                      \
                                                                \
    for (i = 0; i < RARRAY_LEN(ary); i++) {                     \
        val = rb_ary_entry(ary, i);                             \
        if (!rb_obj_is_kind_of(val, expected_class)) {          \
            sk_##type##_pop_free(sk, type##_free);              \
            ossl_raise(eOSSLError, "object in array not"        \
                       " of class ##type##");                   \
        }                                                       \
        x = dup(val); /* NEED TO DUP */                         \
        if (!sk_##type##_push(sk, x)) {                         \
            type##_free(x);                                     \
            sk_##type##_pop_free(sk, type##_free);              \
            ossl_raise(eOSSLError, NULL);                       \
        }                                                       \
    }                                                           \
    return (VALUE)sk;                                           \
}                                                               \
                                                                \
STACK_OF(type) *                                                \
ossl_protect_##name##_ary2sk(VALUE ary, int *status)            \
{                                                               \
    return (STACK_OF(type)*)rb_protect(                         \
            (VALUE (*)(VALUE))ossl_##name##_ary2sk0,            \
            ary,                                                \
            status);                                            \
}                                                               \
                                                                \
STACK_OF(type) *                                                \
ossl_##name##_ary2sk(VALUE ary)                                 \
{                                                               \
    STACK_OF(type) *sk;                                         \
    int status = 0;                                             \
                                                                \
    sk = ossl_protect_##name##_ary2sk(ary, &status);            \
    if (status) rb_jump_tag(status);                            \
                                                                \
    return sk;                                                  \
}
OSSL_IMPL_ARY2SK(x509, X509, cX509Cert, DupX509CertPtr)

#define OSSL_IMPL_SK2ARY(name, type)            \
VALUE                                           \
ossl_##name##_sk2ary(const STACK_OF(type) *sk)  \
{                                               \
    type *t;                                    \
    int i, num;                                 \
    VALUE ary;                                  \
                                                \
    RUBY_ASSERT(sk != NULL);                    \
    num = sk_##type##_num(sk);                  \
    ary = rb_ary_new_capa(num);                 \
                                                \
    for (i=0; i<num; i++) {                     \
        t = sk_##type##_value(sk, i);           \
        rb_ary_push(ary, ossl_##name##_new(t)); \
    }                                           \
    return ary;                                 \
}
OSSL_IMPL_SK2ARY(x509, X509)
OSSL_IMPL_SK2ARY(x509crl, X509_CRL)
OSSL_IMPL_SK2ARY(x509name, X509_NAME)

static VALUE
ossl_str_new_i(VALUE size)
{
    return rb_str_new(NULL, (long)size);
}

VALUE
ossl_str_new(const char *ptr, long len, int *pstate)
{
    VALUE str;
    int state;

    str = rb_protect(ossl_str_new_i, len, &state);
    if (pstate)
        *pstate = state;
    if (state) {
        if (!pstate)
            rb_set_errinfo(Qnil);
        return Qnil;
    }
    if (ptr)
        memcpy(RSTRING_PTR(str), ptr, len);
    return str;
}

VALUE
ossl_buf2str(char *buf, int len)
{
    VALUE str;
    int state;

    str = ossl_str_new(buf, len, &state);
    OPENSSL_free(buf);
    if (state)
        rb_jump_tag(state);
    return str;
}

void
ossl_bin2hex(const unsigned char *in, char *out, size_t inlen)
{
    const char *hex = "0123456789abcdef";
    size_t i;

    assert(inlen <= LONG_MAX / 2);
    for (i = 0; i < inlen; i++) {
        unsigned char p = in[i];

        out[i * 2 + 0] = hex[p >> 4];
        out[i * 2 + 1] = hex[p & 0x0f];
    }
}

/*
 * our default PEM callback
 */
VALUE
ossl_pem_passwd_value(VALUE pass)
{
    if (NIL_P(pass))
        return Qnil;

    StringValue(pass);

    /* PEM_BUFSIZE is currently used as the second argument of pem_password_cb,
     * that is +max_len+ of ossl_pem_passwd_cb() */
    if (RSTRING_LEN(pass) > PEM_BUFSIZE)
        ossl_raise(eOSSLError, "password must not be longer than %d bytes", PEM_BUFSIZE);

    return pass;
}

static VALUE
ossl_pem_passwd_cb0(VALUE flag)
{
    VALUE pass = rb_yield(flag);
    if (NIL_P(pass))
        return Qnil;
    StringValue(pass);
    return pass;
}

int
ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_)
{
    long len;
    int status;
    VALUE rflag, pass = (VALUE)pwd_;

    if (RTEST(pass)) {
        /* PEM_def_callback(buf, max_len, flag, StringValueCStr(pass)) does not
         * work because it does not allow NUL characters and truncates to 1024
         * bytes silently if the input is over 1024 bytes */
        if (RB_TYPE_P(pass, T_STRING)) {
            len = RSTRING_LEN(pass);
            if (len <= max_len) {
                memcpy(buf, RSTRING_PTR(pass), len);
                return (int)len;
            }
        }
        OSSL_Debug("passed data is not valid String???");
        return -1;
    }

    if (!rb_block_given_p()) {
        return PEM_def_callback(buf, max_len, flag, NULL);
    }

    while (1) {
        /*
         * when the flag is nonzero, this password
         * will be used to perform encryption; otherwise it will
         * be used to perform decryption.
         */
        rflag = flag ? Qtrue : Qfalse;
        pass  = rb_protect(ossl_pem_passwd_cb0, rflag, &status);
        if (status) {
            /* ignore an exception raised. */
            rb_set_errinfo(Qnil);
            return -1;
        }
        if (NIL_P(pass))
            return -1;
        len = RSTRING_LEN(pass);
        if (len > max_len) {
            rb_warning("password must not be longer than %d bytes", max_len);
            continue;
        }
        memcpy(buf, RSTRING_PTR(pass), len);
        break;
    }
    return (int)len;
}

/*
 * main module
 */
VALUE mOSSL;

/*
 * OpenSSLError < StandardError
 */
VALUE eOSSLError;

/*
 * Convert to DER string
 */
static ID ossl_s_to_der;

VALUE
ossl_to_der(VALUE obj)
{
    VALUE tmp;

    tmp = rb_funcall(obj, ossl_s_to_der, 0);
    StringValue(tmp);

    return tmp;
}

VALUE
ossl_to_der_if_possible(VALUE obj)
{
    if(rb_respond_to(obj, ossl_s_to_der))
        return ossl_to_der(obj);
    return obj;
}

/*
 * Errors
 */
static ID id_i_errors;

static void collect_errors_into(VALUE ary);

VALUE
ossl_make_error(VALUE exc, VALUE str)
{
    unsigned long e;
    const char *data;
    int flags;
    VALUE errors = rb_ary_new();

    if (NIL_P(str))
        str = rb_str_new(NULL, 0);

#ifdef HAVE_ERR_GET_ERROR_ALL
    e = ERR_peek_last_error_all(NULL, NULL, NULL, &data, &flags);
#else
    e = ERR_peek_last_error_line_data(NULL, NULL, &data, &flags);
#endif
    if (e) {
        const char *msg = ERR_reason_error_string(e);

        if (RSTRING_LEN(str)) rb_str_cat_cstr(str, ": ");
        rb_str_cat_cstr(str, msg ? msg : "(null)");
        if (flags & ERR_TXT_STRING && data)
            rb_str_catf(str, " (%s)", data);
        collect_errors_into(errors);
    }

    VALUE obj = rb_exc_new_str(exc, str);
    rb_ivar_set(obj, id_i_errors, errors);
    return obj;
}

void
ossl_raise(VALUE exc, const char *fmt, ...)
{
    va_list args;
    VALUE err;

    if (fmt) {
        va_start(args, fmt);
        err = rb_vsprintf(fmt, args);
        va_end(args);
    }
    else {
        err = Qnil;
    }

    rb_exc_raise(ossl_make_error(exc, err));
}

static void
collect_errors_into(VALUE ary)
{
    if (dOSSL == Qtrue || !NIL_P(ary)) {
        unsigned long e;
        const char *file, *data, *func, *lib, *reason;
        int line, flags;

#ifdef HAVE_ERR_GET_ERROR_ALL
        while ((e = ERR_get_error_all(&file, &line, &func, &data, &flags))) {
#else
        while ((e = ERR_get_error_line_data(&file, &line, &data, &flags))) {
            func = ERR_func_error_string(e);
#endif
            lib = ERR_lib_error_string(e);
            reason = ERR_reason_error_string(e);

            VALUE str = rb_sprintf("error:%08lX:%s:%s:%s", e, lib ? lib : "",
                                   func ? func : "", reason ? reason : "");
            if (flags & ERR_TXT_STRING) {
                if (!data)
                    data = "(null)";
                rb_str_catf(str, " (%s)", data);
            }

            if (dOSSL == Qtrue)
                rb_warn("error on stack: %"PRIsVALUE, str);
            if (!NIL_P(ary))
                rb_ary_push(ary, str);
        }
    }
    else {
        ERR_clear_error();
    }
}

void
ossl_clear_error(void)
{
    collect_errors_into(Qnil);
}

/*
 * call-seq:
 *    ossl_error.detailed_message(**) -> string
 *
 * Returns the exception message decorated with the captured \OpenSSL error
 * queue entries.
 */
static VALUE
osslerror_detailed_message(int argc, VALUE *argv, VALUE self)
{
    VALUE str;
#ifdef HAVE_RB_CALL_SUPER_KW
    // Ruby >= 3.2
    if (RTEST(rb_funcall(rb_eException, rb_intern("method_defined?"), 1,
                         ID2SYM(rb_intern("detailed_message")))))
        str = rb_call_super_kw(argc, argv, RB_PASS_CALLED_KEYWORDS);
    else
#endif
        str = rb_funcall(self, rb_intern("message"), 0);
    VALUE errors = rb_attr_get(self, id_i_errors);

    // OpenSSLError was not created by ossl_make_error()
    if (!RB_TYPE_P(errors, T_ARRAY))
        return str;

    str = rb_str_resurrect(str);
    rb_str_catf(str, "\nOpenSSL error queue reported %ld errors:",
                RARRAY_LEN(errors));
    for (long i = 0; i < RARRAY_LEN(errors); i++) {
        VALUE err = RARRAY_AREF(errors, i);
        rb_str_catf(str, "\n%"PRIsVALUE, err);
    }
    return str;
}

/*
 * call-seq:
 *   OpenSSL.errors -> [String...]
 *
 * Returns any remaining errors held in the \OpenSSL thread-local error queue
 * and clears the queue. This should normally return an empty array.
 *
 * This is intended for debugging Ruby/OpenSSL. If you see any errors here,
 * it likely indicates a bug in the extension. Please file an issue at
 * https://github.com/ruby/openssl.
 *
 * For debugging your program, OpenSSL.debug= may be useful.
 */
static VALUE
ossl_get_errors(VALUE _)
{
    VALUE ary;
    long e;

    ary = rb_ary_new();
    while ((e = ERR_get_error()) != 0){
        rb_ary_push(ary, rb_str_new2(ERR_error_string(e, NULL)));
    }

    return ary;
}

/*
 * Debug
 */
VALUE dOSSL;

/*
 * call-seq:
 *   OpenSSL.debug -> true | false
 *
 * Returns whether Ruby/OpenSSL's debug mode is currently enabled.
 */
static VALUE
ossl_debug_get(VALUE self)
{
    return dOSSL;
}

/*
 * call-seq:
 *   OpenSSL.debug = boolean
 *
 * Turns on or off debug mode. With debug mode, all errors added to the \OpenSSL
 * error queue will be printed to stderr.
 */
static VALUE
ossl_debug_set(VALUE self, VALUE val)
{
    dOSSL = RTEST(val) ? Qtrue : Qfalse;

    return val;
}

/*
 * call-seq:
 *   OpenSSL.fips_mode -> true | false
 *
 * Returns whether the FIPS mode is currently enabled.
 */
static VALUE
ossl_fips_mode_get(VALUE self)
{

#if OSSL_OPENSSL_PREREQ(3, 0, 0)
    VALUE enabled;
    enabled = EVP_default_properties_is_fips_enabled(NULL) ? Qtrue : Qfalse;
    return enabled;
#elif defined(OPENSSL_FIPS) || defined(OPENSSL_IS_AWSLC)
    VALUE enabled;
    enabled = FIPS_mode() ? Qtrue : Qfalse;
    return enabled;
#else
    return Qfalse;
#endif
}

/*
 * call-seq:
 *   OpenSSL.fips_mode = boolean
 *
 * Turns FIPS mode on or off. Turning on FIPS mode will obviously only have an
 * effect for FIPS-capable installations of the \OpenSSL library. Trying to do
 * so otherwise will result in an error.
 *
 * === Examples
 *   OpenSSL.fips_mode = true   # turn FIPS mode on
 *   OpenSSL.fips_mode = false  # and off again
 */
static VALUE
ossl_fips_mode_set(VALUE self, VALUE enabled)
{
#if OSSL_OPENSSL_PREREQ(3, 0, 0)
    if (RTEST(enabled)) {
        if (!EVP_default_properties_enable_fips(NULL, 1)) {
            ossl_raise(eOSSLError, "Turning on FIPS mode failed");
        }
    } else {
        if (!EVP_default_properties_enable_fips(NULL, 0)) {
            ossl_raise(eOSSLError, "Turning off FIPS mode failed");
        }
    }
    return enabled;
#elif 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 */
            ossl_raise(eOSSLError, "Turning on FIPS mode failed");
    } else {
        if(!FIPS_mode_set(0)) /* turning off twice is OK */
            ossl_raise(eOSSLError, "Turning off FIPS mode failed");
    }
    return enabled;
#else
    if (RTEST(enabled))
        ossl_raise(eOSSLError, "This version of OpenSSL does not support FIPS mode");
    return enabled;
#endif
}

/*
 * call-seq:
 *   OpenSSL.fixed_length_secure_compare(string, string) -> true or false
 *
 * Constant time memory comparison for fixed length strings, such as results
 * of \HMAC calculations.
 *
 * Returns +true+ if the strings are identical, +false+ if they are of the same
 * length but not identical. If the length is different, ArgumentError is
 * raised.
 */
static VALUE
ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
{
    const unsigned char *p1;
    const unsigned char *p2;
    long len1;
    long len2;

    StringValue(str1);
    StringValue(str2);

    p1 = (const unsigned char *)RSTRING_PTR(str1);
    p2 = (const unsigned char *)RSTRING_PTR(str2);
    len1 = RSTRING_LEN(str1);
    len2 = RSTRING_LEN(str2);

    if (len1 != len2) {
        ossl_raise(rb_eArgError, "inputs must be of equal length");
    }

    switch (CRYPTO_memcmp(p1, p2, len1)) {
      case 0: return Qtrue;
      default: return Qfalse;
    }
}

/*
 * OpenSSL provides \SSL, TLS and general purpose cryptography.  It wraps the
 * OpenSSL[https://www.openssl.org/] library.
 *
 * = Examples
 *
 * All examples assume you have loaded OpenSSL with:
 *
 *   require 'openssl'
 *
 * These examples build atop each other.  For example the key created in the
 * next is used in throughout these examples.
 *
 * == Keys
 *
 * === Creating a Key
 *
 * This example creates a 2048 bit RSA keypair and writes it to the current
 * directory.
 *
 *   key = OpenSSL::PKey::RSA.new 2048
 *
 *   File.write 'private_key.pem', key.private_to_pem
 *   File.write 'public_key.pem', key.public_to_pem
 *
 * === Exporting a Key
 *
 * Keys saved to disk without encryption are not secure as anyone who gets
 * ahold of the key may use it unless it is encrypted.  In order to securely
 * export a key you may export it with a password.
 *
 *   cipher = OpenSSL::Cipher.new 'aes-256-cbc'
 *   password = 'my secure password goes here'
 *
 *   key_secure = key.private_to_pem cipher, password
 *
 *   File.write 'private.secure.pem', key_secure
 *
 * OpenSSL::Cipher.ciphers returns a list of available ciphers.
 *
 * === Loading a Key
 *
 * A key can also be loaded from a file.
 *
 *   key2 = OpenSSL::PKey.read File.read 'private_key.pem'
 *   key2.public? # => true
 *   key2.private? # => true
 *
 * or
 *
 *   key3 = OpenSSL::PKey.read File.read 'public_key.pem'
 *   key3.public? # => true
 *   key3.private? # => false
 *
 * === Loading an Encrypted Key
 *
 * \OpenSSL will prompt you for your password when loading an encrypted key.
 * If you will not be able to type in the password you may provide it when
 * loading the key:
 *
 *   key4_pem = File.read 'private.secure.pem'
 *   password = 'my secure password goes here'
 *   key4 = OpenSSL::PKey.read key4_pem, password
 *
 * == RSA Encryption
 *
 * RSA provides encryption and decryption using the public and private keys.
 * You can use a variety of padding methods depending upon the intended use of
 * encrypted data.
 *
 * === Encryption & Decryption
 *
 * Asymmetric public/private key encryption is slow and victim to attack in
 * cases where it is used without padding or directly to encrypt larger chunks
 * of data. Typical use cases for RSA encryption involve "wrapping" a symmetric
 * key with the public key of the recipient who would "unwrap" that symmetric
 * key again using their private key.
 * The following illustrates a simplified example of such a key transport
 * scheme. It shouldn't be used in practice, though, standardized protocols
 * should always be preferred.
 *
 *   wrapped_key = key.public_encrypt key
 *
 * A symmetric key encrypted with the public key can only be decrypted with
 * the corresponding private key of the recipient.
 *
 *   original_key = key.private_decrypt wrapped_key
 *
 * By default PKCS#1 padding will be used, but it is also possible to use
 * other forms of padding, see PKey::RSA for further details.
 *
 * === Signatures
 *
 * Using "private_encrypt" to encrypt some data with the private key is
 * equivalent to applying a digital signature to the data. A verifying
 * party may validate the signature by comparing the result of decrypting
 * the signature with "public_decrypt" to the original data. However,
 * OpenSSL::PKey already has methods "sign" and "verify" that handle
 * digital signatures in a standardized way - "private_encrypt" and
 * "public_decrypt" shouldn't be used in practice.
 *
 * To sign a document, a cryptographically secure hash of the document is
 * computed first, which is then signed using the private key.
 *
 *   signature = key.sign 'SHA256', document
 *
 * To validate the signature, again a hash of the document is computed and
 * the signature is decrypted using the public key. The result is then
 * compared to the hash just computed, if they are equal the signature was
 * valid.
 *
 *   if key.verify 'SHA256', signature, document
 *     puts 'Valid'
 *   else
 *     puts 'Invalid'
 *   end
 *
 * == PBKDF2 Password-based Encryption
 *
 * If supported by the underlying \OpenSSL version used, Password-based
 * Encryption should use the features of PKCS5. If not supported or if
 * required by legacy applications, the older, less secure methods specified
 * in RFC 2898 are also supported (see below).
 *
 * PKCS5 supports PBKDF2 as it was specified in PKCS#5
 * v2.0[http://www.rsa.com/rsalabs/node.asp?id=2127]. It still uses a
 * password, a salt, and additionally a number of iterations that will
 * slow the key derivation process down. The slower this is, the more work
 * it requires being able to brute-force the resulting key.
 *
 * === Encryption
 *
 * The strategy is to first instantiate a Cipher for encryption, and
 * then to generate a random IV plus a key derived from the password
 * using PBKDF2. PKCS #5 v2.0 recommends at least 8 bytes for the salt,
 * the number of iterations largely depends on the hardware being used.
 *
 *   cipher = OpenSSL::Cipher.new 'aes-256-cbc'
 *   cipher.encrypt
 *   iv = cipher.random_iv
 *
 *   pwd = 'some hopefully not to easily guessable password'
 *   salt = OpenSSL::Random.random_bytes 16
 *   iter = 20000
 *   key_len = cipher.key_len
 *   digest = OpenSSL::Digest.new('SHA256')
 *
 *   key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
 *   cipher.key = key
 *
 *   Now encrypt the data:
 *
 *   encrypted = cipher.update document
 *   encrypted << cipher.final
 *
 * === Decryption
 *
 * Use the same steps as before to derive the symmetric AES key, this time
 * setting the Cipher up for decryption.
 *
 *   cipher = OpenSSL::Cipher.new 'aes-256-cbc'
 *   cipher.decrypt
 *   cipher.iv = iv # the one generated with #random_iv
 *
 *   pwd = 'some hopefully not to easily guessable password'
 *   salt = ... # the one generated above
 *   iter = 20000
 *   key_len = cipher.key_len
 *   digest = OpenSSL::Digest.new('SHA256')
 *
 *   key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
 *   cipher.key = key
 *
 *   Now decrypt the data:
 *
 *   decrypted = cipher.update encrypted
 *   decrypted << cipher.final
 *
 * == \X509 Certificates
 *
 * === Creating a Certificate
 *
 * This example creates a self-signed certificate using an RSA key and a SHA1
 * signature.
 *
 *   key = OpenSSL::PKey::RSA.new 2048
 *   name = OpenSSL::X509::Name.parse '/CN=nobody/DC=example'
 *
 *   cert = OpenSSL::X509::Certificate.new
 *   cert.version = 2
 *   cert.serial = 0
 *   cert.not_before = Time.now
 *   cert.not_after = Time.now + 3600
 *
 *   cert.public_key = key.public_key
 *   cert.subject = name
 *
 * === Certificate Extensions
 *
 * You can add extensions to the certificate with
 * OpenSSL::SSL::ExtensionFactory to indicate the purpose of the certificate.
 *
 *   extension_factory = OpenSSL::X509::ExtensionFactory.new nil, cert
 *
 *   cert.add_extension \
 *     extension_factory.create_extension('basicConstraints', 'CA:FALSE', true)
 *
 *   cert.add_extension \
 *     extension_factory.create_extension(
 *       'keyUsage', 'keyEncipherment,dataEncipherment,digitalSignature')
 *
 *   cert.add_extension \
 *     extension_factory.create_extension('subjectKeyIdentifier', 'hash')
 *
 * The list of supported extensions (and in some cases their possible values)
 * can be derived from the "objects.h" file in the \OpenSSL source code.
 *
 * === Signing a Certificate
 *
 * To sign a certificate set the issuer and use OpenSSL::X509::Certificate#sign
 * with a digest algorithm.  This creates a self-signed cert because we're using
 * the same name and key to sign the certificate as was used to create the
 * certificate.
 *
 *   cert.issuer = name
 *   cert.sign key, OpenSSL::Digest.new('SHA1')
 *
 *   open 'certificate.pem', 'w' do |io| io.write cert.to_pem end
 *
 * === Loading a Certificate
 *
 * Like a key, a cert can also be loaded from a file.
 *
 *   cert2 = OpenSSL::X509::Certificate.new File.read 'certificate.pem'
 *
 * === Verifying a Certificate
 *
 * Certificate#verify will return true when a certificate was signed with the
 * given public key.
 *
 *   raise 'certificate can not be verified' unless cert2.verify key
 *
 * == Certificate Authority
 *
 * A certificate authority (CA) is a trusted third party that allows you to
 * verify the ownership of unknown certificates.  The CA issues key signatures
 * that indicate it trusts the user of that key.  A user encountering the key
 * can verify the signature by using the CA's public key.
 *
 * === CA Key
 *
 * CA keys are valuable, so we encrypt and save it to disk and make sure it is
 * not readable by other users.
 *
 *   ca_key = OpenSSL::PKey::RSA.new 2048
 *   password = 'my secure password goes here'
 *
 *   cipher = 'aes-256-cbc'
 *
 *   open 'ca_key.pem', 'w', 0400 do |io|
 *     io.write ca_key.private_to_pem(cipher, password)
 *   end
 *
 * === CA Certificate
 *
 * A CA certificate is created the same way we created a certificate above, but
 * with different extensions.
 *
 *   ca_name = OpenSSL::X509::Name.parse '/CN=ca/DC=example'
 *
 *   ca_cert = OpenSSL::X509::Certificate.new
 *   ca_cert.serial = 0
 *   ca_cert.version = 2
 *   ca_cert.not_before = Time.now
 *   ca_cert.not_after = Time.now + 86400
 *
 *   ca_cert.public_key = ca_key.public_key
 *   ca_cert.subject = ca_name
 *   ca_cert.issuer = ca_name
 *
 *   extension_factory = OpenSSL::X509::ExtensionFactory.new
 *   extension_factory.subject_certificate = ca_cert
 *   extension_factory.issuer_certificate = ca_cert
 *
 *   ca_cert.add_extension \
 *     extension_factory.create_extension('subjectKeyIdentifier', 'hash')
 *
 * This extension indicates the CA's key may be used as a CA.
 *
 *   ca_cert.add_extension \
 *     extension_factory.create_extension('basicConstraints', 'CA:TRUE', true)
 *
 * This extension indicates the CA's key may be used to verify signatures on
 * both certificates and certificate revocations.
 *
 *   ca_cert.add_extension \
 *     extension_factory.create_extension(
 *       'keyUsage', 'cRLSign,keyCertSign', true)
 *
 * Root CA certificates are self-signed.
 *
 *   ca_cert.sign ca_key, OpenSSL::Digest.new('SHA1')
 *
 * The CA certificate is saved to disk so it may be distributed to all the
 * users of the keys this CA will sign.
 *
 *   open 'ca_cert.pem', 'w' do |io|
 *     io.write ca_cert.to_pem
 *   end
 *
 * === Certificate Signing Request
 *
 * The CA signs keys through a Certificate Signing Request (CSR).  The CSR
 * contains the information necessary to identify the key.
 *
 *   csr = OpenSSL::X509::Request.new
 *   csr.version = 0
 *   csr.subject = name
 *   csr.public_key = key.public_key
 *   csr.sign key, OpenSSL::Digest.new('SHA1')
 *
 * A CSR is saved to disk and sent to the CA for signing.
 *
 *   open 'csr.pem', 'w' do |io|
 *     io.write csr.to_pem
 *   end
 *
 * === Creating a Certificate from a CSR
 *
 * Upon receiving a CSR the CA will verify it before signing it.  A minimal
 * verification would be to check the CSR's signature.
 *
 *   csr = OpenSSL::X509::Request.new File.read 'csr.pem'
 *
 *   raise 'CSR can not be verified' unless csr.verify csr.public_key
 *
 * After verification a certificate is created, marked for various usages,
 * signed with the CA key and returned to the requester.
 *
 *   csr_cert = OpenSSL::X509::Certificate.new
 *   csr_cert.serial = 0
 *   csr_cert.version = 2
 *   csr_cert.not_before = Time.now
 *   csr_cert.not_after = Time.now + 600
 *
 *   csr_cert.subject = csr.subject
 *   csr_cert.public_key = csr.public_key
 *   csr_cert.issuer = ca_cert.subject
 *
 *   extension_factory = OpenSSL::X509::ExtensionFactory.new
 *   extension_factory.subject_certificate = csr_cert
 *   extension_factory.issuer_certificate = ca_cert
 *
 *   csr_cert.add_extension \
 *     extension_factory.create_extension('basicConstraints', 'CA:FALSE')
 *
 *   csr_cert.add_extension \
 *     extension_factory.create_extension(
 *       'keyUsage', 'keyEncipherment,dataEncipherment,digitalSignature')
 *
 *   csr_cert.add_extension \
 *     extension_factory.create_extension('subjectKeyIdentifier', 'hash')
 *
 *   csr_cert.sign ca_key, OpenSSL::Digest.new('SHA1')
 *
 *   open 'csr_cert.pem', 'w' do |io|
 *     io.write csr_cert.to_pem
 *   end
 *
 * == \SSL and TLS Connections
 *
 * Using our created key and certificate we can create an \SSL or TLS
 * connection. An OpenSSL::SSL::SSLContext is used to set up an \SSL session.
 *
 *   context = OpenSSL::SSL::SSLContext.new
 *
 * === \SSL Server
 *
 * An \SSL server requires the certificate and private key to communicate
 * securely with its clients:
 *
 *   context.cert = cert
 *   context.key = key
 *
 * Then create an OpenSSL::SSL::SSLServer with a TCP server socket and the
 * context.  Use the SSLServer like an ordinary TCP server.
 *
 *   require 'socket'
 *
 *   tcp_server = TCPServer.new 5000
 *   ssl_server = OpenSSL::SSL::SSLServer.new tcp_server, context
 *
 *   loop do
 *     ssl_connection = ssl_server.accept
 *
 *     data = ssl_connection.gets
 *
 *     response = "I got #{data.dump}"
 *     puts response
 *
 *     ssl_connection.puts "I got #{data.dump}"
 *     ssl_connection.close
 *   end
 *
 * === \SSL client
 *
 * An \SSL client is created with a TCP socket and the context.
 * OpenSSL::SSL::SSLSocket#connect must be called to initiate the \SSL handshake
 * and start encryption.  A key and certificate are not required for the client
 * socket.
 *
 * Note that OpenSSL::SSL::SSLSocket#close doesn't close the underlying socket
 * by default. Set OpenSSL::SSL::SSLSocket#sync_close to true if you want.
 *
 *   require 'socket'
 *
 *   tcp_socket = TCPSocket.new 'localhost', 5000
 *   ssl_client = OpenSSL::SSL::SSLSocket.new tcp_socket, context
 *   ssl_client.sync_close = true
 *   ssl_client.connect
 *
 *   ssl_client.puts "hello server!"
 *   puts ssl_client.gets
 *
 *   ssl_client.close # shutdown the TLS connection and close tcp_socket
 *
 * === Peer Verification
 *
 * An unverified \SSL connection does not provide much security.  For enhanced
 * security the client or server can verify the certificate of its peer.
 *
 * The client can be modified to verify the server's certificate against the
 * certificate authority's certificate:
 *
 *   context.ca_file = 'ca_cert.pem'
 *   context.verify_mode = OpenSSL::SSL::VERIFY_PEER
 *
 *   require 'socket'
 *
 *   tcp_socket = TCPSocket.new 'localhost', 5000
 *   ssl_client = OpenSSL::SSL::SSLSocket.new tcp_socket, context
 *   ssl_client.connect
 *
 *   ssl_client.puts "hello server!"
 *   puts ssl_client.gets
 *
 * If the server certificate is invalid or <tt>context.ca_file</tt> is not set
 * when verifying peers an OpenSSL::SSL::SSLError will be raised.
 *
 */
void
Init_openssl(void)
{
#ifdef HAVE_RB_EXT_RACTOR_SAFE
    rb_ext_ractor_safe(true);
#endif

#undef rb_intern
    /*
     * Init timezone info
     */
#if 0
    tzset();
#endif

    /*
     * Init all digests, ciphers
     */
    if (!OPENSSL_init_ssl(0, NULL))
        rb_raise(rb_eRuntimeError, "OPENSSL_init_ssl");

    /*
     * Init main module
     */
    rb_global_variable(&mOSSL);
    mOSSL = rb_define_module("OpenSSL");
    rb_define_singleton_method(mOSSL, "fixed_length_secure_compare", ossl_crypto_fixed_length_secure_compare, 2);

    /*
     * \OpenSSL library version string used to compile the Ruby/OpenSSL
     * extension. This may differ from the version used at runtime.
     */
    rb_define_const(mOSSL, "OPENSSL_VERSION",
                    rb_obj_freeze(rb_str_new_cstr(OPENSSL_VERSION_TEXT)));

    /*
     * \OpenSSL library version string currently used at runtime.
     */
    rb_define_const(
        mOSSL,
        "OPENSSL_LIBRARY_VERSION",
        rb_obj_freeze(rb_str_new_cstr(OpenSSL_version(OPENSSL_VERSION)))
    );

    /*
     * \OpenSSL library version number used to compile the Ruby/OpenSSL
     * extension. This may differ from the version used at runtime.
     *
     * The version number is encoded into a single integer value. The number
     * follows the format:
     *
     * [\OpenSSL 3.0.0 or later]
     *   <tt>0xMNN00PP0</tt> (major minor 00 patch 0)
     * [\OpenSSL 1.1.1 or earlier]
     *   <tt>0xMNNFFPPS</tt> (major minor fix patch status)
     * [LibreSSL]
     *   <tt>0x20000000</tt> (a fixed value)
     *
     * See also the man page OPENSSL_VERSION_NUMBER(3).
     */
    rb_define_const(mOSSL, "OPENSSL_VERSION_NUMBER", INT2NUM(OPENSSL_VERSION_NUMBER));

#if defined(LIBRESSL_VERSION_NUMBER)
    /*
     * LibreSSL library version number used to compile the Ruby/OpenSSL
     * extension. This may differ from the version used at runtime.
     *
     * This constant is only defined if the extension was compiled against
     * LibreSSL. The number follows the format:
     * <tt>0xMNNFF00f</tt> (major minor fix 00 status).
     *
     * See also the man page LIBRESSL_VERSION_NUMBER(3).
     */
    rb_define_const(mOSSL, "LIBRESSL_VERSION_NUMBER", INT2NUM(LIBRESSL_VERSION_NUMBER));
#endif

    /*
     * Boolean indicating whether the \OpenSSL library is FIPS-capable or not.
     * Always <tt>true</tt> for \OpenSSL 3.0 and later.
     *
     * This is obsolete and will be removed in the future.
     * See also OpenSSL.fips_mode.
     */
    rb_define_const(mOSSL, "OPENSSL_FIPS",
/* OpenSSL 3 is FIPS-capable even when it is installed without fips option */
#if OSSL_OPENSSL_PREREQ(3, 0, 0)
                    Qtrue
#elif defined(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
                   );

    rb_define_module_function(mOSSL, "fips_mode", ossl_fips_mode_get, 0);
    rb_define_module_function(mOSSL, "fips_mode=", ossl_fips_mode_set, 1);

    rb_global_variable(&eOSSLError);
    /*
     * Generic error class for OpenSSL. All error classes in this library
     * inherit from this class.
     *
     * This class indicates that an error was reported by the underlying
     * \OpenSSL library.
     */
    eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
    /*
     * \OpenSSL error queue entries captured at the time the exception was
     * raised. The same information is printed to stderr if OpenSSL.debug is
     * set to +true+.
     *
     * This is an array of zero or more strings, ordered from the oldest to the
     * newest. The format of the strings is not stable and may vary across
     * versions of \OpenSSL or versions of this Ruby extension.
     *
     * See also the man page ERR_get_error(3).
     */
    rb_attr(eOSSLError, rb_intern_const("errors"), 1, 0, 0);
    rb_define_method(eOSSLError, "detailed_message", osslerror_detailed_message, -1);

    /*
     * Init debug core
     */
    dOSSL = Qfalse;
    rb_global_variable(&dOSSL);

    rb_define_module_function(mOSSL, "debug", ossl_debug_get, 0);
    rb_define_module_function(mOSSL, "debug=", ossl_debug_set, 1);
    rb_define_module_function(mOSSL, "errors", ossl_get_errors, 0);

    /*
     * Get ID of to_der
     */
    ossl_s_to_der = rb_intern("to_der");
    id_i_errors = rb_intern("@errors");

    /*
     * Init components
     */
    Init_ossl_asn1();
    Init_ossl_bn();
    Init_ossl_cipher();
    Init_ossl_config();
    Init_ossl_digest();
    Init_ossl_engine();
    Init_ossl_hmac();
    Init_ossl_kdf();
    Init_ossl_ns_spki();
    Init_ossl_ocsp();
    Init_ossl_pkcs12();
    Init_ossl_pkcs7();
    Init_ossl_pkey();
    Init_ossl_provider();
    Init_ossl_rand();
    Init_ossl_ssl();
    Init_ossl_ts();
    Init_ossl_x509();
}


================================================
FILE: ext/openssl/ossl.h
================================================
/*
 * 'OpenSSL for Ruby' project
 * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
 * All rights reserved.
 */
/*
 * This program is licensed under the same licence as Ruby.
 * (See the file 'COPYING'.)
 */
#if !defined(_OSSL_H_)
#define _OSSL_H_

#include RUBY_EXTCONF_H

#include <assert.h>
#include <ruby.h>
#include <errno.h>
#include <ruby/io.h>
#include <ruby/thread.h>
#ifdef HAVE_RUBY_RACTOR_H
#include <ruby/ractor.h>
#else
#define RUBY_TYPED_FROZEN_SHAREABLE 0
#endif

#include <openssl/opensslv.h>

#include <openssl/err.h>
#include <openssl/asn1.h>
#include <openssl/x509v3.h>
#include <openssl/ssl.h>
#include <openssl/pkcs12.h>
#include <openssl/pkcs7.h>
#include <openssl/rand.h>
#include <openssl/conf.h>
#ifndef OPENSSL_NO_TS
  #include <openssl/ts.h>
#endif
#include <openssl/crypto.h>
#if !defined(OPENSSL_NO_OCSP)
#  include <openssl/ocsp.h>
#endif
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/dsa.h>
#include <openssl/evp.h>
#include <openssl/dh.h>
#include "openssl_missing.h"

#ifndef LIBRESSL_VERSION_NUMBER
# define OSSL_IS_LIBRESSL 0
# define OSSL_OPENSSL_PREREQ(maj, min, pat) \
      (OPENSSL_VERSION_NUMBER >= ((maj << 28) | (min << 20) | (pat << 12)))
# define OSSL_LIBRESSL_PREREQ(maj, min, pat) 0
#else
# define OSSL_IS_LIBRESSL 1
# define OSSL_OPENSSL_PREREQ(maj, min, pat) 0
# define OSSL_LIBRESSL_PREREQ(maj, min, pat) \
      (LIBRESSL_VERSION_NUMBER >= ((maj << 28) | (min << 20) | (pat << 12)))
#endif

#if OSSL_OPENSSL_PREREQ(3, 0, 0)
# define OSSL_3_const const
#else
# define OSSL_3_const /* const */
#endif

#if !defined(OPENSSL_NO_ENGINE) && !OSSL_OPENSSL_PREREQ(3, 0, 0)
# define OSSL_USE_ENGINE
#endif

#if OSSL_OPENSSL_PREREQ(3, 0, 0)
# define OSSL_USE_PROVIDER
# include <openssl/provider.h>
#endif

#if OSSL_OPENSSL_PREREQ(3, 0, 0)
# define OSSL_HAVE_IMMUTABLE_PKEY
#endif

/*
 * Common Module
 */
extern VALUE mOSSL;

/*
 * Common Error Class
 */
extern VALUE eOSSLError;

/*
 * CheckTypes
 */
#define OSSL_Check_Kind(obj, klass) do {\
    if (!rb_obj_is_kind_of((obj), (klass))) {\
        ossl_raise(rb_eTypeError, "wrong argument (%"PRIsVALUE")! (Expected kind of %"PRIsVALUE")",\
                   rb_obj_class(obj), (klass));\
    }\
} while (0)

/*
 * Type conversions
 */
#if !defined(NUM2UINT64T) /* in case Ruby starts to provide */
#  if SIZEOF_LONG == 8
#    define NUM2UINT64T(x) ((uint64_t)NUM2ULONG(x))
#  elif defined(HAVE_LONG_LONG) && SIZEOF_LONG_LONG == 8
#    define NUM2UINT64T(x) ((uint64_t)NUM2ULL(x))
#  else
#    error "unknown platform; no 64-bit width integer"
#  endif
#endif

/*
 * Data Conversion
 */
STACK_OF(X509) *ossl_x509_ary2sk(VALUE);
STACK_OF(X509) *ossl_protect_x509_ary2sk(VALUE,int*);
VALUE ossl_x509_sk2ary(const STACK_OF(X509) *certs);
VALUE ossl_x509crl_sk2ary(const STACK_OF(X509_CRL) *crl);
VALUE ossl_x509name_sk2ary(const STACK_OF(X509_NAME) *names);
VALUE ossl_buf2str(char *buf, int len);
VALUE ossl_str_new(const char *, long, int *);
#define ossl_str_adjust(str, p) \
do{\
    long newlen = (long)((p) - (unsigned char*)RSTRING_PTR(str));\
    assert(newlen <= RSTRING_LEN(str));\
    rb_str_set_len((str), newlen);\
}while(0)
/*
 * Convert binary string to hex string. The caller is responsible for
 * ensuring out has (2 * len) bytes of capacity.
 */
void ossl_bin2hex(const unsigned char *in, char *out, size_t len);

/*
 * Our default PEM callback
 */
/* Convert the argument to String and validate the length. Note this may raise. */
VALUE ossl_pem_passwd_value(VALUE);
/* Can be casted to pem_password_cb. If a password (String) is passed as the
 * "arbitrary data" (typically the last parameter of PEM_{read,write}_
 * functions), uses the value. If not, but a block is given, yields to it.
 * If not either, fallbacks to PEM_def_callback() which reads from stdin. */
int ossl_pem_passwd_cb(char *, int, int, void *);

/*
 * Clear BIO* with this in PEM/DER fallback scenarios to avoid decoding
 * errors piling up in OpenSSL::Errors
 */
#define OSSL_BIO_reset(bio) do { \
    (void)BIO_reset((bio)); \
    ossl_clear_error(); \
} while (0)

/*
 * ERRor messages
 */
PRINTF_ARGS(NORETURN(void ossl_raise(VALUE, const char *, ...)), 2, 3);
/* Make exception instance from str and OpenSSL error reason string. */
VALUE ossl_make_error(VALUE exc, VALUE str);
/* Clear OpenSSL error queue. If dOSSL is set, rb_warn() them. */
void ossl_clear_error(void);

/*
 * String to DER String
 */
VALUE ossl_to_der(VALUE);
VALUE ossl_to_der_if_possible(VALUE);

/*
 * Debug
 */
extern VALUE dOSSL;

#define OSSL_Debug(...) do { \
    if (dOSSL == Qtrue) { \
        fprintf(stderr, "OSSL_DEBUG: "); \
        fprintf(stderr, __VA_ARGS__); \
        fprintf(stderr, " [%s:%d]\n", __FILE__, __LINE__); \
    } \
} while (0)

/*
 * Include all parts
 */
#include "ossl_asn1.h"
#include "ossl_bio.h"
#include "ossl_bn.h"
#include "ossl_cipher.h"
#include "ossl_config.h"
#include "ossl_digest.h"
#include "ossl_engine.h"
#include "ossl_hmac.h"
#include "ossl_kdf.h"
#include "ossl_ns_spki.h"
#include "ossl_ocsp.h"
#include "ossl_pkcs12.h"
#include "ossl_pkcs7.h"
#include "ossl_pkey.h"
#include "ossl_provider.h"
#include "ossl_rand.h"
#include "ossl_ssl.h"
#include "ossl_ts.h"
#include "ossl_x509.h"

void Init_openssl(void);

#endif /* _OSSL_H_ */


================================================
FILE: ext/openssl/ossl_asn1.c
================================================
/*
 * 'OpenSSL for Ruby' team members
 * Copyright (C) 2003
 * All rights reserved.
 */
/*
 * This program is licensed under the same licence as Ruby.
 * (See the file 'COPYING'.)
 */
#include "ossl.h"

/********/
/*
 * ASN1 module
 */
#define ossl_asn1_get_value(o)           rb_attr_get((o),sivVALUE)
#define ossl_asn1_get_tag(o)             rb_attr_get((o),sivTAG)
#define ossl_asn1_get_tagging(o)         rb_attr_get((o),sivTAGGING)
#define ossl_asn1_get_tag_class(o)       rb_attr_get((o),sivTAG_CLASS)
#define ossl_asn1_get_indefinite_length(o) rb_attr_get((o),sivINDEFINITE_LENGTH)

#define ossl_asn1_set_value(o,v)           rb_ivar_set((o),sivVALUE,(v))
#define ossl_asn1_set_tag(o,v)             rb_ivar_set((o),sivTAG,(v))
#define ossl_asn1_set_tagging(o,v)         rb_ivar_set((o),sivTAGGING,(v))
#define ossl_asn1_set_tag_class(o,v)       rb_ivar_set((o),sivTAG_CLASS,(v))
#define ossl_asn1_set_indefinite_length(o,v) rb_ivar_set((o),sivINDEFINITE_LENGTH,(v))

VALUE mASN1;
static VALUE eASN1Error;

VALUE cASN1Data;
static VALUE cASN1Primitive;
static VALUE cASN1Constructive;

static VALUE cASN1EndOfContent;
static VALUE cASN1Boolean;                           /* BOOLEAN           */
static VALUE cASN1Integer, cASN1Enumerated;          /* INTEGER           */
static VALUE cASN1BitString;                         /* BIT STRING        */
static VALUE cASN1OctetString, cASN1UTF8String;      /* STRINGs           */
static VALUE cASN1NumericString, cASN1PrintableString;
static VALUE cASN1T61String, cASN1VideotexString;
static VALUE cASN1IA5String, cASN1GraphicString;
static VALUE cASN1ISO64String, cASN1GeneralString;
static VALUE cASN1UniversalString, cASN1BMPString;
static VALUE cASN1Null;                              /* NULL              */
static VALUE cASN1ObjectId;                          /* OBJECT IDENTIFIER */
static VALUE cASN1UTCTime, cASN1GeneralizedTime;     /* TIME              */
static VALUE cASN1Sequence, cASN1Set;                /* CONSTRUCTIVE      */

static VALUE sym_IMPLICIT, sym_EXPLICIT;
static VALUE sym_UNIVERSAL, sym_APPLICATION, sym_CONTEXT_SPECIFIC, sym_PRIVATE;
static ID sivVALUE, sivTAG, sivTAG_CLASS, sivTAGGING, sivINDEFINITE_LENGTH, sivUNUSED_BITS;
static ID id_each;

/*
 * DATE conversion
 */
static VALUE
time_utc_new(VALUE args)
{
    return rb_funcallv(rb_cTime, rb_intern("utc"), 6, (VALUE *)args);
}

static VALUE
time_utc_new_rescue(VALUE args, VALUE exc)
{
    rb_raise(eASN1Error, "invalid time");
}

VALUE
asn1time_to_time(const ASN1_TIME *time)
{
    struct tm tm;
    if (!ASN1_TIME_to_tm(time, &tm))
        ossl_raise(eASN1Error, "ASN1_TIME_to_tm");

    VALUE args[] = {
        INT2NUM(tm.tm_year + 1900),
        INT2NUM(tm.tm_mon + 1),
        INT2NUM(tm.tm_mday),
        INT2NUM(tm.tm_hour),
        INT2NUM(tm.tm_min),
        INT2NUM(tm.tm_sec),
    };
    return rb_rescue2(time_utc_new, (VALUE)args, time_utc_new_rescue, Qnil,
                      rb_eArgError, 0);
}

static VALUE
asn1time_to_time_i(VALUE arg)
{
    return asn1time_to_time((ASN1_TIME *)arg);
}

void
ossl_time_split(VALUE time, time_t *sec, int *days)
{
    VALUE num = rb_Integer(time);

    if (FIXNUM_P(num)) {
        time_t t = FIX2LONG(num);
        *sec = t % 86400;
        *days = rb_long2int(t / 86400);
    }
    else {
        *days = NUM2INT(rb_funcall(num, rb_intern("/"), 1, INT2FIX(86400)));
        *sec = NUM2TIMET(rb_funcall(num, rb_intern("%"), 1, INT2FIX(86400)));
    }
}

/*
 * STRING conversion
 */
VALUE
asn1str_to_str(const ASN1_STRING *str)
{
    return rb_str_new((const char *)ASN1_STRING_get0_data(str),
                      ASN1_STRING_length(str));
}

/*
 * ASN1_INTEGER conversions
 */
VALUE
asn1integer_to_num(const ASN1_INTEGER *ai)
{
    BIGNUM *bn;
    VALUE num;

    if (!ai) {
        ossl_raise(rb_eTypeError, "ASN1_INTEGER is NULL!");
    }

    num = ossl_bn_new(BN_value_one());
    bn = GetBNPtr(num);

    if (ASN1_STRING_type(ai) == V_ASN1_ENUMERATED)
        bn = ASN1_ENUMERATED_to_BN(ai, bn);
    else
        bn = ASN1_INTEGER_to_BN(ai, bn);

    if (!bn)
        ossl_raise(eOSSLError, NULL);

    return num;
}

ASN1_INTEGER *
num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai)
{
    BIGNUM *bn;

    if (NIL_P(obj))
        ossl_raise(rb_eTypeError, "Can't convert nil into Integer");

    bn = GetBNPtr(obj);

    if (!(ai = BN_to_ASN1_INTEGER(bn, ai)))
        ossl_raise(eOSSLError, NULL);

    return ai;
}

static VALUE
asn1integer_to_num_i(VALUE arg)
{
    return asn1integer_to_num((ASN1_INTEGER *)arg);
}

/*
 * ASN1_OBJECT conversions
 */
VALUE
ossl_asn1obj_to_string_oid(const ASN1_OBJECT *a1obj)
{
    VALUE str;
    int len;

    str = rb_usascii_str_new(NULL, 127);
    len = OBJ_obj2txt(RSTRING_PTR(str), RSTRING_LENINT(str), a1obj, 1);
    if (len <= 0 || len == INT_MAX)
        ossl_raise(eOSSLError, "OBJ_obj2txt");
    if (len > RSTRING_LEN(str)) {
        /* +1 is for the \0 terminator added by OBJ_obj2txt() */
        rb_str_resize(str, len + 1);
        len = OBJ_obj2txt(RSTRING_PTR(str), len + 1, a1obj, 1);
        if (len <= 0)
            ossl_raise(eOSSLError, "OBJ_obj2txt");
    }
    rb_str_set_len(str, len);
    return str;
}

VALUE
ossl_asn1obj_to_string(const ASN1_OBJECT *obj)
{
    int nid = OBJ_obj2nid(obj);
    if (nid != NID_undef)
        return rb_str_new_cstr(OBJ_nid2sn(nid));
    return ossl_asn1obj_to_string_oid(obj);
}

VALUE
ossl_asn1obj_to_string_long_name(const ASN1_OBJECT *obj)
{
    int nid = OBJ_obj2nid(obj);
    if (nid != NID_undef)
        return rb_str_new_cstr(OBJ_nid2ln(nid));
    return ossl_asn1obj_to_string_oid(obj);
}

/*
 * Ruby to ASN1 converters
 */
static ASN1_BOOLEAN
obj_to_asn1bool(VALUE obj)
{
    if (NIL_P(obj))
        ossl_raise(rb_eTypeError, "Can't convert nil into Boolean");

    return RTEST(obj) ? 0xff : 0x0;
}

static ASN1_INTEGER*
obj_to_asn1int(VALUE obj)
{
    return num_to_asn1integer(obj, NULL);
}

static ASN1_BIT_STRING*
obj_to_asn1bstr(VALUE obj, int unused_bits)
{
    ASN1_BIT_STRING *bstr;

    if (unused_bits < 0 || unused_bits > 7)
        ossl_raise(eASN1Error, "unused_bits for a bitstring value must be in "\
                   "the range 0 to 7");
    StringValue(obj);
    if (!(bstr = ASN1_BIT_STRING_new()))
        ossl_raise(eASN1Error, "ASN1_BIT_STRING_new");
    if (!ASN1_BIT_STRING_set1(bstr, (uint8_t *)RSTRING_PTR(obj),
                              RSTRING_LEN(obj), unused_bits))
        ossl_raise(eASN1Error, "ASN1_BIT_STRING_set1");

    return bstr;
}

static ASN1_STRING*
obj_to_asn1str(VALUE obj)
{
    ASN1_STRING *str;

    StringValue(obj);
    if(!(str = ASN1_STRING_new()))
        ossl_raise(eASN1Error, NULL);
    ASN1_STRING_set(str, RSTRING_PTR(obj), RSTRING_LENINT(obj));

    return str;
}

static ASN1_NULL*
obj_to_asn1null(VALUE obj)
{
    ASN1_NULL *null;

    if(!NIL_P(obj))
        ossl_raise(eASN1Error, "nil expected");
    if(!(null = ASN1_NULL_new()))
        ossl_raise(eASN1Error, NULL);

    return null;
}

ASN1_OBJECT *
ossl_to_asn1obj(VALUE obj)
{
    ASN1_OBJECT *a1obj;

    StringValueCStr(obj);
    a1obj = OBJ_txt2obj(RSTRING_PTR(obj), 0);
    if(!a1obj) a1obj = OBJ_txt2obj(RSTRING_PTR(obj), 1);
    if(!a1obj) ossl_raise(eASN1Error, "invalid OBJECT ID %"PRIsVALUE, obj);

    return a1obj;
}

static ASN1_UTCTIME *
obj_to_asn1utime(VALUE time)
{
    time_t sec;
    ASN1_UTCTIME *t;

    int off_days;

    ossl_time_split(time, &sec, &off_days);
    if (!(t = ASN1_UTCTIME_adj(NULL, sec, off_days, 0)))
        ossl_raise(eASN1Error, NULL);

    return t;
}

static ASN1_GENERALIZEDTIME *
obj_to_asn1gtime(VALUE time)
{
    time_t sec;
    ASN1_GENERALIZEDTIME *t;

    int off_days;

    ossl_time_split(time, &sec, &off_days);
    if (!(t = ASN1_GENERALIZEDTIME_adj(NULL, sec, off_days, 0)))
        ossl_raise(eASN1Error, NULL);

    return t;
}

static ASN1_STRING*
obj_to_asn1derstr(VALUE obj)
{
    ASN1_STRING *a1str;
    VALUE str;

    str = ossl_to_der(obj);
    if(!(a1str = ASN1_STRING_new()))
        ossl_raise(eASN1Error, NULL);
    ASN1_STRING_set(a1str, RSTRING_PTR(str), RSTRING_LENINT(str));

    return a1str;
}

/*
 * DER to Ruby converters
 */
static VALUE
decode_bool(unsigned char* der, long length)
{
    const unsigned char *p = der;

    if (length != 3)
        ossl_raise(eASN1Error, "invalid length for BOOLEAN");
    if (p[0] != 1 || p[1] != 1)
        ossl_raise(eASN1Error, "invalid BOOLEAN");

    return p[2] ? Qtrue : Qfalse;
}

static VALUE
decode_int(unsigned char* der, long length)
{
    ASN1_INTEGER *ai;
    const unsigned char *p;
    VALUE ret;
    int status = 0;

    p = der;
    if(!(ai = d2i_ASN1_INTEGER(NULL, &p, length)))
        ossl_raise(eASN1Error, NULL);
    ret = rb_protect(asn1integer_to_num_i,
                     (VALUE)ai, &status);
    ASN1_INTEGER_free(ai);
    if(status) rb_jump_tag(status);

    return ret;
}

static VALUE
decode_bstr(unsigned char* der, long length, int *unused_bits)
{
    ASN1_BIT_STRING *bstr;
    const unsigned char *p;
    size_t len;
    VALUE ret;
    int state;

    p = der;
    if (!(bstr = d2i_ASN1_BIT_STRING(NULL, &p, length)))
        ossl_raise(eASN1Error, "d2i_ASN1_BIT_STRING");
    if (!ASN1_BIT_STRING_get_length(bstr, &len, unused_bits)) {
        ASN1_BIT_STRING_free(bstr);
        ossl_raise(eASN1Error, "ASN1_BIT_STRING_get_length");
    }
    ret = ossl_str_new((const char *)ASN1_STRING_get0_data(bstr), len, &state);
    ASN1_BIT_STRING_free(bstr);
    if (state)
        rb_jump_tag(state);

    return ret;
}

static VALUE
decode_enum(unsigned char* der, long length)
{
    ASN1_ENUMERATED *ai;
    const unsigned char *p;
    VALUE ret;
    int status = 0;

    p = der;
    if(!(ai = d2i_ASN1_ENUMERATED(NULL, &p, length)))
        ossl_raise(eASN1Error, NULL);
    ret = rb_protect(asn1integer_to_num_i,
                     (VALUE)ai, &status);
    ASN1_ENUMERATED_free(ai);
    if(status) rb_jump_tag(status);

    return ret;
}

static VALUE
decode_null(unsigned char* der, long length)
{
    ASN1_NULL *null;
    const unsigned char *p;

    p = der;
    if(!(null = d2i_ASN1_NULL(NULL, &p, length)))
        ossl_raise(eASN1Error, NULL);
    ASN1_NULL_free(null);

    return Qnil;
}

VALUE
asn1obj_to_string_i(VALUE arg)
{
    return ossl_asn1obj_to_string((const ASN1_OBJECT *)arg);
}

static VALUE
decode_obj(unsigned char* der, long length)
{
    ASN1_OBJECT *obj;
    const unsigned char *p;
    VALUE ret;
    int state;

    p = der;
    if (!(obj = d2i_ASN1_OBJECT(NULL, &p, length)))
        ossl_raise(eASN1Error, "d2i_ASN1_OBJECT");
    ret = rb_protect(asn1obj_to_string_i, (VALUE)obj, &state);
    ASN1_OBJECT_free(obj);
    if (state)
        rb_jump_tag(state);
    return ret;
}

static VALUE
decode_time(unsigned char* der, long length)
{
    ASN1_TIME *time;
    const unsigned char *p;
    VALUE ret;
    int status = 0;

    p = der;
    if(!(time = d2i_ASN1_TIME(NULL, &p, length)))
        ossl_raise(eASN1Error, NULL);
    ret = rb_protect(asn1time_to_time_i,
                     (VALUE)time, &status);
    ASN1_TIME_free(time);
    if(status) rb_jump_tag(status);

    return ret;
}

static VALUE
decode_eoc(unsigned char *der, long length)
{
    if (length != 2 || !(der[0] == 0x00 && der[1] == 0x00))
        ossl_raise(eASN1Error, NULL);

    return rb_str_new("", 0);
}

/********/

typedef struct {
    const char *name;
    VALUE *klass;
} ossl_asn1_info_t;

static const ossl_asn1_info_t ossl_asn1_info[] = {
    { "EOC",               &cASN1EndOfContent,    },  /*  0 */
    { "BOOLEAN",           &cASN1Boolean,         },  /*  1 */
    { "INTEGER",           &cASN1Integer,         },  /*  2 */
    { "BIT_STRING",        &cASN1BitString,       },  /*  3 */
    { "OCTET_STRING",      &cASN1OctetString,     },  /*  4 */
    { "NULL",              &cASN1Null,            },  /*  5 */
    { "OBJECT",            &cASN1ObjectId,        },  /*  6 */
    { "OBJECT_DESCRIPTOR", NULL,                  },  /*  7 */
    { "EXTERNAL",          NULL,                  },  /*  8 */
    { "REAL",              NULL,                  },  /*  9 */
    { "ENUMERATED",        &cASN1Enumerated,      },  /* 10 */
    { "EMBEDDED_PDV",      NULL,                  },  /* 11 */
    { "UTF8STRING",        &cASN1UTF8String,      },  /* 12 */
    { "RELATIVE_OID",      NULL,                  },  /* 13 */
    { "[UNIVERSAL 14]",    NULL,                  },  /* 14 */
    { "[UNIVERSAL 15]",    NULL,                  },  /* 15 */
    { "SEQUENCE",          &cASN1Sequence,        },  /* 16 */
    { "SET",               &cASN1Set,             },  /* 17 */
    { "NUMERICSTRING",     &cASN1NumericString,   },  /* 18 */
    { "PRINTABLESTRING",   &cASN1PrintableString, },  /* 19 */
    { "T61STRING",         &cASN1T61String,       },  /* 20 */
    { "VIDEOTEXSTRING",    &cASN1VideotexString,  },  /* 21 */
    { "IA5STRING",         &cASN1IA5String,       },  /* 22 */
    { "UTCTIME",           &cASN1UTCTime,         },  /* 23 */
    { "GENERALIZEDTIME",   &cASN1GeneralizedTime, },  /* 24 */
    { "GRAPHICSTRING",     &cASN1GraphicString,   },  /* 25 */
    { "ISO64STRING",       &cASN1ISO64String,     },  /* 26 */
    { "GENERALSTRING",     &cASN1GeneralString,   },  /* 27 */
    { "UNIVERSALSTRING",   &cASN1UniversalString, },  /* 28 */
    { "CHARACTER_STRING",  NULL,                  },  /* 29 */
    { "BMPSTRING",         &cASN1BMPString,       },  /* 30 */
};

enum {ossl_asn1_info_size = (sizeof(ossl_asn1_info)/sizeof(ossl_asn1_info[0]))};

static VALUE class_tag_map;

static int ossl_asn1_default_tag(VALUE obj);

static ASN1_TYPE *
ossl_asn1_get_asn1type(VALUE obj)
{
    ASN1_TYPE *ret;
    VALUE value, rflag;
    void *ptr;
    typedef void free_func_type(void *);
    free_func_type *free_func;
    int tag;

    tag = ossl_asn1_default_tag(obj);
    value = ossl_asn1_get_value(obj);
    switch(tag){
      case V_ASN1_BOOLEAN:
        ptr = (void*)(VALUE)obj_to_asn1bool(value);
        free_func = NULL;
        break;
      case V_ASN1_INTEGER:         /* FALLTHROUGH */
      case V_ASN1_ENUMERATED:
        ptr = obj_to_asn1int(value);
        free_func = (free_func_type *)ASN1_INTEGER_free;
        break;
      case V_ASN1_BIT_STRING:
        rflag = rb_attr_get(obj, sivUNUSED_BITS);
        ptr = obj_to_asn1bstr(value, NUM2INT(rflag));
        free_func = (free_func_type *)ASN1_BIT_STRING_free;
        break;
      case V_ASN1_NULL:
        ptr = obj_to_asn1null(value);
        free_func = (free_func_type *)ASN1_NULL_free;
        break;
      case V_ASN1_OCTET_STRING:    /* FALLTHROUGH */
      case V_ASN1_UTF8STRING:      /* FALLTHROUGH */
      case V_ASN1_NUMERICSTRING:   /* FALLTHROUGH */
      case V_ASN1_PRINTABLESTRING: /* FALLTHROUGH */
      case V_ASN1_T61STRING:       /* FALLTHROUGH */
      case V_ASN1_VIDEOTEXSTRING:  /* FALLTHROUGH */
      case V_ASN1_IA5STRING:       /* FALLTHROUGH */
      case V_ASN1_GRAPHICSTRING:   /* FALLTHROUGH */
      case V_ASN1_ISO64STRING:     /* FALLTHROUGH */
      case V_ASN1_GENERALSTRING:   /* FALLTHROUGH */
      case V_ASN1_UNIVERSALSTRING: /* FALLTHROUGH */
      case V_ASN1_BMPSTRING:
        ptr = obj_to_asn1str(value);
        free_func = (free_func_type *)ASN1_STRING_free;
        break;
      case V_ASN1_OBJECT:
        ptr = ossl_to_asn1obj(value);
        free_func = (free_func_type *)ASN1_OBJECT_free;
        break;
      case V_ASN1_UTCTIME:
        ptr = obj_to_asn1utime(value);
        free_func = (free_func_type *)ASN1_TIME_free;
        break;
      case V_ASN1_GENERALIZEDTIME:
        ptr = obj_to_asn1gtime(value);
        free_func = (free_func_type *)ASN1_TIME_free;
        break;
      case V_ASN1_SET:             /* FALLTHROUGH */
      case V_ASN1_SEQUENCE:
        ptr = obj_to_asn1derstr(obj);
        free_func = (free_func_type *)ASN1_STRING_free;
        break;
      default:
        ossl_raise(eASN1Error, "unsupported ASN.1 type");
    }
    if(!(ret = OPENSSL_malloc(sizeof(ASN1_TYPE)))){
        if(free_func) free_func(ptr);
        ossl_raise(eASN1Error, "ASN1_TYPE alloc failure");
    }
    memset(ret, 0, sizeof(ASN1_TYPE));
    ASN1_TYPE_set(ret, tag, ptr);

    return ret;
}

static int
ossl_asn1_default_tag(VALUE obj)
{
    VALUE tmp_class, tag;

    tmp_class = CLASS_OF(obj);
    while (!NIL_P(tmp_class)) {
        tag = rb_hash_lookup(class_tag_map, tmp_class);
        if (tag != Qnil)
            return NUM2INT(tag);
        tmp_class = rb_class_superclass(tmp_class);
    }

    return -1;
}

static int
ossl_asn1_tag(VALUE obj)
{
    VALUE tag;

    tag = ossl_asn1_get_tag(obj);
    if(NIL_P(tag))
        ossl_raise(eASN1Error, "tag number not specified");

    return NUM2INT(tag);
}

static int
ossl_asn1_tag_class(VALUE obj)
{
    VALUE s;

    s = ossl_asn1_get_tag_class(obj);
    if (NIL_P(s) || s == sym_UNIVERSAL)
        return V_ASN1_UNIVERSAL;
    else if (s == sym_APPLICATION)
        return V_ASN1_APPLICATION;
    else if (s == sym_CONTEXT_SPECIFIC)
        return V_ASN1_CONTEXT_SPECIFIC;
    else if (s == sym_PRIVATE)
        return V_ASN1_PRIVATE;
    else
        ossl_raise(eASN1Error, "invalid tag class");
}

static VALUE
ossl_asn1_class2sym(int tc)
{
    if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
        return sym_PRIVATE;
    else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
        return sym_CONTEXT_SPECIFIC;
    else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
        return sym_APPLICATION;
    else
        return sym_UNIVERSAL;
}

/*
 * call-seq:
 *    OpenSSL::ASN1::ASN1Data.new(value, tag, tag_class) => ASN1Data
 *
 * _value_: Please have a look at Constructive and Primitive to see how Ruby
 * types are mapped to ASN.1 types and vice versa.
 *
 * _tag_: An Integer indicating the tag number.
 *
 * _tag_class_: A Symbol indicating the tag class. Please cf. ASN1 for
 * possible values.
 *
 * == Example
 *   asn1_int = OpenSSL::ASN1Data.new(42, 2, :UNIVERSAL) # => Same as OpenSSL::ASN1::Integer.new(42)
 *   tagged_int = OpenSSL::ASN1Data.new(42, 0, :CONTEXT_SPECIFIC) # implicitly 0-tagged INTEGER
 */
static VALUE
ossl_asn1data_initialize(VALUE self, VALUE value, VALUE tag, VALUE tag_class)
{
    if(!SYMBOL_P(tag_class))
        ossl_raise(eASN1Error, "invalid tag class");
    ossl_asn1_set_tag(self, tag);
    ossl_asn1_set_value(self, value);
    ossl_asn1_set_tag_class(self, tag_class);
    ossl_asn1_set_indefinite_length(self, Qfalse);

    return self;
}

static VALUE
to_der_internal(VALUE self, int constructed, int indef_len, VALUE body)
{
    int encoding = constructed ? indef_len ? 2 : 1 : 0;
    int tag_class = ossl_asn1_tag_class(self);
    int tag_number = ossl_asn1_tag(self);
    int default_tag_number = ossl_asn1_default_tag(self);
    int body_length, total_length;
    VALUE str;
    unsigned char *p;

    body_length = RSTRING_LENINT(body);
    if (ossl_asn1_get_tagging(self) == sym_EXPLICIT) {
        int inner_length, e_encoding = indef_len ? 2 : 1;

        if (default_tag_number == -1)
            ossl_raise(eASN1Error, "explicit tagging of unknown tag");

        inner_length = ASN1_object_size(encoding, body_length, default_tag_number);
        total_length = ASN1_object_size(e_encoding, inner_length, tag_number);
        str = rb_str_new(NULL, total_length);
        p = (unsigned char *)RSTRING_PTR(str);
        /* Put explicit tag */
        ASN1_put_object(&p, e_encoding, inner_length, tag_number, tag_class);
        /* Append inner object */
        ASN1_put_object(&p, encoding, body_length, default_tag_number, V_ASN1_UNIVERSAL);
        memcpy(p, RSTRING_PTR(body), body_length);
        p += body_length;
        if (indef_len) {
            ASN1_put_eoc(&p); /* For inner object */
            ASN1_put_eoc(&p); /* For wrapper object */
        }
    }
    else {
        total_length = ASN1_object_size(encoding, body_length, tag_number);
        str = rb_str_new(NULL, total_length);
        p = (unsigned char *)RSTRING_PTR(str);
        ASN1_put_object(&p, encoding, body_length, tag_number, tag_class);
        memcpy(p, RSTRING_PTR(body), body_length);
        p += body_length;
        if (indef_len)
            ASN1_put_eoc(&p);
    }
    assert(p - (unsigned char *)RSTRING_PTR(str) == total_length);
    return str;
}

static VALUE ossl_asn1prim_to_der(VALUE);
static VALUE ossl_asn1cons_to_der(VALUE);
/*
 * call-seq:
 *    asn1.to_der => DER-encoded String
 *
 * Encodes this ASN1Data into a DER-encoded String value. The result is
 * DER-encoded except for the possibility of indefinite length forms.
 * Indefinite length forms are not allowed in strict DER, so strictly speaking
 * the result of such an encoding would be a BER-encoding.
 */
static VALUE
ossl_asn1data_to_der(VALUE self)
{
    VALUE value = ossl_asn1_get_value(self);

    if (rb_obj_is_kind_of(value, rb_cArray))
        return ossl_asn1cons_to_der(self);
    else {
        if (RTEST(ossl_asn1_get_indefinite_length(self)))
            ossl_raise(eASN1Error, "indefinite length form cannot be used " \
                       "with primitive encoding");
        return ossl_asn1prim_to_der(self);
    }
}

static VALUE ossl_asn1_initialize(int argc, VALUE *argv, VALUE self);
static VALUE ossl_asn1_decode0(unsigned char **pp, long length, long *offset,
                               int depth, int yield, long *num_read);

static VALUE
int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag,
                           VALUE tc, long *num_read)
{
    VALUE value, asn1data;
    unsigned char *p;
    int flag = 0;

    p = *pp;

    if(tc == sym_UNIVERSAL && tag < ossl_asn1_info_size) {
        switch(tag){
          case V_ASN1_EOC:
            value = decode_eoc(p, hlen+length);
            break;
          case V_ASN1_BOOLEAN:
            value = decode_bool(p, hlen+length);
            break;
          case V_ASN1_INTEGER:
            value = decode_int(p, hlen+length);
            break;
          case V_ASN1_BIT_STRING:
            value = decode_bstr(p, hlen+length, &flag);
            break;
          case V_ASN1_NULL:
            value = decode_null(p, hlen+length);
            break;
          case V_ASN1_ENUMERATED:
            value = decode_enum(p, hlen+length);
            break;
          case V_ASN1_OBJECT:
            value = decode_obj(p, hlen+length);
            break;
          case V_ASN1_UTCTIME:           /* FALLTHROUGH */
          case V_ASN1_GENERALIZEDTIME:
            value = decode_time(p, hlen+length);
            break;
          default:
            /* use original value */
            p += hlen;
            value = rb_str_new((const char *)p, length);
            break;
        }
    }
    else {
        p += hlen;
        value = rb_str_new((const char *)p, length);
    }

    *pp += hlen + length;
    *num_read = hlen + length;

    if (tc == sym_UNIVERSAL &&
        tag < ossl_asn1_info_size && ossl_asn1_info[tag].klass) {
        VALUE klass = *ossl_asn1_info[tag].klass;
        VALUE args[4];
        args[0] = value;
        args[1] = INT2NUM(tag);
        args[2] = Qnil;
        args[3] = tc;
        asn1data = rb_obj_alloc(klass);
        ossl_asn1_initialize(4, args, asn1data);
        if(tag == V_ASN1_BIT_STRING){
            rb_ivar_set(asn1data, sivUNUSED_BITS, INT2NUM(flag));
        }
    }
    else {
        asn1data = rb_obj_alloc(cASN1Data);
        ossl_asn1data_initialize(asn1data, value, INT2NUM(tag), tc);
    }

    return asn1data;
}

static VALUE
int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length,
                           long *offset, int depth, int yield, int j,
                           int tag, VALUE tc, long *num_read)
{
    VALUE value, asn1data, ary;
    int indefinite;
    long available_len, off = *offset;

    indefinite = (j == 0x21);
    ary = rb_ary_new();

    available_len = indefinite ? max_len : length;
    while (available_len > 0) {
        long inner_read = 0;
        value = ossl_asn1_decode0(pp, available_len, &off, depth + 1, yield, &inner_read);
        *num_read += inner_read;
        available_len -= inner_read;

        if (indefinite) {
            if (ossl_asn1_tag(value) == V_ASN1_EOC &&
                ossl_asn1_get_tag_class(value) == sym_UNIVERSAL)
                break;
            if (available_len == 0)
                ossl_raise(eASN1Error, "EOC missing in indefinite length encoding");
        }
        rb_ary_push(ary, value);
    }

    if (tc == sym_UNIVERSAL) {
        VALUE args[4];
        if (tag == V_ASN1_SEQUENCE || tag == V_ASN1_SET)
            asn1data = rb_obj_alloc(*ossl_asn1_info[tag].klass);
        else
            asn1data = rb_obj_alloc(cASN1Constructive);
        args[0] = ary;
        args[1] = INT2NUM(tag);
        args[2] = Qnil;
        args[3] = tc;
        ossl_asn1_initialize(4, args, asn1data);
    }
    else {
        asn1data = rb_obj_alloc(cASN1Data);
        ossl_asn1data_initialize(asn1data, ary, INT2NUM(tag), tc);
    }

    if (indefinite)
        ossl_asn1_set_indefinite_length(asn1data, Qtrue);
    else
        ossl_asn1_set_indefinite_length(asn1data, Qfalse);

    *offset = off;
    return asn1data;
}

static VALUE
ossl_asn1_decode0(unsigned char **pp, long length, long *offset, int depth,
                  int yield, long *num_read)
{
    unsigned char *start, *p;
    const unsigned char *p0;
    long len = 0, inner_read = 0, off = *offset, hlen;
    int tag, tc, j;
    VALUE asn1data, tag_class;

    p = *pp;
    start = p;
    p0 = p;
    j = ASN1_get_object(&p0, &len, &tag, &tc, length);
    p = (unsigned char *)p0;
    if(j & 0x80) ossl_raise(eASN1Error, NULL);
    if(len > length) ossl_raise(eASN1Error, "value is too short");
    if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
        tag_class = sym_PRIVATE;
    else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
        tag_class = sym_CONTEXT_SPECIFIC;
    else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
        tag_class = sym_APPLICATION;
    else
        tag_class = sym_UNIVERSAL;

    hlen = p - start;

    if(yield) {
        VALUE arg = rb_ary_new();
        rb_ary_push(arg, LONG2NUM(depth));
        rb_ary_push(arg, LONG2NUM(*offset));
        rb_ary_push(arg, LONG2NUM(hlen));
        rb_ary_push(arg, LONG2NUM(len));
        rb_ary_push(arg, (j & V_ASN1_CONSTRUCTED) ? Qtrue : Qfalse);
        rb_ary_push(arg, ossl_asn1_class2sym(tc));
        rb_ary_push(arg, INT2NUM(tag));
        rb_yield(arg);
    }

    if(j & V_ASN1_CONSTRUCTED) {
        *pp += hlen;
        off += hlen;
        asn1data = int_ossl_asn1_decode0_cons(pp, length - hlen, len, &off, depth, yield, j, tag, tag_class, &inner_read);
        inner_read += hlen;
    }
    else {
        if ((j & 0x01) && (len == 0))
            ossl_raise(eASN1Error, "indefinite length for primitive value");
        asn1data = int_ossl_asn1_decode0_prim(pp, len, hlen, tag, tag_class, &inner_read);
        off += hlen + len;
    }
    if (num_read)
        *num_read = inner_read;
    if (len != 0 && inner_read != hlen + len) {
        ossl_raise(eASN1Error,
                   "Type mismatch. Bytes read: %ld Bytes available: %ld",
                   inner_read, hlen + len);
    }

    *offset = off;
    return asn1data;
}

static void
int_ossl_decode_sanity_check(long len, long read, long offset)
{
    if (len != 0 && (read != len || offset != len)) {
        ossl_raise(eASN1Error,
                   "Type mismatch. Total bytes read: %ld Bytes available: %ld Offset: %ld",
                   read, len, offset);
    }
}

/*
 * call-seq:
 *    OpenSSL::ASN1.traverse(asn1) -> nil
 *
 * If a block is given, it prints out each of the elements encountered.
 * Block parameters are (in that order):
 * * depth: The recursion depth, plus one with each constructed value being encountered (Integer)
 * * offset: Current byte offset (Integer)
 * * header length: Combined length in bytes of the Tag and Length headers. (Integer)
 * * length: The overall remaining length of the entire data (Integer)
 * * constructed: Whether this value is constructed or not (Boolean)
 * * tag_class: Current tag class (Symbol)
 * * tag: The current tag number (Integer)
 *
 * == Example
 *   der = File.binread('asn1data.der')
 *   OpenSSL::ASN1.traverse(der) do | depth, offset, header_len, length, constructed, tag_class, tag|
 *     puts "Depth: #{depth} Offset: #{offset} Length: #{length}"
 *     puts "Header length: #{header_len} Tag: #{tag} Tag class: #{tag_class} Constructed: #{constructed}"
 *   end
 */
static VALUE
ossl_asn1_traverse(VALUE self, VALUE obj)
{
    unsigned char *p;
    VALUE tmp;
    long len, read = 0, offset = 0;

    obj = ossl_to_der_if_possible(obj);
    tmp = rb_str_new4(StringValue(obj));
    p = (unsigned char *)RSTRING_PTR(tmp);
    len = RSTRING_LEN(tmp);
    ossl_asn1_decode0(&p, len, &offset, 0, 1, &read);
    RB_GC_GUARD(tmp);
    int_ossl_decode_sanity_check(len, read, offset);
    return Qnil;
}

/*
 * call-seq:
 *    OpenSSL::ASN1.decode(der) -> ASN1Data
 *
 * Decodes a BER- or DER-encoded value and creates an ASN1Data instance. _der_
 * may be a String or any object that features a +.to_der+ method transforming
 * it into a BER-/DER-encoded String+
 *
 * == Example
 *   der = File.binread('asn1data')
 *   asn1 = OpenSSL::ASN1.decode(der)
 */
static VALUE
ossl_asn1_decode(VALUE self, VALUE obj)
{
    VALUE ret;
    unsigned char *p;
    VALUE tmp;
    long len, read = 0, offset = 0;

    obj = ossl_to_der_if_possible(obj);
    tmp = rb_str_new4(StringValue(obj));
    p = (unsigned char *)RSTRING_PTR(tmp);
    len = RSTRING_LEN(tmp);
    ret = ossl_asn1_decode0(&p, len, &offset, 0, 0, &read);
    RB_GC_GUARD(tmp);
    int_ossl_decode_sanity_check(len, read, offset);
    return ret;
}

/*
 * call-seq:
 *    OpenSSL::ASN1.decode_all(der) -> Array of ASN1Data
 *
 * Similar to #decode with the difference that #decode expects one
 * distinct value represented in _der_. #decode_all on the contrary
 * decodes a sequence of sequential BER/DER values lined up in _der_
 * and returns them as an array.
 *
 * == Example
 *   ders = File.binread('asn1data_seq')
 *   asn1_ary = OpenSSL::ASN1.decode_all(ders)
 */
static VALUE
ossl_asn1_decode_all(VALUE self, VALUE obj)
{
    VALUE ary, val;
    unsigned char *p;
    long len, tmp_len = 0, read = 0, offset = 0;
    VALUE tmp;

    obj = ossl_to_der_if_possible(obj);
    tmp = rb_str_new4(StringValue(obj));
    p = (unsigned char *)RSTRING_PTR(tmp);
    len = RSTRING_LEN(tmp);
    tmp_len = len;
    ary = rb_ary_new();
    while (tmp_len > 0) {
        long tmp_read = 0;
        val = ossl_asn1_decode0(&p, tmp_len, &offset, 0, 0, &tmp_read);
        rb_ary_push(ary, val);
        read += tmp_read;
        tmp_len -= tmp_read;
    }
    RB_GC_GUARD(tmp);
    int_ossl_decode_sanity_check(len, read, offset);
    return ary;
}

/*
 * call-seq:
 *    OpenSSL::ASN1::Primitive.new(value [, tag, tagging, tag_class ]) => Primitive
 *
 * _value_: is mandatory.
 *
 * _tag_: optional, may be specified for tagged values. If no _tag_ is
 * specified, the UNIVERSAL tag corresponding to the Primitive sub-class
 * is used by default.
 *
 * _tagging_: may be used as an encoding hint to encode a value either
 * explicitly or implicitly, see ASN1 for possible values.
 *
 * _tag_class_: if _tag_ and _tagging_ are +nil+ then this is set to
 * +:UNIVERSAL+ by default. If either _tag_ or _tagging_ are set then
 * +:CONTEXT_SPECIFIC+ is used as the default. For possible values please
 * cf. ASN1.
 *
 * == Example
 *   int = OpenSSL::ASN1::Integer.new(42)
 *   zero_tagged_int = OpenSSL::ASN1::Integer.new(42, 0, :IMPLICIT)
 *   private_explicit_zero_tagged_int = OpenSSL::ASN1::Integer.new(42, 0, :EXPLICIT, :PRIVATE)
 */
static VALUE
ossl_asn1_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE value, tag, tagging, tag_class;
    int default_tag;

    rb_scan_args(argc, argv, "13", &value, &tag, &tagging, &tag_class);
    default_tag = ossl_asn1_default_tag(self);

    if (default_tag == -1 || argc > 1) {
        if(NIL_P(tag))
            ossl_raise(eASN1Error, "must specify tag number");
        if(!NIL_P(tagging) && !SYMBOL_P(tagging))
            ossl_raise(eASN1Error, "invalid tagging method");
        if(NIL_P(tag_class)) {
            if (NIL_P(tagging))
                tag_class = sym_UNIVERSAL;
            else
                tag_class = sym_CONTEXT_SPECIFIC;
        }
        if(!SYMBOL_P(tag_class))
            ossl_raise(eASN1Error, "invalid tag class");
    }
    else{
        tag = INT2NUM(default_tag);
        tagging = Qnil;
        tag_class = sym_UNIVERSAL;
    }
    ossl_asn1_set_tag(self, tag);
    ossl_asn1_set_value(self, value);
    ossl_asn1_set_tagging(self, tagging);
    ossl_asn1_set_tag_class(self, tag_class);
    ossl_asn1_set_indefinite_length(self, Qfalse);
    if (default_tag == V_ASN1_BIT_STRING)
        rb_ivar_set(self, sivUNUSED_BITS, INT2FIX(0));

    return self;
}

static VALUE
ossl_asn1eoc_initialize(VALUE self) {
    VALUE tag, tagging, tag_class, value;
    tag = INT2FIX(0);
    tagging = Qnil;
    tag_class = sym_UNIVERSAL;
    value = rb_str_new("", 0);
    ossl_asn1_set_tag(self, tag);
    ossl_asn1_set_value(self, value);
    ossl_asn1_set_tagging(self, tagging);
    ossl_asn1_set_tag_class(self, tag_class);
    ossl_asn1_set_indefinite_length(self, Qfalse);
    return self;
}

static VALUE
ossl_asn1eoc_to_der(VALUE self)
{
    return rb_str_new("\0\0", 2);
}

/*
 * call-seq:
 *    asn1.to_der => DER-encoded String
 *
 * See ASN1Data#to_der for details.
 */
static VALUE
ossl_asn1prim_to_der(VALUE self)
{
    ASN1_TYPE *asn1;
    long alllen, bodylen;
    unsigned char *p0, *p1;
    int j, tag, tc, state;
    VALUE str;

    if (ossl_asn1_default_tag(self) == -1) {
        str = ossl_asn1_get_value(self);
        return to_der_internal(self, 0, 0, StringValue(str));
    }

    asn1 = ossl_asn1_get_asn1type(self);
    alllen = i2d_ASN1_TYPE(asn1, NULL);
    if (alllen < 0) {
        ASN1_TYPE_free(asn1);
        ossl_raise(eASN1Error, "i2d_ASN1_TYPE");
    }
    str = ossl_str_new(NULL, alllen, &state);
    if (state) {
        ASN1_TYPE_free(asn1);
        rb_jump_tag(state);
    }
    p0 = p1 = (unsigned char *)RSTRING_PTR(str);
    if (i2d_ASN1_TYPE(asn1, &p0) < 0) {
        ASN1_TYPE_free(asn1);
        ossl_raise(eASN1Error, "i2d_ASN1_TYPE");
    }
    ASN1_TYPE_free(asn1);
    ossl_str_adjust(str, p0);

    /* Strip header since to_der_internal() wants only the payload */
    j = ASN1_get_object((const unsigned char **)&p1, &bodylen, &tag, &tc, alllen);
    if (j & 0x80)
        ossl_raise(eASN1Error, "ASN1_get_object"); /* should not happen */

    return to_der_internal(self, 0, 0, rb_str_drop_bytes(str, alllen - bodylen));
}

/*
 * call-seq:
 *    asn1.to_der => DER-encoded String
 *
 * See ASN1Data#to_der for details.
 */
static VALUE
ossl_asn1cons_to_der(VALUE self)
{
    VALUE ary, str;
    long i;
    int indef_len;

    indef_len = RTEST(ossl_asn1_get_indefinite_length(self));
    ary = rb_convert_type(ossl_asn1_get_value(self), T_ARRAY, "Array", "to_a");
    str = rb_str_new(NULL, 0);
    for (i = 0; i < RARRAY_LEN(ary); i++) {
        VALUE item = RARRAY_AREF(ary, i);

        if (indef_len && rb_obj_is_kind_of(item, cASN1EndOfContent)) {
            if (i != RARRAY_LEN(ary) - 1)
                ossl_raise(eASN1Error, "illegal EOC octets in value");

            /*
             * EOC is not really part of the content, but we required to add one
             * at the end in the past.
             */
            break;
        }

        item = ossl_to_der_if_possible(item);
        StringValue(item);
        rb_str_append(str, item);
    }

    return to_der_internal(self, 1, indef_len, str);
}

/*
 * call-seq:
 *    asn1_ary.each { |asn1| block } => asn1_ary
 *
 * Calls the given block once for each element in self, passing that element
 * as parameter _asn1_. If no block is given, an enumerator is returned
 * instead.
 *
 * == Example
 *   asn1_ary.each do |asn1|
 *     puts asn1
 *   end
 */
static VALUE
ossl_asn1cons_each(VALUE self)
{
    rb_block_call(ossl_asn1_get_value(self), id_each, 0, 0, 0, 0);

    return self;
}

/*
 * call-seq:
 *    OpenSSL::ASN1::ObjectId.register(object_id, short_name, long_name)
 *
 * This adds a new ObjectId to the internal tables. Where _object_id_ is the
 * numerical form, _short_name_ is the short name, and _long_name_ is the long
 * name.
 *
 * Returns +true+ if successful. Raises an OpenSSL::ASN1::ASN1Error if it fails.
 *
 */
static VALUE
ossl_asn1obj_s_register(VALUE self, VALUE oid, VALUE sn, VALUE ln)
{
    StringValueCStr(oid);
    StringValueCStr(sn);
    StringValueCStr(ln);

    if(!OBJ_create(RSTRING_PTR(oid), RSTRING_PTR(sn), RSTRING_PTR(ln)))
        ossl_raise(eASN1Error, NULL);

    return Qtrue;
}

/*
 * call-seq:
 *    oid.sn -> string
 *    oid.short_name -> string
 *
 * The short name of the ObjectId, as defined in <openssl/objects.h>.
 */
static VALUE
ossl_asn1obj_get_sn(VALUE self)
{
    VALUE val, ret = Qnil;
    int nid;

    val = ossl_asn1_get_value(self);
    if ((nid = OBJ_txt2nid(StringValueCStr(val))) != NID_undef)
        ret = rb_str_new2(OBJ_nid2sn(nid));

    return ret;
}

/*
 * call-seq:
 *    oid.ln -> string
 *    oid.long_name -> string
 *
 * The long name of the ObjectId, as defined in <openssl/objects.h>.
 */
static VALUE
ossl_asn1obj_get_ln(VALUE self)
{
    VALUE val, ret = Qnil;
    int nid;

    val = ossl_asn1_get_value(self);
    if ((nid = OBJ_txt2nid(StringValueCStr(val))) != NID_undef)
        ret = rb_str_new2(OBJ_nid2ln(nid));

    return ret;
}

static VALUE
asn1obj_get_oid_i(VALUE vobj)
{
    return ossl_asn1obj_to_string_oid((const ASN1_OBJECT *)vobj);
}

/*
 * call-seq:
 *    oid.oid -> string
 *
 * Returns a String representing the Object Identifier in the dot notation,
 * e.g. "1.2.3.4.5"
 */
static VALUE
ossl_asn1obj_get_oid(VALUE self)
{
    VALUE str;
    ASN1_OBJECT *a1obj;
    int state;

    a1obj = ossl_to_asn1obj(ossl_asn1_get_value(self));
    str = rb_protect(asn1obj_get_oid_i, (VALUE)a1obj, &state);
    ASN1_OBJECT_free(a1obj);
    if (state)
        rb_jump_tag(state);
    return str;
}

/*
 *  call-seq:
 *     oid == other_oid => true or false
 *
 *  Returns +true+ if _other_oid_ is the same as _oid_.
 */
static VALUE
ossl_asn1obj_eq(VALUE self, VALUE other)
{
    VALUE oid1, oid2;

    if (!rb_obj_is_kind_of(other, cASN1ObjectId))
        return Qfalse;

    oid1 = ossl_asn1obj_get_oid(self);
    oid2 = ossl_asn1obj_get_oid(other);
    return rb_str_equal(oid1, oid2);
}

#define OSSL_ASN1_IMPL_FACTORY_METHOD(klass) \
static VALUE ossl_asn1_##klass(int argc, VALUE *argv, VALUE self)\
{ return rb_funcall3(cASN1##klass, rb_intern("new"), argc, argv); }

OSSL_ASN1_IMPL_FACTORY_METHOD(Boolean)
OSSL_ASN1_IMPL_FACTORY_METHOD(Integer)
OSSL_ASN1_IMPL_FACTORY_METHOD(Enumerated)
OSSL_ASN1_IMPL_FACTORY_METHOD(BitString)
OSSL_ASN1_IMPL_FACTORY_METHOD(OctetString)
OSSL_ASN1_IMPL_FACTORY_METHOD(UTF8String)
OSSL_ASN1_IMPL_FACTORY_METHOD(NumericString)
OSSL_ASN1_IMPL_FACTORY_METHOD(PrintableString)
OSSL_ASN1_IMPL_FACTORY_METHOD(T61String)
OSSL_ASN1_IMPL_FACTORY_METHOD(VideotexString)
OSSL_ASN1_IMPL_FACTORY_METHOD(IA5String)
OSSL_ASN1_IMPL_FACTORY_METHOD(GraphicString)
OSSL_ASN1_IMPL_FACTORY_METHOD(ISO64String)
OSSL_ASN1_IMPL_FACTORY_METHOD(GeneralString)
OSSL_ASN1_IMPL_FACTORY_METHOD(UniversalString)
OSSL_ASN1_IMPL_FACTORY_METHOD(BMPString)
OSSL_ASN1_IMPL_FACTORY_METHOD(Null)
OSSL_ASN1_IMPL_FACTORY_METHOD(ObjectId)
OSSL_ASN1_IMPL_FACTORY_METHOD(UTCTime)
OSSL_ASN1_IMPL_FACTORY_METHOD(GeneralizedTime)
OSSL_ASN1_IMPL_FACTORY_METHOD(Sequence)
OSSL_ASN1_IMPL_FACTORY_METHOD(Set)
OSSL_ASN1_IMPL_FACTORY_METHOD(EndOfContent)

void
Init_ossl_asn1(void)
{
#undef rb_intern

    sym_UNIVERSAL = ID2SYM(rb_intern_const("UNIVERSAL"));
    sym_CONTEXT_SPECIFIC = ID2SYM(rb_intern_const("CONTEXT_SPECIFIC"));
    sym_APPLICATION = ID2SYM(rb_intern_const("APPLICATION"));
    sym_PRIVATE = ID2SYM(rb_intern_const("PRIVATE"));
    sym_EXPLICIT = ID2SYM(rb_intern_const("EXPLICIT"));
    sym_IMPLICIT = ID2SYM(rb_intern_const("IMPLICIT"));

    sivVALUE = rb_intern("@value");
    sivTAG = rb_intern("@tag");
    sivTAGGING = rb_intern("@tagging");
    sivTAG_CLASS = rb_intern("@tag_class");
    sivINDEFINITE_LENGTH = rb_intern("@indefinite_length");
    sivUNUSED_BITS = rb_intern("@unused_bits");

    /*
     * Document-module: OpenSSL::ASN1
     *
     * Abstract Syntax Notation One (or ASN.1) is a notation syntax to
     * describe data structures and is defined in ITU-T X.680. ASN.1 itself
     * does not mandate any encoding or parsing rules, but usually ASN.1 data
     * structures are encoded using the Distinguished Encoding Rules (DER) or
     * less often the Basic Encoding Rules (BER) described in ITU-T X.690. DER
     * and BER encodings are binary Tag-Length-Value (TLV) encodings that are
     * quite concise compared to other popular data description formats such
     * as XML, JSON etc.
     * ASN.1 data structures are very common in cryptographic applications,
     * e.g. X.509 public key certificates or certificate revocation lists
     * (CRLs) are all defined in ASN.1 and DER-encoded. ASN.1, DER and BER are
     * the building blocks of applied cryptography.
     * The ASN1 module provides the necessary classes that allow generation
     * of ASN.1 data structures and the methods to encode them using a DER
     * encoding. The decode method allows parsing arbitrary BER-/DER-encoded
     * data to a Ruby object that can then be modified and re-encoded at will.
     *
     * == ASN.1 class hierarchy
     *
     * The base class representing ASN.1 structures is ASN1Data. ASN1Data offers
     * attributes to read and set the _tag_, the _tag_class_ and finally the
     * _value_ of a particular ASN.1 item. Upon parsing, any tagged values
     * (implicit or explicit) will be represented by ASN1Data instances because
     * their "real type" can only be determined using out-of-band information
     * from the ASN.1 type declaration. Since this information is normally
     * known when encoding a type, all sub-classes of ASN1Data offer an
     * additional attribute _tagging_ that allows to encode a value implicitly
     * (+:IMPLICIT+) or explicitly (+:EXPLICIT+).
     *
     * === Constructive
     *
     * Constructive is, as its name implies, the base class for all
     * constructed encodings, i.e. those that consist of several values,
     * opposed to "primitive" encodings with just one single value. The value of
     * an Constructive is always an Array.
     *
     * ==== ASN1::Set and ASN1::Sequence
     *
     * The most common constructive encodings are SETs and SEQUENCEs, which is
     * why there are two sub-classes of Constructive representing each of
     * them.
     *
     * === Primitive
     *
     * This is the super class of all primitive values. Primitive
     * itself is not used when parsing ASN.1 data, all values are either
     * instances of a corresponding sub-class of Primitive or they are
     * instances of ASN1Data if the value was tagged implicitly or explicitly.
     * Please cf. Primitive documentation for details on sub-classes and
     * their respective mappings of ASN.1 data types to Ruby objects.
     *
     * == Possible values for _tagging_
     *
     * When constructing an ASN1Data object the ASN.1 type definition may
     * require certain elements to be either implicitly or explicitly tagged.
     * This can be achieved by setting the _tagging_ attribute manually for
     * sub-classes of ASN1Data. Use the symbol +:IMPLICIT+ for implicit
     * tagging and +:EXPLICIT+ if the element requires explicit tagging.
     *
     * == Possible values for _tag_class_
     *
     * It is possible to create arbitrary ASN1Data objects that also support
     * a PRIVATE or APPLICATION tag class. Possible values for the _tag_class_
     * attribute are:
     * * +:UNIVERSAL+ (the default for untagged values)
     * * +:CONTEXT_SPECIFIC+ (the default for tagged values)
     * * +:APPLICATION+
     * * +:PRIVATE+
     *
     * == Tag constants
     *
     * There is a constant defined for each universal tag:
     * * OpenSSL::ASN1::EOC (0)
     * * OpenSSL::ASN1::BOOLEAN (1)
     * * OpenSSL::ASN1::INTEGER (2)
     * * OpenSSL::ASN1::BIT_STRING (3)
     * * OpenSSL::ASN1::OCTET_STRING (4)
     * * OpenSSL::ASN1::NULL (5)
     * * OpenSSL::ASN1::OBJECT (6)
     * * OpenSSL::ASN1::ENUMERATED (10)
     * * OpenSSL::ASN1::UTF8STRING (12)
     * * OpenSSL::ASN1::SEQUENCE (16)
     * * OpenSSL::ASN1::SET (17)
     * * OpenSSL::ASN1::NUMERICSTRING (18)
     * * OpenSSL::ASN1::PRINTABLESTRING (19)
     * * OpenSSL::ASN1::T61STRING (20)
     * * OpenSSL::ASN1::VIDEOTEXSTRING (21)
     * * OpenSSL::ASN1::IA5STRING (22)
     * * OpenSSL::ASN1::UTCTIME (23)
     * * OpenSSL::ASN1::GENERALIZEDTIME (24)
     * * OpenSSL::ASN1::GRAPHICSTRING (25)
     * * OpenSSL::ASN1::ISO64STRING (26)
     * * OpenSSL::ASN1::GENERALSTRING (27)
     * * OpenSSL::ASN1::UNIVERSALSTRING (28)
     * * OpenSSL::ASN1::BMPSTRING (30)
     *
     * == UNIVERSAL_TAG_NAME constant
     *
     * An Array that stores the name of a given tag number. These names are
     * the same as the name of the tag constant that is additionally defined,
     * e.g. <tt>UNIVERSAL_TAG_NAME[2] = "INTEGER"</tt> and <tt>OpenSSL::ASN1::INTEGER = 2</tt>.
     *
     * == Example usage
     *
     * === Decoding and viewing a DER-encoded file
     *   require 'openssl'
     *   require 'pp'
     *   der = File.binread('data.der')
     *   asn1 = OpenSSL::ASN1.decode(der)
     *   pp der
     *
     * === Creating an ASN.1 structure and DER-encoding it
     *   require 'openssl'
     *   version = OpenSSL::ASN1::Integer.new(1)
     *   # Explicitly 0-tagged implies context-specific tag class
     *   serial = OpenSSL::ASN1::Integer.new(12345, 0, :EXPLICIT, :CONTEXT_SPECIFIC)
     *   name = OpenSSL::ASN1::PrintableString.new('Data 1')
     *   sequence = OpenSSL::ASN1::Sequence.new( [ version, serial, name ] )
     *   der = sequence.to_der
     */
    mASN1 = rb_define_module_under(mOSSL, "ASN1");

    /* Document-class: OpenSSL::ASN1::ASN1Error
     *
     * Generic error class for all errors raised in ASN1 and any of the
     * classes defined in it.
     */
    eASN1Error = rb_define_class_under(mASN1, "ASN1Error", eOSSLError);
    rb_define_module_function(mASN1, "traverse", ossl_asn1_traverse, 1);
    rb_define_module_function(mASN1, "decode", ossl_asn1_decode, 1);
    rb_define_module_function(mASN1, "decode_all", ossl_asn1_decode_all, 1);

    VALUE ary = rb_ary_new_capa(ossl_asn1_info_size);
    for (int i = 0; i < ossl_asn1_info_size; i++) {
        const char *name = ossl_asn1_info[i].name;
        if (name[0] == '[')
            continue;
        rb_define_const(mASN1, name, INT2NUM(i));
        rb_ary_store(ary, i, rb_obj_freeze(rb_str_new_cstr(name)));
    }
    rb_obj_freeze(ary);
    /*
     * Array storing tag names at the tag's index.
     */
    rb_define_const(mASN1, "UNIVERSAL_TAG_NAME", ary);

    /* Document-class: OpenSSL::ASN1::ASN1Data
     *
     * The top-level class representing any ASN.1 object. When parsed by
     * ASN1.decode, tagged values are always represented by an instance
     * of ASN1Data.
     *
     * == The role of ASN1Data for parsing tagged values
     *
     * When encoding an ASN.1 type it is inherently clear what original
     * type (e.g. INTEGER, OCTET STRING etc.) this value has, regardless
     * of its tagging.
     * But opposed to the time an ASN.1 type is to be encoded, when parsing
     * them it is not possible to deduce the "real type" of tagged
     * values. This is why tagged values are generally parsed into ASN1Data
     * instances, but with a different outcome for implicit and explicit
     * tagging.
     *
     * === Example of a parsed implicitly tagged value
     *
     * An implicitly 1-tagged INTEGER value will be parsed as an
     * ASN1Data with
     * * _tag_ equal to 1
     * * _tag_class_ equal to +:CONTEXT_SPECIFIC+
     * * _value_ equal to a String that carries the raw encoding
     *   of the INTEGER.
     * This implies that a subsequent decoding step is required to
     * completely decode implicitly tagged values.
     *
     * === Example of a parsed explicitly tagged value
     *
     * An explicitly 1-tagged INTEGER value will be parsed as an
     * ASN1Data with
     * * _tag_ equal to 1
     * * _tag_class_ equal to +:CONTEXT_SPECIFIC+
     * * _value_ equal to an Array with one single element, an
     *   instance of OpenSSL::ASN1::Integer, i.e. the inner element
     *   is the non-tagged primitive value, and the tagging is represented
     *   in the outer ASN1Data
     *
     * == Example - Decoding an implicitly tagged INTEGER
     *   int = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT) # implicit 0-tagged
     *   seq = OpenSSL::ASN1::Sequence.new( [int] )
     *   der = seq.to_der
     *   asn1 = OpenSSL::ASN1.decode(der)
     *   # pp asn1 => #<OpenSSL::ASN1::Sequence:0x87326e0
     *   #              @indefinite_length=false,
     *   #              @tag=16,
     *   #              @tag_class=:UNIVERSAL,
     *   #              @tagging=nil,
     *   #              @value=
     *   #                [#<OpenSSL::ASN1::ASN1Data:0x87326f4
     *   #                   @indefinite_length=false,
     *   #                   @tag=0,
     *   #                   @tag_class=:CONTEXT_SPECIFIC,
     *   #                   @value="\x01">]>
     *   raw_int = asn1.value[0]
     *   # manually rewrite tag and tag class to make it an UNIVERSAL value
     *   raw_int.tag = OpenSSL::ASN1::INTEGER
     *   raw_int.tag_class = :UNIVERSAL
     *   int2 = OpenSSL::ASN1.decode(raw_int)
     *   puts int2.value # => 1
     *
     * == Example - Decoding an explicitly tagged INTEGER
     *   int = OpenSSL::ASN1::Integer.new(1, 0, :EXPLICIT) # explicit 0-tagged
     *   seq = OpenSSL::ASN1::Sequence.new( [int] )
     *   der = seq.to_der
     *   asn1 = OpenSSL::ASN1.decode(der)
     *   # pp asn1 => #<OpenSSL::ASN1::Sequence:0x87326e0
     *   #              @indefinite_length=false,
     *   #              @tag=16,
     *   #              @tag_class=:UNIVERSAL,
     *   #              @tagging=nil,
     *   #              @value=
     *   #                [#<OpenSSL::ASN1::ASN1Data:0x87326f4
     *   #                   @indefinite_length=false,
     *   #                   @tag=0,
     *   #                   @tag_class=:CONTEXT_SPECIFIC,
     *   #                   @value=
     *   #                     [#<OpenSSL::ASN1::Integer:0x85bf308
     *   #                        @indefinite_length=false,
     *   #                        @tag=2,
     *   #                        @tag_class=:UNIVERSAL
     *   #                        @tagging=nil,
     *   #                        @value=1>]>]>
     *   int2 = asn1.value[0].value[0]
     *   puts int2.value # => 1
     */
    cASN1Data = rb_define_class_under(mASN1, "ASN1Data", rb_cObject);
    /*
     * Carries the value of a ASN.1 type.
     * Please confer Constructive and Primitive for the mappings between
     * ASN.1 data types and Ruby classes.
     */
    rb_attr(cASN1Data, rb_intern("value"), 1, 1, 0);
    /*
     * An Integer representing the tag number of this ASN1Data. Never +nil+.
     */
    rb_attr(cASN1Data, rb_intern("tag"), 1, 1, 0);
    /*
     * A Symbol representing the tag class of this ASN1Data. Never +nil+.
     * See ASN1Data for possible values.
     */
    rb_attr(cASN1Data, rb_intern("tag_class"), 1, 1, 0);
    /*
     * Never +nil+. A boolean value indicating whether the encoding uses
     * indefinite length (in the case of parsing) or whether an indefinite
     * length form shall be used (in the encoding case).
     * In DER, every value uses definite length form. But in scenarios where
     * large amounts of data need to be transferred it might be desirable to
     * have some kind of streaming support available.
     * For example, huge OCTET STRINGs are preferably sent in smaller-sized
     * chunks, each at a time.
     * This is possible in BER by setting the length bytes of an encoding
     * to zero and by this indicating that the following value will be
     * sent in chunks. Indefinite length encodings are always constructed.
     * The end of such a stream of chunks is indicated by sending a EOC
     * (End of Content) tag. SETs and SEQUENCEs may use an indefinite length
     * encoding, but also primitive types such as e.g. OCTET STRINGS or
     * BIT STRINGS may leverage this functionality (cf. ITU-T X.690).
     */
    rb_attr(cASN1Data, rb_intern("indefinite_length"), 1, 1, 0);
    rb_define_alias(cASN1Data, "infinite_length", "indefinite_length");
    rb_define_alias(cASN1Data, "infinite_length=", "indefinite_length=");
    rb_define_method(cASN1Data, "initialize", ossl_asn1data_initialize, 3);
    rb_define_method(cASN1Data, "to_der", ossl_asn1data_to_der, 0);

    /* Document-class: OpenSSL::ASN1::Primitive
     *
     * The parent class for all primitive encodings. Attributes are the same as
     * for ASN1Data, with the addition of _tagging_.
     * Primitive values can never be encoded with indefinite length form, thus
     * it is not possible to set the _indefinite_length_ attribute for Primitive
     * and its sub-classes.
     *
     * == Primitive sub-classes and their mapping to Ruby classes
     * * OpenSSL::ASN1::EndOfContent    <=> _value_ is always +nil+
     * * OpenSSL::ASN1::Boolean         <=> _value_ is +true+ or +false+
     * * OpenSSL::ASN1::Integer         <=> _value_ is an OpenSSL::BN
     * * OpenSSL::ASN1::BitString       <=> _value_ is a String
     * * OpenSSL::ASN1::OctetString     <=> _value_ is a String
     * * OpenSSL::ASN1::Null            <=> _value_ is always +nil+
     * * OpenSSL::ASN1::Object          <=> _value_ is a String
     * * OpenSSL::ASN1::Enumerated      <=> _value_ is an OpenSSL::BN
     * * OpenSSL::ASN1::UTF8String      <=> _value_ is a String
     * * OpenSSL::ASN1::NumericString   <=> _value_ is a String
     * * OpenSSL::ASN1::PrintableString <=> _value_ is a String
     * * OpenSSL::ASN1::T61String       <=> _value_ is a String
     * * OpenSSL::ASN1::VideotexString  <=> _value_ is a String
     * * OpenSSL::ASN1::IA5String       <=> _value_ is a String
     * * OpenSSL::ASN1::UTCTime         <=> _value_ is a Time
     * * OpenSSL::ASN1::GeneralizedTime <=> _value_ is a Time
     * * OpenSSL::ASN1::GraphicString   <=> _value_ is a String
     * * OpenSSL::ASN1::ISO64String     <=> _value_ is a String
     * * OpenSSL::ASN1::GeneralString   <=> _value_ is a String
     * * OpenSSL::ASN1::UniversalString <=> _value_ is a String
     * * OpenSSL::ASN1::BMPString       <=> _value_ is a String
     *
     * == OpenSSL::ASN1::BitString
     *
     * === Additional attributes
     * _unused_bits_: if the underlying BIT STRING's
     * length is a multiple of 8 then _unused_bits_ is 0. Otherwise
     * _unused_bits_ indicates the number of bits that are to be ignored in
     * the final octet of the BitString's _value_.
     *
     * == OpenSSL::ASN1::ObjectId
     *
     * NOTE: While OpenSSL::ASN1::ObjectId.new will allocate a new ObjectId,
     * it is not typically allocated this way, but rather that are received from
     * parsed ASN1 encodings.
     *
     * === Additional attributes
     * * _sn_: the short name as defined in <openssl/objects.h>.
     * * _ln_: the long name as defined in <openssl/objects.h>.
     * * _oid_: the object identifier as a String, e.g. "1.2.3.4.5"
     * * _short_name_: alias for _sn_.
     * * _long_name_: alias for _ln_.
     *
     * == Examples
     * With the Exception of OpenSSL::ASN1::EndOfContent, each Primitive class
     * constructor takes at least one parameter, the _value_.
     *
     * === Creating EndOfContent
     *   eoc = OpenSSL::ASN1::EndOfContent.new
     *
     * === Creating any other Primitive
     *   prim = <class>.new(value) # <class> being one of the sub-classes except EndOfContent
     *   prim_zero_tagged_implicit = <class>.new(value, 0, :IMPLICIT)
     *   prim_zero_tagged_explicit = <class>.new(value, 0, :EXPLICIT)
     */
    cASN1Primitive = rb_define_class_under(mASN1, "Primitive", cASN1Data);
    /*
     * May be used as a hint for encoding a value either implicitly or
     * explicitly by setting it either to +:IMPLICIT+ or to +:EXPLICIT+.
     * _tagging_ is not set when a ASN.1 structure is parsed using
     * OpenSSL::ASN1.decode.
     */
    rb_attr(cASN1Primitive, rb_intern("tagging"), 1, 1, Qtrue);
    rb_undef_method(cASN1Primitive, "indefinite_length=");
    rb_undef_method(cASN1Primitive, "infinite_length=");
    rb_define_method(cASN1Primitive, "initialize", ossl_asn1_initialize, -1);
    rb_define_method(cASN1Primitive, "to_der", ossl_asn1prim_to_der, 0);

    /* Document-class: OpenSSL::ASN1::Constructive
     *
     * The parent class for all constructed encodings. The _value_ attribute
     * of a Constructive is always an Array. Attributes are the same as
     * for ASN1Data, with the addition of _tagging_.
     *
     * == SET and SEQUENCE
     *
     * Most constructed encodings come in the form of a SET or a SEQUENCE.
     * These encodings are represented by one of the two sub-classes of
     * Constructive:
     * * OpenSSL::ASN1::Set
     * * OpenSSL::ASN1::Sequence
     * Please note that tagged sequences and sets are still parsed as
     * instances of ASN1Data. Find further details on tagged values
     * there.
     *
     * === Example - constructing a SEQUENCE
     *   int = OpenSSL::ASN1::Integer.new(1)
     *   str = OpenSSL::ASN1::PrintableString.new('abc')
     *   sequence = OpenSSL::ASN1::Sequence.new( [ int, str ] )
     *
     * === Example - constructing a SET
     *   int = OpenSSL::ASN1::Integer.new(1)
     *   str = OpenSSL::ASN1::PrintableString.new('abc')
     *   set = OpenSSL::ASN1::Set.new( [ int, str ] )
     */
    cASN1Constructive = rb_define_class_under(mASN1,"Constructive", cASN1Data);
    rb_include_module(cASN1Constructive, rb_mEnumerable);
    /*
     * May be used as a hint for encoding a value either implicitly or
     * explicitly by setting it either to +:IMPLICIT+ or to +:EXPLICIT+.
     * _tagging_ is not set when a ASN.1 structure is parsed using
     * OpenSSL::ASN1.decode.
     */
    rb_attr(cASN1Constructive, rb_intern("tagging"), 1, 1, Qtrue);
    rb_define_method(cASN1Constructive, "initialize", ossl_asn1_initialize, -1);
    rb_define_method(cASN1Constructive, "to_der", ossl_asn1cons_to_der, 0);
    rb_define_method(cASN1Constructive, "each", ossl_asn1cons_each, 0);

#define OSSL_ASN1_DEFINE_CLASS(name, super) \
do{\
    cASN1##name = rb_define_class_under(mASN1, #name, cASN1##super);\
    rb_define_module_function(mASN1, #name, ossl_asn1_##name, -1);\
}while(0)

    OSSL_ASN1_DEFINE_CLASS(Boolean, Primitive);
    OSSL_ASN1_DEFINE_CLASS(Integer, Primitive);
    OSSL_ASN1_DEFINE_CLASS(Enumerated, Primitive);
    OSSL_ASN1_DEFINE_CLASS(BitString, Primitive);
    OSSL_ASN1_DEFINE_CLASS(OctetString, Primitive);
    OSSL_ASN1_DEFINE_CLASS(UTF8String, Primitive);
    OSSL_ASN1_DEFINE_CLASS(NumericString, Primitive);
    OSSL_ASN1_DEFINE_CLASS(PrintableString, Primitive);
    OSSL_ASN1_DEFINE_CLASS(T61String, Primitive);
    OSSL_ASN1_DEFINE_CLASS(VideotexString, Primitive);
    OSSL_ASN1_DEFINE_CLASS(IA5String, Primitive);
    OSSL_ASN1_DEFINE_CLASS(GraphicString, Primitive);
    OSSL_ASN1_DEFINE_CLASS(ISO64String, Primitive);
    OSSL_ASN1_DEFINE_CLASS(GeneralString, Primitive);
    OSSL_ASN1_DEFINE_CLASS(UniversalString, Primitive);
    OSSL_ASN1_DEFINE_CLASS(BMPString, Primitive);
    OSSL_ASN1_DEFINE_CLASS(Null, Primitive);
    OSSL_ASN1_DEFINE_CLASS(ObjectId, Primitive);
    OSSL_ASN1_DEFINE_CLASS(UTCTime, Primitive);
    OSSL_ASN1_DEFINE_CLASS(GeneralizedTime, Primitive);

    OSSL_ASN1_DEFINE_CLASS(Sequence, Constructive);
    OSSL_ASN1_DEFINE_CLASS(Set, Constructive);

    OSSL_ASN1_DEFINE_CLASS(EndOfContent, Data);


    /* Document-class: OpenSSL::ASN1::ObjectId
     *
     * Represents the primitive object id for OpenSSL::ASN1
     */
#if 0
    cASN1ObjectId = rb_define_class_under(mASN1, "ObjectId", cASN1Primitive);  /* let rdoc know */
#endif
    rb_define_singleton_method(cASN1ObjectId, "register", ossl_asn1obj_s_register, 3);
    rb_define_method(cASN1ObjectId, "sn", ossl_asn1obj_get_sn, 0);
    rb_define_method(cASN1ObjectId, "ln", ossl_asn1obj_get_ln, 0);
    rb_define_method(cASN1ObjectId, "oid", ossl_asn1obj_get_oid, 0);
    rb_define_alias(cASN1ObjectId, "short_name", "sn");
    rb_define_alias(cASN1ObjectId, "long_name", "ln");
    rb_define_method(cASN1ObjectId, "==", ossl_asn1obj_eq, 1);
    rb_attr(cASN1BitString, rb_intern("unused_bits"), 1, 1, 0);

    rb_define_method(cASN1EndOfContent, "initialize", ossl_asn1eoc_initialize, 0);
    rb_define_method(cASN1EndOfContent, "to_der", ossl_asn1eoc_to_der, 0);

    class_tag_map = rb_hash_new();
    rb_gc_register_mark_object(class_tag_map);
    rb_hash_aset(class_tag_map, cASN1EndOfContent, INT2NUM(V_ASN1_EOC));
    rb_hash_aset(class_tag_map, cASN1Boolean, INT2NUM(V_ASN1_BOOLEAN));
    rb_hash_aset(class_tag_map, cASN1Integer, INT2NUM(V_ASN1_INTEGER));
    rb_hash_aset(class_tag_map, cASN1BitString, INT2NUM(V_ASN1_BIT_STRING));
    rb_hash_aset(class_tag_map, cASN1OctetString, INT2NUM(V_ASN1_OCTET_STRING));
    rb_hash_aset(class_tag_map, cASN1Null, INT2NUM(V_ASN1_NULL));
    rb_hash_aset(class_tag_map, cASN1ObjectId, INT2NUM(V_ASN1_OBJECT));
    rb_hash_aset(class_tag_map, cASN1Enumerated, INT2NUM(V_ASN1_ENUMERATED));
    rb_hash_aset(class_tag_map, cASN1UTF8String, INT2NUM(V_ASN1_UTF8STRING));
    rb_hash_aset(class_tag_map, cASN1Sequence, INT2NUM(V_ASN1_SEQUENCE));
    rb_hash_aset(class_tag_map, cASN1Set, INT2NUM(V_ASN1_SET));
    rb_hash_aset(class_tag_map, cASN1NumericString, INT2NUM(V_ASN1_NUMERICSTRING));
    rb_hash_aset(class_tag_map, cASN1PrintableString, INT2NUM(V_ASN1_PRINTABLESTRING));
    rb_hash_aset(class_tag_map, cASN1T61String, INT2NUM(V_ASN1_T61STRING));
    rb_hash_aset(class_tag_map, cASN1VideotexString, INT2NUM(V_ASN1_VIDEOTEXSTRING));
    rb_hash_aset(class_tag_map, cASN1IA5String, INT2NUM(V_ASN1_IA5STRING));
    rb_hash_aset(class_tag_map, cASN1UTCTime, INT2NUM(V_ASN1_UTCTIME));
    rb_hash_aset(class_tag_map, cASN1GeneralizedTime, INT2NUM(V_ASN1_GENERALIZEDTIME));
    rb_hash_aset(class_tag_map, cASN1GraphicString, INT2NUM(V_ASN1_GRAPHICSTRING));
    rb_hash_aset(class_tag_map, cASN1ISO64String, INT2NUM(V_ASN1_ISO64STRING));
    rb_hash_aset(class_tag_map, cASN1GeneralString, INT2NUM(V_ASN1_GENERALSTRING));
    rb_hash_aset(class_tag_map, cASN1UniversalString, INT2NUM(V_ASN1_UNIVERSALSTRING));
    rb_hash_aset(class_tag_map, cASN1BMPString, INT2NUM(V_ASN1_BMPSTRING));
    rb_obj_freeze(class_tag_map);

    id_each = rb_intern_const("each");
}


================================================
FILE: ext/openssl/ossl_asn1.h
================================================
/*
 * 'OpenSSL for Ruby' team members
 * Copyright (C) 2003
 * All rights reserved.
 */
/*
 * This program is licensed under the same licence as Ruby.
 * (See the file 'COPYING'.)
 */
#if !defined(_OSSL_ASN1_H_)
#define _OSSL_ASN1_H_

/*
 * ASN1_DATE conversions
 */
VALUE asn1time_to_time(const ASN1_TIME *);
/* Splits VALUE to seconds and offset days. VALUE is typically a Time or an
 * Integer. This is used when updating ASN1_*TIME with ASN1_TIME_adj() or
 * X509_time_adj_ex(). We can't use ASN1_TIME_set() and X509_time_adj() because
 * they have the Year 2038 issue on sizeof(time_t) == 4 environment */
void ossl_time_split(VALUE, time_t *, int *);

/*
 * ASN1_STRING conversions
 */
VALUE asn1str_to_str(const ASN1_STRING *);

/*
 * ASN1_INTEGER conversions
 */
VALUE asn1integer_to_num(const ASN1_INTEGER *);
ASN1_INTEGER *num_to_asn1integer(VALUE, ASN1_INTEGER *);

/*
 * ASN1_OBJECT conversions
 */
ASN1_OBJECT *ossl_to_asn1obj(VALUE obj);
/*
 * Returns the short name if available, the dotted decimal notation otherwise.
 * This is the most common way to return ASN1_OBJECT to Ruby.
 */
VALUE ossl_asn1obj_to_string(const ASN1_OBJECT *a1obj);
/*
 * However, some places use long names instead. This is likely unintentional,
 * but we keep the current behavior in existing methods.
 */
VALUE ossl_asn1obj_to_string_long_name(const ASN1_OBJECT *a1obj);

/*
 * ASN1 module
 */
extern VALUE mASN1;

extern VALUE cASN1Data;

void Init_ossl_asn1(void);

#endif


================================================
FILE: ext/openssl/ossl_bio.c
================================================
/*
 * 'OpenSSL for Ruby' team members
 * Copyright (C) 2003
 * All rights reserved.
 */
/*
 * This program is licensed under the same licence as Ruby.
 * (See the file 'COPYING'.)
 */
#include "ossl.h"

BIO *
ossl_obj2bio(volatile VALUE *pobj)
{
    VALUE obj = *pobj;
    BIO *bio;

    if (RB_TYPE_P(obj, T_FILE))
        obj = rb_funcallv(obj, rb_intern("read"), 0, NULL);
    StringValue(obj);
    bio = BIO_new_mem_buf(RSTRING_PTR(obj), RSTRING_LENINT(obj));
    if (!bio)
        ossl_raise(eOSSLError, "BIO_new_mem_buf");
    *pobj = obj;
    return bio;
}

VALUE
ossl_membio2str(BIO *bio)
{
    VALUE ret;
    int state;
    BUF_MEM *buf;

    if (BIO_get_mem_ptr(bio, &buf) <= 0) {
        BIO_free(bio);
        ossl_raise(eOSSLError, "BIO_get_mem_ptr");
    }

    ret = ossl_str_new(buf->data, buf->length, &state);
    BIO_free(bio);
    if (state)
        rb_jump_tag(state);

    return ret;
}


================================================
FILE: ext/openssl/ossl_bio.h
================================================
/*
 * 'OpenSSL for Ruby' team members
 * Copyright (C) 2003
 * All rights reserved.
 */
/*
 * This program is licensed under the same licence as Ruby.
 * (See the file 'COPYING'.)
 */
#if !defined(_OSSL_BIO_H_)
#define _OSSL_BIO_H_

BIO *ossl_obj2bio(volatile VALUE *);
VALUE ossl_membio2str(BIO*);

#endif


================================================
FILE: ext/openssl/ossl_bn.c
================================================
/*
 * 'OpenSSL for Ruby' project
 * Copyright (C) 2001-2002  Technorama team <oss-ruby@technorama.net>
 * All rights reserved.
 */
/*
 * This program is licensed under the same licence as Ruby.
 * (See the file 'COPYING'.)
 */
/* modified by Michal Rokos <m.rokos@sh.cvut.cz> */
#include "ossl.h"

#define NewBN(klass) \
    TypedData_Wrap_Struct((klass), &ossl_bn_type, 0)
#define SetBN(obj, bn) do { \
    if (!(bn)) { \
        ossl_raise(rb_eRuntimeError, "BN wasn't initialized!"); \
    } \
    RTYPEDDATA_DATA(obj) = (bn); \
} while (0)

#define GetBN(obj, bn) do { \
    TypedData_Get_Struct((obj), BIGNUM, &ossl_bn_type, (bn)); \
    if (!(bn)) { \
        ossl_raise(rb_eRuntimeError, "BN wasn't initialized!"); \
    } \
} while (0)

static void
ossl_bn_free(void *ptr)
{
    BN_clear_free(ptr);
}

static const rb_data_type_t ossl_bn_type = {
    "OpenSSL/BN",
    {
        0, ossl_bn_free,
    },
    0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE,
};

/*
 * Classes
 */
VALUE cBN;

/* Document-class: OpenSSL::BNError
 *
 * Generic Error for all of OpenSSL::BN (big num)
 */
static VALUE eBNError;

/*
 * Public
 */
VALUE
ossl_bn_new(const BIGNUM *bn)
{
    BIGNUM *newbn;
    VALUE obj;

    obj = NewBN(cBN);
    newbn = BN_dup(bn);
    if (!newbn)
        ossl_raise(eBNError, "BN_dup");
    SetBN(obj, newbn);

    return obj;
}

static BIGNUM *
integer_to_bnptr(VALUE obj, BIGNUM *orig)
{
    BIGNUM *bn;

    if (FIXNUM_P(obj)) {
        long i;
        unsigned char bin[sizeof(long)];
        long n = FIX2LONG(obj);
        unsigned long un = labs(n);

        for (i = sizeof(long) - 1; 0 <= i; i--) {
            bin[i] = un & 0xff;
            un >>= 8;
        }

        bn = BN_bin2bn(bin, sizeof(bin), orig);
        if (!bn)
            ossl_raise(eBNError, "BN_bin2bn");
        if (n < 0)
            BN_set_negative(bn, 1);
    }
    else { /* assuming Bignum */
        size_t len = rb_absint_size(obj, NULL);
        unsigned char *bin;
        VALUE buf;
        int sign;

        if (INT_MAX < len) {
            rb_raise(eBNError, "bignum too long");
        }
        bin = (unsigned char*)ALLOCV_N(unsigned char, buf, len);
        sign = rb_integer_pack(obj, bin, len, 1, 0, INTEGER_PACK_BIG_ENDIAN);

        bn = BN_bin2bn(bin, (int)len, orig);
        ALLOCV_END(buf);
        if (!bn)
            ossl_raise(eBNError, "BN_bin2bn");
        if (sign < 0)
            BN_set_negative(bn, 1);
    }

    return bn;
}

static VALUE
try_convert_to_bn(VALUE obj)
{
    BIGNUM *bn;
    VALUE newobj = Qnil;

    if (rb_obj_is_kind_of(obj, cBN))
        return obj;
    if (RB_INTEGER_TYPE_P(obj)) {
        newobj = NewBN(cBN); /* Handle potential mem leaks */
        bn = integer_to_bnptr(obj, NULL);
        SetBN(newobj, bn);
    }

    return newobj;
}

BIGNUM *
ossl_bn_value_ptr(volatile VALUE *ptr)
{
    VALUE tmp;
    BIGNUM *bn;

    tmp = try_convert_to_bn(*ptr);
    if (NIL_P(tmp))
        ossl_raise(rb_eTypeError, "Cannot convert into OpenSSL::BN");
    GetBN(tmp, bn);
    *ptr = tmp;

    return bn;
}

/*
 * Private
 */

#ifdef HAVE_RB_EXT_RACTOR_SAFE
static void
ossl_bn_ctx_free(void *ptr)
{
    BN_CTX *ctx = (BN_CTX *)ptr;
    BN_CTX_free(ctx);
}

static struct rb_ractor_local_storage_type ossl_bn_ctx_key_type = {
    NULL, // mark
    ossl_bn_ctx_free,
};

static rb_ractor_local_key_t ossl_bn_ctx_key;

BN_CTX *
ossl_bn_ctx_get(void)
{
    // stored in ractor local storage

    BN_CTX *ctx = rb_ractor_local_storage_ptr(ossl_bn_ctx_key);
    if (!ctx) {
        if (!(ctx = BN_CTX_new())) {
            ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX");
        }
        rb_ractor_local_storage_ptr_set(ossl_bn_ctx_key, ctx);
    }
    return ctx;
}
#else
// for ruby 2.x
static BN_CTX *gv_ossl_bn_ctx;

BN_CTX *
ossl_bn_ctx_get(void)
{
    if (gv_ossl_bn_ctx == NULL) {
        if (!(gv_ossl_bn_ctx = BN_CTX_new())) {
            ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX");
        }
    }
    return gv_ossl_bn_ctx;
}

void
ossl_bn_ctx_free(void)
{
    BN_CTX_free(gv_ossl_bn_ctx);
    gv_ossl_bn_ctx = NULL;
}
#endif

static VALUE
ossl_bn_alloc(VALUE klass)
{
    BIGNUM *bn;
    VALUE obj = NewBN(klass);

    if (!(bn = BN_new())) {
        ossl_raise(eBNError, NULL);
    }
    SetBN(obj, bn);

    return obj;
}

/*
 * call-seq:
 *    OpenSSL::BN.new(bn) -> aBN
 *    OpenSSL::BN.new(integer) -> aBN
 *    OpenSSL::BN.new(string, base = 10) -> aBN
 *
 * Construct a new \OpenSSL BIGNUM object.
 *
 * If +bn+ is an Integer or OpenSSL::BN, a new instance of OpenSSL::BN
 * representing the same value is returned. See also Integer#to_bn for the
 * short-hand.
 *
 * If a String is given, the content will be parsed according to +base+.
 *
 * +string+::
 *   The string to be parsed.
 * +base+::
 *   The format. Must be one of the following:
 *   - +0+  - MPI format. See the man page BN_mpi2bn(3) for details.
 *   - +2+  - Variable-length and big-endian binary encoding of a positive
 *     number.
 *   - +10+ - Decimal number representation, with a leading '-' for a negative
 *     number.
 *   - +16+ - Hexadecimal number representation, with a leading '-' for a
 *     negative number.
 */
static VALUE
ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
{
    BIGNUM *bn;
    VALUE str, bs;
    int base = 10;
    char *ptr;

    if (rb_scan_args(argc, argv, "11", &str, &bs) == 2) {
        base = NUM2INT(bs);
    }

    if (NIL_P(str)) {
        ossl_raise(rb_eArgError, "invalid argument");
    }

    rb_check_frozen(self);
    if (RB_INTEGER_TYPE_P(str)) {
        GetBN(self, bn);
        integer_to_bnptr(str, bn);

        return self;
    }

    if (RTEST(rb_obj_is_kind_of(str, cBN))) {
        BIGNUM *other;

        GetBN(self, bn);
        GetBN(str, other); /* Safe - we checked kind_of? above */
        if (!BN_copy(bn, other)) {
            ossl_raise(eBNError, NULL);
        }
        return self;
    }

    GetBN(self, bn);
    switch (base) {
      case 0:
        ptr = StringValuePtr(str);
        if (!BN_mpi2bn((unsigned char *)ptr, RSTRING_LENINT(str), bn)) {
            ossl_raise(eBNError, NULL);
        }
        break;
      case 2:
        ptr = StringValuePtr(str);
        if (!BN_bin2bn((unsigned char *)ptr, RSTRING_LENINT(str), bn)) {
            ossl_raise(eBNError, NULL);
        }
        break;
      case 10:
        if (!BN_dec2bn(&bn, StringValueCStr(str))) {
            ossl_raise(eBNError, NULL);
        }
        break;
      case 16:
        if (!BN_hex2bn(&bn, StringValueCStr(str))) {
            ossl_raise(eBNError, NULL);
        }
        break;
      default:
        ossl_raise(rb_eArgError, "invalid radix %d", base);
    }
    return self;
}

/*
 * call-seq:
 *    bn.to_s(base = 10) -> string
 *
 * Returns the string representation of the bignum.
 *
 * BN.new can parse the encoded string to convert back into an OpenSSL::BN.
 *
 * +base+::
 *   The format. Must be one of the following:
 *   - +0+  - MPI format. See the man page BN_bn2mpi(3) for details.
 *   - +2+  - Variable-length and big-endian binary encoding. The sign of
 *     the bignum is ignored.
 *   - +10+ - Decimal number representation, with a leading '-' for a negative
 *     bignum.
 *   - +16+ - Hexadecimal number representation, with a leading '-' for a
 *     negative bignum.
 */
static VALUE
ossl_bn_to_s(int argc, VALUE *argv, VALUE self)
{
    BIGNUM *bn;
    VALUE str, bs;
    int base = 10, len;
    char *buf;

    if (rb_scan_args(argc, argv, "01", &bs) == 1) {
        base = NUM2INT(bs);
    }
    GetBN(self, bn);
    switch (base) {
      case 0:
        len = BN_bn2mpi(bn, NULL);
        str = rb_str_new(0, len);
        if (BN_bn2mpi(bn, (unsigned char *)RSTRING_PTR(str)) != len)
            ossl_raise(eBNError, NULL);
        break;
      case 2:
        len = BN_num_bytes(bn);
        str = rb_str_new(0, len);
        if (BN_bn2bin(bn, (unsigned char *)RSTRING_PTR(str)) != len)
            ossl_raise(eBNError, NULL);
        break;
      case 10:
        if (!(buf = BN_bn2dec(bn))) ossl_raise(eBNError, NULL);
        str = ossl_buf2str(buf, rb_long2int(strlen(buf)));
        break;
      case 16:
        if (!(buf = BN_bn2hex(bn))) ossl_raise(eBNError, NULL);
        str = ossl_buf2str(buf, rb_long2int(strlen(buf)));
        break;
      default:
        ossl_raise(rb_eArgError, "invalid radix %d", base);
    }

    return str;
}

/*
 * call-seq:
 *    bn.to_i => integer
 */
static VALUE
ossl_bn_to_i(VALUE self)
{
    BIGNUM *bn;
    char *txt;
    VALUE num;

    GetBN(self, bn);

    if (!(txt = BN_bn2hex(bn))) {
        ossl_raise(eBNError, NULL);
    }
    num = rb_cstr_to_inum(txt, 16, Qtrue);
    OPENSSL_free(txt);

    return num;
}

static VALUE
ossl_bn_to_bn(VALUE self)
{
    return self;
}

static VALUE
ossl_bn_coerce(VALUE self, VALUE other)
{
    switch(TYPE(other)) {
      case T_STRING:
        self = ossl_bn_to_s(0, NULL, self);
        break;
      case T_FIXNUM:
      case T_BIGNUM:
        self = ossl_bn_to_i(self);
        break;
      default:
        if (!RTEST(rb_obj_is_kind_of(other, cBN))) {
            ossl_raise(rb_eTypeError, "Don't know how to coerce");
        }
    }
    return rb_assoc_new(other, self);
}

#define BIGNUM_BOOL1(func)                              \
    static VALUE                                        \
    ossl_bn_##func(VALUE self)                          \
    {                                                   \
        BIGNUM *bn;                                     \
        GetBN(self, bn);                                \
        if (BN_##func(bn)) {                            \
            return Qtrue;                               \
        }                                               \
        return Qfalse;                                  \
    }

/*
 * Document-method: OpenSSL::BN#zero?
 * call-seq:
 *   bn.zero? => true | false
 */
BIGNUM_BOOL1(is_zero)

/*
 * Document-method: OpenSSL::BN#one?
 * call-seq:
 *   bn.one? => true | false
 */
BIGNUM_BOOL1(is_one)

/*
 * Document-method: OpenSSL::BN#odd?
 * call-seq:
 *   bn.odd? => true | false
 */
BIGNUM_BOOL1(is_odd)

/*
 * call-seq:
 *   bn.negative? => true | false
 */
static VALUE
ossl_bn_is_negative(VALUE self)
{
    BIGNUM *bn;

    GetBN(self, bn);
    if (BN_is_zero(bn))
        return Qfalse;
    return BN_is_negative(bn) ? Qtrue : Qfalse;
}

#define BIGNUM_1c(func)                                 \
    static VALUE                                        \
    ossl_bn_##func(VALUE self)                          \
    {                                                   \
        BIGNUM *bn, *result;                            \
        VALUE obj;                                      \
        GetBN(self, bn);                                \
        obj = NewBN(rb_obj_class(self));                \
        if (!(result = BN_new())) {                     \
            ossl_raise(eBNError, NULL);                 \
        }                                               \
        if (BN_##func(result, bn, ossl_bn_ctx) <= 0) {  \
            BN_free(result);                            \
            ossl_raise(eBNError, NULL);                 \
        }                                               \
        SetBN(obj, result);                             \
        return obj;                                     \
    }

/*
 * Document-method: OpenSSL::BN#sqr
 * call-seq:
 *   bn.sqr => aBN
 */
BIGNUM_1c(sqr)

#define BIGNUM_2(func)                                  \
    static VALUE                                        \
    ossl_bn_##func(VALUE self, VALUE other)             \
    {                                                   \
        BIGNUM *bn1, *bn2 = GetBNPtr(other), *result;   \
        VALUE obj;                                      \
        GetBN(self, bn1);                               \
        obj = NewBN(rb_obj_class(self));                \
        if (!(result = BN_new())) {                     \
            ossl_raise(eBNError, NULL);                 \
        }                                               \
        if (BN_##func(result, bn1, bn2) <= 0) {         \
            BN_free(result);                            \
            ossl_raise(eBNError, NULL);                 \
        }                                               \
        SetBN(obj, result);                             \
        return obj;                                     \
    }

/*
 * Document-method: OpenSSL::BN#+
 * call-seq:
 *   bn + bn2 => aBN
 */
BIGNUM_2(add)

/*
 * Document-method: OpenSSL::BN#-
 * call-seq:
 *   bn - bn2 => aBN
 */
BIGNUM_2(sub)

#define BIGNUM_2c(func)                                         \
    static VALUE                                                \
    ossl_bn_##func(VALUE self, VALUE other)                     \
    {                                                           \
        BIGNUM *bn1, *bn2 = GetBNPtr(other), *result;           \
        VALUE obj;                                              \
        GetBN(self, bn1);                                       \
        obj = NewBN(rb_obj_class(self));                        \
        if (!(result = BN_new())) {                             \
            ossl_raise(eBNError, NULL);                         \
        }                                                       \
        if (BN_##func(result, bn1, bn2, ossl_bn_ctx) <= 0) {    \
            BN_free(result);                                    \
            ossl_raise(eBNError, NULL);                         \
        }                                                       \
        SetBN(obj, result);                                     \
        return obj;                                             \
    }

/*
 * Document-method: OpenSSL::BN#*
 * call-seq:
 *   bn * bn2 => aBN
 */
BIGNUM_2c(mul)

/*
 * Document-method: OpenSSL::BN#%
 * call-seq:
 *   bn % bn2 => aBN
 */
BIGNUM_2c(mod)

/*
 * Document-method: OpenSSL::BN#**
 * call-seq:
 *   bn ** bn2 => aBN
 */
BIGNUM_2c(exp)

/*
 * Document-method: OpenSSL::BN#gcd
 * call-seq:
 *   bn.gcd(bn2) => aBN
 */
BIGNUM_2c(gcd)

/*
 * Document-method: OpenSSL::BN#mod_sqr
 * call-seq:
 *   bn.mod_sqr(bn2) => aBN
 */
BIGNUM_2c(mod_sqr)

#define BIGNUM_2cr(func)                                        \
    static VALUE                                                \
    ossl_bn_##func(VA
Download .txt
gitextract_bnbciiwa/

├── .git-blame-ignore-revs
├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       ├── github-pages.yml
│       ├── push_gem.yml
│       ├── sync-ruby.yml
│       └── test.yml
├── .gitignore
├── BSDL
├── CONTRIBUTING.md
├── COPYING
├── Gemfile
├── History.md
├── README.md
├── Rakefile
├── ext/
│   └── openssl/
│       ├── extconf.rb
│       ├── openssl_missing.h
│       ├── ossl.c
│       ├── ossl.h
│       ├── ossl_asn1.c
│       ├── ossl_asn1.h
│       ├── ossl_bio.c
│       ├── ossl_bio.h
│       ├── ossl_bn.c
│       ├── ossl_bn.h
│       ├── ossl_cipher.c
│       ├── ossl_cipher.h
│       ├── ossl_config.c
│       ├── ossl_config.h
│       ├── ossl_digest.c
│       ├── ossl_digest.h
│       ├── ossl_engine.c
│       ├── ossl_engine.h
│       ├── ossl_hmac.c
│       ├── ossl_hmac.h
│       ├── ossl_kdf.c
│       ├── ossl_kdf.h
│       ├── ossl_ns_spki.c
│       ├── ossl_ns_spki.h
│       ├── ossl_ocsp.c
│       ├── ossl_ocsp.h
│       ├── ossl_pkcs12.c
│       ├── ossl_pkcs12.h
│       ├── ossl_pkcs7.c
│       ├── ossl_pkcs7.h
│       ├── ossl_pkey.c
│       ├── ossl_pkey.h
│       ├── ossl_pkey_dh.c
│       ├── ossl_pkey_dsa.c
│       ├── ossl_pkey_ec.c
│       ├── ossl_pkey_rsa.c
│       ├── ossl_provider.c
│       ├── ossl_provider.h
│       ├── ossl_rand.c
│       ├── ossl_rand.h
│       ├── ossl_ssl.c
│       ├── ossl_ssl.h
│       ├── ossl_ssl_session.c
│       ├── ossl_ts.c
│       ├── ossl_ts.h
│       ├── ossl_x509.c
│       ├── ossl_x509.h
│       ├── ossl_x509attr.c
│       ├── ossl_x509cert.c
│       ├── ossl_x509crl.c
│       ├── ossl_x509ext.c
│       ├── ossl_x509name.c
│       ├── ossl_x509req.c
│       ├── ossl_x509revoked.c
│       └── ossl_x509store.c
├── lib/
│   ├── openssl/
│   │   ├── bn.rb
│   │   ├── buffering.rb
│   │   ├── cipher.rb
│   │   ├── digest.rb
│   │   ├── hmac.rb
│   │   ├── marshal.rb
│   │   ├── pkcs5.rb
│   │   ├── pkey.rb
│   │   ├── ssl.rb
│   │   ├── version.rb
│   │   └── x509.rb
│   └── openssl.rb
├── openssl.gemspec
├── sample/
│   ├── c_rehash.rb
│   ├── cert2text.rb
│   ├── certstore.rb
│   ├── cipher.rb
│   ├── crlstore.rb
│   ├── echo_cli.rb
│   ├── echo_svr.rb
│   ├── gen_csr.rb
│   ├── smime_read.rb
│   ├── smime_write.rb
│   └── wget.rb
├── test/
│   └── openssl/
│       ├── fixtures/
│       │   └── pkey/
│       │       ├── dh-1.pem
│       │       ├── dh2048_ffdhe2048.pem
│       │       ├── dsa2048.pem
│       │       ├── mldsa65-1.pem
│       │       ├── mldsa65-2.pem
│       │       ├── p256.pem
│       │       ├── rsa-1.pem
│       │       ├── rsa-2.pem
│       │       ├── rsa-3.pem
│       │       └── rsa2048.pem
│       ├── test_asn1.rb
│       ├── test_bn.rb
│       ├── test_buffering.rb
│       ├── test_cipher.rb
│       ├── test_config.rb
│       ├── test_digest.rb
│       ├── test_engine.rb
│       ├── test_fips.rb
│       ├── test_hmac.rb
│       ├── test_kdf.rb
│       ├── test_ns_spki.rb
│       ├── test_ocsp.rb
│       ├── test_ossl.rb
│       ├── test_pair.rb
│       ├── test_pkcs12.rb
│       ├── test_pkcs7.rb
│       ├── test_pkey.rb
│       ├── test_pkey_dh.rb
│       ├── test_pkey_dsa.rb
│       ├── test_pkey_ec.rb
│       ├── test_pkey_rsa.rb
│       ├── test_provider.rb
│       ├── test_random.rb
│       ├── test_ssl.rb
│       ├── test_ssl_session.rb
│       ├── test_ts.rb
│       ├── test_x509attr.rb
│       ├── test_x509cert.rb
│       ├── test_x509crl.rb
│       ├── test_x509ext.rb
│       ├── test_x509name.rb
│       ├── test_x509req.rb
│       ├── test_x509store.rb
│       ├── ut_eof.rb
│       └── utils.rb
└── tool/
    └── openssl_fips.cnf.tmpl
Download .txt
SYMBOL INDEX (1858 symbols across 88 files)

FILE: ext/openssl/extconf.rb
  function find_openssl_library (line 62) | def find_openssl_library

FILE: ext/openssl/openssl_missing.h
  function ASN1_BIT_STRING_set1 (line 34) | static inline int
  function ASN1_BIT_STRING_get_length (line 45) | static inline int

FILE: ext/openssl/ossl.c
  function VALUE (line 90) | static VALUE
  function VALUE (line 96) | VALUE
  function VALUE (line 115) | VALUE
  function ossl_bin2hex (line 128) | void
  function VALUE (line 146) | VALUE
  function VALUE (line 162) | static VALUE
  function ossl_pem_passwd_cb (line 172) | int
  function VALUE (line 239) | VALUE
  function VALUE (line 250) | VALUE
  function VALUE (line 265) | VALUE
  function ossl_raise (line 296) | void
  function ossl_clear_error (line 350) | void
  function VALUE (line 363) | static VALUE
  function VALUE (line 404) | static VALUE
  function VALUE (line 429) | static VALUE
  function VALUE (line 442) | static VALUE
  function VALUE (line 456) | static VALUE
  function VALUE (line 485) | static VALUE
  function VALUE (line 527) | static VALUE
  function Init_openssl (line 1003) | void

FILE: ext/openssl/ossl_asn1.c
  function VALUE (line 58) | static VALUE
  function VALUE (line 64) | static VALUE
  function VALUE (line 70) | VALUE
  function VALUE (line 89) | static VALUE
  function ossl_time_split (line 95) | void
  function VALUE (line 114) | VALUE
  function VALUE (line 124) | VALUE
  function ASN1_INTEGER (line 148) | ASN1_INTEGER *
  function VALUE (line 164) | static VALUE
  function VALUE (line 173) | VALUE
  function VALUE (line 194) | VALUE
  function VALUE (line 203) | VALUE
  function ASN1_BOOLEAN (line 215) | static ASN1_BOOLEAN
  function ASN1_INTEGER (line 224) | static ASN1_INTEGER*
  function ASN1_BIT_STRING (line 230) | static ASN1_BIT_STRING*
  function ASN1_STRING (line 248) | static ASN1_STRING*
  function ASN1_NULL (line 261) | static ASN1_NULL*
  function ASN1_OBJECT (line 274) | ASN1_OBJECT *
  function ASN1_UTCTIME (line 287) | static ASN1_UTCTIME *
  function ASN1_GENERALIZEDTIME (line 302) | static ASN1_GENERALIZEDTIME *
  function ASN1_STRING (line 317) | static ASN1_STRING*
  function VALUE (line 334) | static VALUE
  function VALUE (line 347) | static VALUE
  function VALUE (line 366) | static VALUE
  function VALUE (line 390) | static VALUE
  function VALUE (line 409) | static VALUE
  function VALUE (line 423) | VALUE
  function VALUE (line 429) | static VALUE
  function VALUE (line 447) | static VALUE
  function VALUE (line 466) | static VALUE
  type ossl_asn1_info_t (line 477) | typedef struct {
  function ASN1_TYPE (line 522) | static ASN1_TYPE *
  function ossl_asn1_default_tag (line 598) | static int
  function ossl_asn1_tag (line 614) | static int
  function ossl_asn1_tag_class (line 626) | static int
  function VALUE (line 644) | static VALUE
  function VALUE (line 673) | static VALUE
  function VALUE (line 686) | static VALUE
  function VALUE (line 744) | static VALUE
  function VALUE (line 763) | static VALUE
  function VALUE (line 837) | static VALUE
  function VALUE (line 892) | static VALUE
  function int_ossl_decode_sanity_check (line 956) | static void
  function VALUE (line 987) | static VALUE
  function VALUE (line 1016) | static VALUE
  function VALUE (line 1047) | static VALUE
  function VALUE (line 1096) | static VALUE
  function VALUE (line 1135) | static VALUE
  function VALUE (line 1150) | static VALUE
  function VALUE (line 1162) | static VALUE
  function VALUE (line 1209) | static VALUE
  function VALUE (line 1254) | static VALUE
  function VALUE (line 1273) | static VALUE
  function VALUE (line 1293) | static VALUE
  function VALUE (line 1313) | static VALUE
  function VALUE (line 1326) | static VALUE
  function VALUE (line 1339) | static VALUE
  function VALUE (line 1360) | static VALUE
  function OSSL_ASN1_IMPL_FACTORY_METHOD (line 1377) | OSSL_ASN1_IMPL_FACTORY_METHOD(Boolean)

FILE: ext/openssl/ossl_bio.c
  function BIO (line 12) | BIO *
  function VALUE (line 28) | VALUE

FILE: ext/openssl/ossl_bn.c
  function ossl_bn_free (line 29) | static void
  function VALUE (line 57) | VALUE
  function BIGNUM (line 72) | static BIGNUM *
  function VALUE (line 117) | static VALUE
  function BIGNUM (line 134) | BIGNUM *
  function ossl_bn_ctx_free (line 154) | static void
  type rb_ractor_local_storage_type (line 161) | struct rb_ractor_local_storage_type
  function BN_CTX (line 168) | BN_CTX *
  function BN_CTX (line 186) | BN_CTX *
  function ossl_bn_ctx_free (line 197) | void
  function VALUE (line 205) | static VALUE
  function VALUE (line 245) | static VALUE
  function VALUE (line 328) | static VALUE
  function VALUE (line 372) | static VALUE
  function VALUE (line 390) | static VALUE
  function VALUE (line 396) | static VALUE
  function BIGNUM_BOOL1 (line 432) | BIGNUM_BOOL1(is_zero)
  function BIGNUM_2cr (line 595) | BIGNUM_2cr(mod_sqrt)
  function BIGNUM_BIT (line 705) | BIGNUM_BIT(set_bit)
  function BIGNUM_NUM (line 922) | BIGNUM_NUM(num_bytes)
  function VALUE (line 954) | static VALUE
  function VALUE (line 974) | static VALUE
  function VALUE (line 995) | static VALUE
  function BIGNUM_CMP (line 1028) | BIGNUM_CMP(cmp)
  function VALUE (line 1069) | static VALUE
  function VALUE (line 1090) | static VALUE
  function VALUE (line 1121) | static VALUE
  function VALUE (line 1154) | static VALUE
  function VALUE (line 1171) | static VALUE
  function VALUE (line 1187) | static VALUE
  function Init_ossl_bn (line 1202) | void

FILE: ext/openssl/ossl_cipher.c
  function ossl_evp_cipher_free (line 50) | static void
  function EVP_CIPHER (line 70) | const EVP_CIPHER *
  function VALUE (line 103) | VALUE
  function ossl_cipher_free (line 123) | static void
  function VALUE (line 129) | static VALUE
  function VALUE (line 143) | static VALUE
  function VALUE (line 164) | static VALUE
  function add_cipher_name_to_ary (line 183) | static void
  function VALUE (line 196) | static VALUE
  function VALUE (line 218) | static VALUE
  function VALUE (line 230) | static VALUE
  function VALUE (line 256) | static VALUE
  function VALUE (line 273) | static VALUE
  function VALUE (line 295) | static VALUE
  function ossl_cipher_update_long (line 329) | static int
  function VALUE (line 369) | static VALUE
  function VALUE (line 439) | static VALUE
  function VALUE (line 471) | static VALUE
  function VALUE (line 494) | static VALUE
  function VALUE (line 533) | static VALUE
  function VALUE (line 561) | static VALUE
  function VALUE (line 591) | static VALUE
  function VALUE (line 629) | static VALUE
  function VALUE (line 675) | static VALUE
  function VALUE (line 710) | static VALUE
  function VALUE (line 742) | static VALUE
  function VALUE (line 777) | static VALUE
  function VALUE (line 803) | static VALUE
  function VALUE (line 821) | static VALUE
  function VALUE (line 837) | static VALUE
  function VALUE (line 858) | static VALUE
  function VALUE (line 882) | static VALUE
  function Init_ossl_cipher (line 900) | void

FILE: ext/openssl/ossl_config.c
  function nconf_free (line 14) | static void
  function CONF (line 28) | CONF *
  function VALUE (line 39) | static VALUE
  function config_load_bio (line 53) | static void
  function VALUE (line 81) | static VALUE
  function VALUE (line 104) | static VALUE
  function VALUE (line 133) | static VALUE
  function VALUE (line 152) | static VALUE
  function VALUE (line 187) | static VALUE
  function VALUE (line 226) | static VALUE
  function get_conf_section_doall_arg (line 249) | static void
  function config_get_sections (line 258) | static IMPLEMENT_LHASH_DOALL_ARG_FN(get_conf_section, CONF_VALUE, VALUE)
  function dump_conf_value_doall_arg (line 278) | static void
  function config_to_s (line 302) | static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_conf_value, CONF_VALUE, VALUE)
  function each_conf_value_doall_arg (line 344) | static void
  function config_each (line 364) | static IMPLEMENT_LHASH_DOALL_ARG_FN(each_conf_value, CONF_VALUE, void)
  function VALUE (line 395) | static VALUE
  function Init_ossl_config (line 410) | void

FILE: ext/openssl/ossl_digest.c
  function ossl_digest_free (line 28) | static void
  function ossl_evp_md_free (line 43) | static void
  function EVP_MD (line 63) | const EVP_MD *
  function VALUE (line 101) | VALUE
  function VALUE (line 125) | static VALUE
  function VALUE (line 151) | static VALUE
  function VALUE (line 178) | static VALUE
  function add_digest_name_to_ary (line 200) | static void
  function VALUE (line 213) | static VALUE
  function VALUE (line 234) | static VALUE
  function VALUE (line 262) | static VALUE
  function VALUE (line 281) | static VALUE
  function VALUE (line 307) | static VALUE
  function VALUE (line 329) | static VALUE
  function VALUE (line 352) | static VALUE
  function Init_ossl_digest (line 365) | void

FILE: ext/openssl/ossl_engine.c
  function ossl_engine_free (line 60) | static void
  function VALUE (line 84) | static VALUE
  function VALUE (line 113) | static VALUE
  function VALUE (line 125) | static VALUE
  function VALUE (line 156) | static VALUE
  function VALUE (line 189) | static VALUE
  function VALUE (line 209) | static VALUE
  function VALUE (line 225) | static VALUE
  function VALUE (line 251) | static VALUE
  function VALUE (line 283) | static VALUE
  function VALUE (line 309) | static VALUE
  function VALUE (line 338) | static VALUE
  function VALUE (line 372) | static VALUE
  function VALUE (line 392) | static VALUE
  function VALUE (line 408) | static VALUE
  function VALUE (line 426) | static VALUE
  function VALUE (line 454) | static VALUE
  function Init_ossl_engine (line 466) | void
  function Init_ossl_engine (line 500) | void

FILE: ext/openssl/ossl_hmac.c
  function ossl_hmac_free (line 35) | static void
  function VALUE (line 49) | static VALUE
  function VALUE (line 93) | static VALUE
  function VALUE (line 121) | static VALUE
  function VALUE (line 154) | static VALUE
  function VALUE (line 179) | static VALUE
  function VALUE (line 203) | static VALUE
  function VALUE (line 239) | static VALUE
  function Init_ossl_hmac (line 256) | void

FILE: ext/openssl/ossl_kdf.c
  type pbkdf2_hmac_args (line 10) | struct pbkdf2_hmac_args {
  type pbkdf2_hmac_args (line 24) | struct pbkdf2_hmac_args
  type pbkdf2_hmac_args (line 24) | struct pbkdf2_hmac_args
  function VALUE (line 56) | static VALUE
  type scrypt_args (line 102) | struct scrypt_args {
  type scrypt_args (line 115) | struct scrypt_args
  type scrypt_args (line 115) | struct scrypt_args
  function VALUE (line 160) | static VALUE
  function VALUE (line 240) | static VALUE
  function Init_ossl_kdf (line 307) | void

FILE: ext/openssl/ossl_ns_spki.c
  function ossl_netscape_spki_free (line 42) | static void
  function VALUE (line 56) | static VALUE
  function VALUE (line 78) | static VALUE
  function VALUE (line 108) | static VALUE
  function VALUE (line 134) | static VALUE
  function VALUE (line 157) | static VALUE
  function VALUE (line 182) | static VALUE
  function VALUE (line 207) | static VALUE
  function VALUE (line 227) | static VALUE
  function VALUE (line 251) | static VALUE
  function VALUE (line 279) | static VALUE
  function VALUE (line 306) | static VALUE
  function Init_ossl_ns_spki (line 377) | void

FILE: ext/openssl/ossl_ocsp.c
  function ossl_ocsp_request_free (line 78) | static void
  function ossl_ocsp_response_free (line 92) | static void
  function ossl_ocsp_basicresp_free (line 106) | static void
  function ossl_ocsp_singleresp_free (line 120) | static void
  function ossl_ocsp_certid_free (line 134) | static void
  function VALUE (line 151) | static VALUE
  function VALUE (line 166) | static VALUE
  function VALUE (line 181) | static VALUE
  function VALUE (line 209) | static VALUE
  function VALUE (line 243) | static VALUE
  function VALUE (line 284) | static VALUE
  function VALUE (line 305) | static VALUE
  function VALUE (line 331) | static VALUE
  function VALUE (line 369) | static VALUE
  function VALUE (line 413) | static VALUE
  function VALUE (line 439) | static VALUE
  function VALUE (line 466) | static VALUE
  function VALUE (line 485) | static VALUE
  function VALUE (line 503) | static VALUE
  function VALUE (line 518) | static VALUE
  function VALUE (line 546) | static VALUE
  function VALUE (line 576) | static VALUE
  function VALUE (line 595) | static VALUE
  function VALUE (line 614) | static VALUE
  function VALUE (line 637) | static VALUE
  function VALUE (line 660) | static VALUE
  function VALUE (line 675) | static VALUE
  function VALUE (line 702) | static VALUE
  function VALUE (line 733) | static VALUE
  function VALUE (line 755) | static VALUE
  function VALUE (line 777) | static VALUE
  function VALUE (line 820) | static VALUE
  function VALUE (line 898) | static VALUE
  function VALUE (line 944) | static VALUE
  function VALUE (line 970) | static VALUE
  function VALUE (line 998) | static VALUE
  function VALUE (line 1037) | static VALUE
  function VALUE (line 1065) | static VALUE
  function VALUE (line 1088) | static VALUE
  function VALUE (line 1105) | static VALUE
  function VALUE (line 1125) | static VALUE
  function VALUE (line 1146) | static VALUE
  function VALUE (line 1181) | static VALUE
  function VALUE (line 1214) | static VALUE
  function VALUE (line 1237) | static VALUE
  function VALUE (line 1255) | static VALUE
  function VALUE (line 1276) | static VALUE
  function VALUE (line 1297) | static VALUE
  function VALUE (line 1320) | static VALUE
  function VALUE (line 1340) | static VALUE
  function VALUE (line 1365) | static VALUE
  function VALUE (line 1389) | static VALUE
  function VALUE (line 1404) | static VALUE
  function VALUE (line 1437) | static VALUE
  function VALUE (line 1482) | static VALUE
  function VALUE (line 1503) | static VALUE
  function VALUE (line 1523) | static VALUE
  function VALUE (line 1542) | static VALUE
  function VALUE (line 1566) | static VALUE
  function VALUE (line 1590) | static VALUE
  function VALUE (line 1607) | static VALUE
  function Init_ossl_ocsp (line 1627) | void
  function Init_ossl_ocsp (line 1933) | void

FILE: ext/openssl/ossl_pkcs12.c
  function ossl_pkcs12_free (line 36) | static void
  function VALUE (line 50) | static VALUE
  function VALUE (line 64) | static VALUE
  function VALUE (line 105) | static VALUE
  function VALUE (line 163) | static VALUE
  function VALUE (line 169) | static VALUE
  function VALUE (line 175) | static VALUE
  function VALUE (line 191) | static VALUE
  function VALUE (line 237) | static VALUE
  function VALUE (line 270) | static VALUE
  function Init_ossl_pkcs12 (line 299) | void

FILE: ext/openssl/ossl_pkcs7.c
  function ossl_pkcs7_free (line 73) | static void
  function VALUE (line 87) | VALUE
  function ossl_pkcs7_signer_info_free (line 101) | static void
  function ossl_pkcs7_recip_info_free (line 115) | static void
  function PKCS7_SIGNER_INFO (line 133) | static PKCS7_SIGNER_INFO *
  function PKCS7_RECIP_INFO (line 146) | static PKCS7_RECIP_INFO *
  function VALUE (line 162) | static VALUE
  function VALUE (line 177) | static VALUE
  function VALUE (line 196) | static VALUE
  function VALUE (line 227) | static VALUE
  function VALUE (line 262) | static VALUE
  function VALUE (line 313) | static VALUE
  function VALUE (line 353) | static VALUE
  function VALUE (line 375) | static VALUE
  function VALUE (line 408) | static VALUE
  function ossl_pkcs7_sym2typeid (line 429) | static int
  function VALUE (line 469) | static VALUE
  function VALUE (line 485) | static VALUE
  function VALUE (line 504) | static VALUE
  function VALUE (line 518) | static VALUE
  function VALUE (line 528) | static VALUE
  function VALUE (line 536) | static VALUE
  function VALUE (line 552) | static VALUE
  function VALUE (line 573) | static VALUE
  function VALUE (line 594) | static VALUE
  function VALUE (line 615) | static VALUE
  function VALUE (line 640) | static VALUE
  function VALUE (line 701) | static VALUE
  function VALUE (line 707) | static VALUE
  function VALUE (line 723) | static VALUE
  function VALUE (line 732) | static VALUE
  function VALUE (line 747) | static VALUE
  function VALUE (line 753) | static VALUE
  function VALUE (line 769) | static VALUE
  function VALUE (line 778) | static VALUE
  function VALUE (line 823) | static VALUE
  function VALUE (line 850) | static VALUE
  function VALUE (line 892) | static VALUE
  function VALUE (line 912) | static VALUE
  function VALUE (line 931) | static VALUE
  function VALUE (line 954) | static VALUE
  function VALUE (line 969) | static VALUE
  function VALUE (line 989) | static VALUE
  function VALUE (line 999) | static VALUE
  function VALUE (line 1009) | static VALUE
  function VALUE (line 1035) | static VALUE
  function VALUE (line 1050) | static VALUE
  function VALUE (line 1065) | static VALUE
  function VALUE (line 1075) | static VALUE
  function VALUE (line 1085) | static VALUE
  function Init_ossl_pkcs7 (line 1098) | void

FILE: ext/openssl/ossl_pkey.c
  function ossl_evp_pkey_free (line 24) | static void
  function VALUE (line 41) | static VALUE
  function VALUE (line 67) | VALUE
  function EVP_PKEY (line 85) | static EVP_PKEY *
  function EVP_PKEY (line 118) | EVP_PKEY *
  function EVP_PKEY (line 184) | EVP_PKEY *
  function VALUE (line 230) | static VALUE
  function VALUE (line 246) | static VALUE
  function VALUE (line 262) | static VALUE
  function pkey_ctx_apply_options (line 273) | static void
  type pkey_blocking_generate_arg (line 283) | struct pkey_blocking_generate_arg {
  function VALUE (line 292) | static VALUE
  function VALUE (line 307) | static VALUE
  function pkey_gen_cb (line 322) | static int
  function pkey_blocking_gen_stop (line 346) | static void
  type pkey_blocking_generate_arg (line 356) | struct pkey_blocking_generate_arg
  function VALUE (line 365) | static VALUE
  function VALUE (line 470) | static VALUE
  function VALUE (line 496) | static VALUE
  function ossl_pkey_check_public_key (line 508) | void
  function EVP_PKEY (line 552) | EVP_PKEY *
  function EVP_PKEY (line 562) | EVP_PKEY *
  function EVP_PKEY (line 582) | EVP_PKEY *
  function VALUE (line 596) | static VALUE
  function VALUE (line 609) | static VALUE
  function VALUE (line 620) | static VALUE
  function lookup_pkey_type (line 640) | static int
  function VALUE (line 669) | static VALUE
  function VALUE (line 701) | static VALUE
  function VALUE (line 732) | static VALUE
  function VALUE (line 753) | static VALUE
  function VALUE (line 787) | static VALUE
  function VALUE (line 813) | VALUE
  function VALUE (line 848) | static VALUE
  function VALUE (line 897) | static VALUE
  function VALUE (line 923) | static VALUE
  function VALUE (line 936) | static VALUE
  function VALUE (line 956) | VALUE
  function VALUE (line 988) | static VALUE
  function VALUE (line 1006) | static VALUE
  function VALUE (line 1019) | static VALUE
  function VALUE (line 1051) | static VALUE
  function VALUE (line 1110) | static VALUE
  function VALUE (line 1189) | static VALUE
  function VALUE (line 1268) | static VALUE
  function VALUE (line 1344) | static VALUE
  function VALUE (line 1407) | static VALUE
  function VALUE (line 1471) | static VALUE
  function VALUE (line 1540) | static VALUE
  function VALUE (line 1603) | static VALUE
  function Init_ossl_pkey (line 1659) | void

FILE: ext/openssl/ossl_pkey_dh.c
  function VALUE (line 75) | static VALUE
  function VALUE (line 140) | static VALUE
  function VALUE (line 187) | static VALUE
  function VALUE (line 206) | static VALUE
  function VALUE (line 243) | static VALUE
  function VALUE (line 276) | static VALUE
  function VALUE (line 306) | static VALUE
  function Init_ossl_dh (line 357) | void
  function Init_ossl_dh (line 416) | void

FILE: ext/openssl/ossl_pkey_dsa.c
  function DSA_HAS_PRIVATE (line 28) | static inline int
  function DSA_PRIVATE (line 36) | static inline int
  function VALUE (line 85) | static VALUE
  function VALUE (line 151) | static VALUE
  function VALUE (line 187) | static VALUE
  function VALUE (line 206) | static VALUE
  function VALUE (line 275) | static VALUE
  function VALUE (line 301) | static VALUE
  function Init_ossl_dsa (line 334) | void
  function Init_ossl_dsa (line 367) | void

FILE: ext/openssl/ossl_pkey_ec.c
  function EC_KEY (line 63) | static EC_KEY *
  function VALUE (line 102) | static VALUE
  function VALUE (line 137) | static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
  function VALUE (line 198) | static VALUE
  function VALUE (line 231) | static VALUE
  function VALUE (line 252) | static VALUE
  function VALUE (line 277) | static VALUE ossl_ec_key_get_private_key(VALUE self)
  function VALUE (line 295) | static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key)
  function VALUE (line 328) | static VALUE ossl_ec_key_get_public_key(VALUE self)
  function VALUE (line 346) | static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key)
  function VALUE (line 380) | static VALUE ossl_ec_key_is_public(VALUE self)
  function VALUE (line 396) | static VALUE ossl_ec_key_is_private(VALUE self)
  function VALUE (line 463) | static VALUE
  function VALUE (line 491) | static VALUE
  function VALUE (line 518) | static VALUE ossl_ec_key_generate_key(VALUE self)
  function VALUE (line 541) | static VALUE ossl_ec_key_check_key(VALUE self)
  function ossl_ec_group_free (line 582) | static void
  function VALUE (line 596) | static VALUE
  function VALUE (line 602) | static VALUE
  function VALUE (line 629) | static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self)
  function VALUE (line 715) | static VALUE
  function VALUE (line 741) | static VALUE ossl_ec_group_eql(VALUE a, VALUE b)
  function VALUE (line 763) | static VALUE ossl_ec_group_get_generator(VALUE self)
  function VALUE (line 785) | static VALUE ossl_ec_group_set_generator(VALUE self, VALUE generator, VA...
  function VALUE (line 810) | static VALUE ossl_ec_group_get_order(VALUE self)
  function VALUE (line 834) | static VALUE ossl_ec_group_get_cofactor(VALUE self)
  function VALUE (line 859) | static VALUE ossl_ec_group_get_curve_name(VALUE self)
  function VALUE (line 880) | static VALUE ossl_s_builtin_curves(VALUE self)
  function VALUE (line 916) | static VALUE ossl_ec_group_get_asn1_flag(VALUE self)
  function VALUE (line 941) | static VALUE ossl_ec_group_set_asn1_flag(VALUE self, VALUE flag_v)
  function VALUE (line 959) | static VALUE ossl_ec_group_get_point_conversion_form(VALUE self)
  function point_conversion_form_t (line 980) | static point_conversion_form_t
  function VALUE (line 1012) | static VALUE
  function VALUE (line 1032) | static VALUE ossl_ec_group_get_seed(VALUE self)
  function VALUE (line 1052) | static VALUE ossl_ec_group_set_seed(VALUE self, VALUE seed)
  function VALUE (line 1073) | static VALUE ossl_ec_group_get_degree(VALUE self)
  function VALUE (line 1082) | static VALUE ossl_ec_group_to_string(VALUE self, int format)
  function VALUE (line 1122) | static VALUE ossl_ec_group_to_pem(VALUE self)
  function VALUE (line 1133) | static VALUE ossl_ec_group_to_der(VALUE self)
  function VALUE (line 1144) | static VALUE ossl_ec_group_to_text(VALUE self)
  function ossl_ec_point_free (line 1167) | static void
  function VALUE (line 1181) | static VALUE
  function VALUE (line 1187) | static VALUE
  function VALUE (line 1216) | static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self)
  function VALUE (line 1266) | static VALUE
  function VALUE (line 1295) | static VALUE ossl_ec_point_eql(VALUE a, VALUE b)
  function VALUE (line 1322) | static VALUE ossl_ec_point_is_at_infinity(VALUE self)
  function VALUE (line 1343) | static VALUE ossl_ec_point_is_on_curve(VALUE self)
  function VALUE (line 1366) | static VALUE ossl_ec_point_make_affine(VALUE self)
  function VALUE (line 1387) | static VALUE ossl_ec_point_invert(VALUE self)
  function VALUE (line 1405) | static VALUE ossl_ec_point_set_to_infinity(VALUE self)
  function VALUE (line 1431) | static VALUE
  function VALUE (line 1461) | static VALUE ossl_ec_point_add(VALUE self, VALUE other)
  function VALUE (line 1497) | static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
  function Init_ossl_ec (line 1526) | void Init_ossl_ec(void)
  function Init_ossl_ec (line 1652) | void Init_ossl_ec(void)

FILE: ext/openssl/ossl_pkey_rsa.c
  function RSA_HAS_PRIVATE (line 28) | static inline int
  function RSA_PRIVATE (line 37) | static inline int
  function VALUE (line 78) | static VALUE
  function VALUE (line 147) | static VALUE
  function VALUE (line 182) | static VALUE
  function VALUE (line 201) | static VALUE
  function can_export_rsaprivatekey (line 211) | static int
  function VALUE (line 284) | static VALUE
  function VALUE (line 306) | static VALUE
  function VALUE (line 348) | static VALUE
  function VALUE (line 435) | static VALUE
  function Init_ossl_rsa (line 536) | void
  function Init_ossl_rsa (line 585) | void

FILE: ext/openssl/ossl_provider.c
  function VALUE (line 52) | static VALUE
  type ary_with_state (line 70) | struct ary_with_state { VALUE ary; int state; }
  type rb_push_provider_name_args (line 71) | struct rb_push_provider_name_args { OSSL_PROVIDER *prov; VALUE ary; }
  function VALUE (line 73) | static VALUE
  function push_provider (line 82) | static int
  function VALUE (line 102) | static VALUE
  function VALUE (line 128) | static VALUE
  function VALUE (line 154) | static VALUE
  function VALUE (line 172) | static VALUE
  function Init_ossl_provider (line 185) | void
  function Init_ossl_provider (line 200) | void

FILE: ext/openssl/ossl_rand.c
  function VALUE (line 21) | static VALUE
  function VALUE (line 52) | static VALUE
  function VALUE (line 67) | static VALUE
  function VALUE (line 84) | static VALUE
  function VALUE (line 105) | static VALUE
  function VALUE (line 130) | static VALUE
  function VALUE (line 148) | static VALUE
  function VALUE (line 166) | static VALUE
  function Init_ossl_rand (line 175) | void

FILE: ext/openssl/ossl_ssl.c
  function ossl_sslctx_mark (line 55) | static void
  function ossl_sslctx_free (line 62) | static void
  function VALUE (line 76) | static VALUE
  function VALUE (line 100) | static VALUE
  function ossl_client_cert_cb (line 118) | static int
  type tmp_dh_callback_args (line 135) | struct tmp_dh_callback_args {
  function VALUE (line 141) | static VALUE
  function DH (line 163) | static DH *
  function VALUE (line 178) | static VALUE
  function ossl_ssl_verify_callback (line 199) | static int
  function VALUE (line 228) | static VALUE
  function SSL_SESSION (line 242) | static SSL_SESSION *
  function VALUE (line 269) | static VALUE
  function ossl_sslctx_session_new_cb (line 284) | static int
  type ossl_call_keylog_cb_args (line 323) | struct ossl_call_keylog_cb_args {
  function VALUE (line 328) | static VALUE
  function ossl_sslctx_keylog_cb (line 344) | static void
  function VALUE (line 364) | static VALUE
  function ossl_sslctx_session_remove_cb (line 378) | static void
  function VALUE (line 412) | static VALUE
  function VALUE (line 430) | static VALUE
  function ssl_servername_cb (line 459) | static int
  function ssl_renegotiation_cb (line 474) | static void
  function VALUE (line 487) | static VALUE
  function VALUE (line 501) | static VALUE
  type npn_select_cb_common_args (line 509) | struct npn_select_cb_common_args {
  function VALUE (line 515) | static VALUE
  function ssl_npn_select_cb_common (line 542) | static int
  function ssl_npn_advertise_cb (line 570) | static int
  function ssl_npn_select_cb (line 582) | static int
  function ssl_alpn_select_cb (line 596) | static int
  function ssl_info_cb (line 609) | static void
  function VALUE (line 625) | static VALUE
  function VALUE (line 650) | static VALUE
  function VALUE (line 678) | static VALUE
  function parse_proto_version (line 856) | static int
  function VALUE (line 904) | static VALUE
  function VALUE (line 928) | static VALUE
  function VALUE (line 943) | static VALUE
  function VALUE (line 965) | static VALUE
  function VALUE (line 988) | static VALUE
  function VALUE (line 1025) | static VALUE
  function VALUE (line 1052) | static VALUE
  function VALUE (line 1086) | static VALUE
  function VALUE (line 1114) | static VALUE
  function VALUE (line 1149) | static VALUE
  function VALUE (line 1207) | static VALUE
  function VALUE (line 1229) | static VALUE
  function VALUE (line 1258) | static VALUE
  function VALUE (line 1279) | static VALUE
  function VALUE (line 1326) | static VALUE
  function VALUE (line 1376) | static VALUE
  function VALUE (line 1394) | static VALUE
  function VALUE (line 1412) | static VALUE
  function VALUE (line 1430) | static VALUE
  function VALUE (line 1449) | static VALUE
  function VALUE (line 1466) | static VALUE
  function VALUE (line 1500) | static VALUE
  function VALUE (line 1532) | static VALUE
  function ssl_started (line 1559) | static inline int
  function ossl_ssl_mark (line 1566) | static void
  function ossl_ssl_free (line 1573) | static void
  function VALUE (line 1587) | static VALUE
  function VALUE (line 1593) | static VALUE
  function VALUE (line 1601) | static VALUE
  function VALUE (line 1607) | static VALUE
  function VALUE (line 1635) | static VALUE
  function io_descriptor_fallback (line 1686) | static int
  function VALUE (line 1696) | static VALUE
  function errno_mapped (line 1717) | static int
  function write_would_block (line 1727) | static void
  function read_would_block (line 1734) | static void
  function no_exception_p (line 1741) | static int
  function io_wait_writable (line 1762) | static void
  function io_wait_readable (line 1776) | static void
  function VALUE (line 1790) | static VALUE
  function VALUE (line 1875) | static VALUE
  function VALUE (line 1905) | static VALUE
  function VALUE (line 1922) | static VALUE
  function VALUE (line 1952) | static VALUE
  function VALUE (line 1963) | static VALUE
  function VALUE (line 2068) | static VALUE
  function VALUE (line 2087) | static VALUE
  function VALUE (line 2093) | static VALUE
  function VALUE (line 2163) | static VALUE
  function VALUE (line 2190) | static VALUE
  function VALUE (line 2203) | static VALUE
  function VALUE (line 2220) | static VALUE
  function VALUE (line 2251) | static VALUE
  function VALUE (line 2277) | static VALUE
  function VALUE (line 2303) | static VALUE
  function VALUE (line 2333) | static VALUE
  function VALUE (line 2350) | static VALUE
  function VALUE (line 2368) | static VALUE
  function VALUE (line 2390) | static VALUE
  function VALUE (line 2406) | static VALUE
  function VALUE (line 2422) | static VALUE
  function VALUE (line 2444) | static VALUE
  function VALUE (line 2473) | static VALUE
  function VALUE (line 2490) | static VALUE
  function VALUE (line 2515) | static VALUE
  function VALUE (line 2544) | static VALUE
  function VALUE (line 2566) | static VALUE
  function VALUE (line 2590) | static VALUE
  function VALUE (line 2612) | static VALUE
  function VALUE (line 2655) | static VALUE
  function VALUE (line 2675) | static VALUE
  function VALUE (line 2694) | static VALUE
  function VALUE (line 2715) | static VALUE
  function Init_ossl_ssl (line 2730) | void

FILE: ext/openssl/ossl_ssl_session.c
  function ossl_ssl_session_free (line 11) | static void
  function VALUE (line 25) | static VALUE ossl_ssl_session_alloc(VALUE klass)
  function VALUE (line 38) | static VALUE
  function VALUE (line 73) | static VALUE
  function ossl_SSL_SESSION_cmp (line 93) | static int
  function VALUE (line 115) | static VALUE ossl_ssl_session_eq(VALUE val1, VALUE val2)
  function VALUE (line 134) | static VALUE
  function VALUE (line 156) | static VALUE
  function VALUE (line 176) | static VALUE ossl_ssl_session_set_time(VALUE self, VALUE time_v)
  function VALUE (line 196) | static VALUE ossl_ssl_session_set_timeout(VALUE self, VALUE time_v)
  function VALUE (line 213) | static VALUE ossl_ssl_session_get_id(VALUE self)
  function VALUE (line 232) | static VALUE ossl_ssl_session_to_der(VALUE self)
  function VALUE (line 258) | static VALUE ossl_ssl_session_to_pem(VALUE self)
  function VALUE (line 285) | static VALUE ossl_ssl_session_to_text(VALUE self)
  function Init_ossl_ssl_session (line 306) | void Init_ossl_ssl_session(void)

FILE: ext/openssl/ossl_ts.c
  function ossl_ts_req_free (line 75) | static void
  function ossl_ts_resp_free (line 89) | static void
  function ossl_ts_token_info_free (line 103) | static void
  function VALUE (line 117) | static VALUE
  function VALUE (line 135) | static VALUE
  function VALUE (line 141) | static VALUE
  function VALUE (line 168) | static VALUE
  function VALUE (line 199) | static VALUE
  function VALUE (line 224) | static VALUE
  function VALUE (line 250) | static VALUE
  function VALUE (line 273) | static VALUE
  function VALUE (line 294) | static VALUE
  function VALUE (line 310) | static VALUE
  function VALUE (line 332) | static VALUE
  function VALUE (line 355) | static VALUE
  function VALUE (line 379) | static VALUE
  function VALUE (line 399) | static VALUE
  function VALUE (line 422) | static VALUE
  function VALUE (line 438) | static VALUE
  function VALUE (line 455) | static VALUE
  function VALUE (line 479) | static VALUE
  function VALUE (line 498) | static VALUE
  function VALUE (line 522) | static VALUE
  function VALUE (line 549) | static VALUE
  function VALUE (line 588) | static VALUE
  function VALUE (line 627) | static VALUE
  function VALUE (line 656) | static VALUE
  function VALUE (line 674) | static VALUE
  function VALUE (line 703) | static VALUE
  function VALUE (line 727) | static VALUE
  function VALUE (line 736) | static VALUE
  function VALUE (line 775) | static VALUE
  function VALUE (line 852) | static VALUE
  function VALUE (line 876) | static VALUE
  function VALUE (line 903) | static VALUE
  function VALUE (line 924) | static VALUE
  function VALUE (line 946) | static VALUE
  function VALUE (line 973) | static VALUE
  function VALUE (line 997) | static VALUE
  function VALUE (line 1013) | static VALUE
  function VALUE (line 1039) | static VALUE
  function VALUE (line 1055) | static VALUE
  function VALUE (line 1074) | static VALUE
  function VALUE (line 1083) | static VALUE
  function ASN1_INTEGER (line 1102) | static ASN1_INTEGER *
  type TS_resp_ctx (line 1113) | struct TS_resp_ctx
  type TS_resp_ctx (line 1115) | struct TS_resp_ctx
  function VALUE (line 1123) | static VALUE
  function VALUE (line 1134) | static VALUE
  function VALUE (line 1164) | static VALUE
  function Init_ossl_ts (line 1298) | void
  function Init_ossl_ts (line 1547) | void

FILE: ext/openssl/ossl_x509.c
  function ASN1_TIME (line 19) | ASN1_TIME *
  function Init_ossl_x509 (line 30) | void

FILE: ext/openssl/ossl_x509attr.c
  function ossl_x509attr_free (line 33) | static void
  function VALUE (line 50) | VALUE
  function X509_ATTRIBUTE (line 66) | X509_ATTRIBUTE *
  function VALUE (line 79) | static VALUE
  function VALUE (line 97) | static VALUE
  function VALUE (line 123) | static VALUE
  function VALUE (line 146) | static VALUE
  function VALUE (line 173) | static VALUE
  function VALUE (line 186) | static VALUE
  function VALUE (line 228) | static VALUE
  function VALUE (line 266) | static VALUE
  function Init_ossl_x509attr (line 289) | void

FILE: ext/openssl/ossl_x509cert.c
  function ossl_x509_free (line 33) | static void
  function VALUE (line 50) | VALUE
  function X509 (line 66) | X509 *
  function X509 (line 76) | X509 *
  function VALUE (line 91) | static VALUE
  function VALUE (line 110) | static VALUE
  function VALUE (line 140) | static VALUE
  function VALUE (line 164) | static VALUE
  function VALUE (line 188) | static VALUE
  function VALUE (line 212) | static VALUE
  function VALUE (line 237) | static VALUE
  function VALUE (line 259) | static VALUE
  function VALUE (line 273) | static VALUE
  function VALUE (line 294) | static VALUE
  function VALUE (line 308) | static VALUE
  function VALUE (line 332) | static VALUE
  function VALUE (line 347) | static VALUE
  function VALUE (line 365) | static VALUE
  function VALUE (line 382) | static VALUE
  function VALUE (line 400) | static VALUE
  function VALUE (line 417) | static VALUE
  function VALUE (line 435) | static VALUE
  function VALUE (line 456) | static VALUE
  function VALUE (line 474) | static VALUE
  function VALUE (line 495) | static VALUE
  function VALUE (line 513) | static VALUE
  function VALUE (line 531) | static VALUE
  function VALUE (line 556) | static VALUE
  function VALUE (line 583) | static VALUE
  function VALUE (line 604) | static VALUE
  function VALUE (line 626) | static VALUE
  function VALUE (line 655) | static VALUE
  function VALUE (line 683) | static VALUE
  function VALUE (line 703) | static VALUE
  type load_chained_certificates_arguments (line 726) | struct load_chained_certificates_arguments {
  function VALUE (line 731) | static VALUE
  function VALUE (line 744) | static VALUE
  function VALUE (line 753) | inline static VALUE
  function VALUE (line 764) | static VALUE
  function VALUE (line 805) | static VALUE
  function VALUE (line 820) | static VALUE
  function VALUE (line 845) | static VALUE
  function VALUE (line 869) | static VALUE
  function Init_ossl_x509cert (line 880) | void

FILE: ext/openssl/ossl_x509crl.c
  function ossl_x509crl_free (line 33) | static void
  function X509_CRL (line 50) | X509_CRL *
  function VALUE (line 60) | VALUE
  function VALUE (line 79) | static VALUE
  function VALUE (line 94) | static VALUE
  function VALUE (line 123) | static VALUE
  function VALUE (line 141) | static VALUE
  function VALUE (line 153) | static VALUE
  function VALUE (line 179) | static VALUE
  function VALUE (line 192) | static VALUE
  function VALUE (line 202) | static VALUE
  function VALUE (line 215) | static VALUE
  function VALUE (line 229) | static VALUE
  function VALUE (line 246) | static VALUE
  function VALUE (line 260) | static VALUE
  function VALUE (line 277) | static VALUE
  function VALUE (line 300) | static VALUE
  function VALUE (line 330) | static VALUE
  function VALUE (line 347) | static VALUE
  function VALUE (line 365) | static VALUE
  function VALUE (line 385) | static VALUE
  function VALUE (line 403) | static VALUE
  function VALUE (line 421) | static VALUE
  function VALUE (line 442) | static VALUE
  function VALUE (line 463) | static VALUE
  function VALUE (line 488) | static VALUE
  function Init_ossl_x509crl (line 506) | void

FILE: ext/openssl/ossl_x509ext.c
  function ossl_x509ext_free (line 47) | static void
  function VALUE (line 64) | VALUE
  function X509_EXTENSION (line 80) | X509_EXTENSION *
  function ossl_x509extfactory_free (line 96) | static void
  function VALUE (line 110) | static VALUE
  function VALUE (line 122) | static VALUE
  function VALUE (line 134) | static VALUE
  function VALUE (line 146) | static VALUE
  function VALUE (line 158) | static VALUE
  function VALUE (line 170) | static VALUE
  function VALUE (line 199) | static VALUE
  function VALUE (line 242) | static VALUE
  function VALUE (line 269) | static VALUE
  function VALUE (line 295) | static VALUE
  function VALUE (line 314) | static VALUE
  function VALUE (line 333) | static VALUE
  function VALUE (line 360) | static VALUE
  function VALUE (line 378) | static VALUE
  function VALUE (line 387) | static VALUE
  function VALUE (line 404) | static VALUE
  function VALUE (line 417) | static VALUE
  function VALUE (line 426) | static VALUE
  function Init_ossl_x509ext (line 449) | void

FILE: ext/openssl/ossl_x509name.c
  function ossl_x509name_free (line 38) | static void
  function VALUE (line 55) | VALUE
  function X509_NAME (line 71) | X509_NAME *
  function VALUE (line 84) | static VALUE
  function VALUE (line 103) | static VALUE
  function VALUE (line 141) | static VALUE
  function VALUE (line 177) | static VALUE
  function VALUE (line 215) | static
  function VALUE (line 245) | static VALUE
  function VALUE (line 258) | static VALUE
  function VALUE (line 300) | static VALUE
  function VALUE (line 318) | static VALUE
  function VALUE (line 327) | static VALUE
  function VALUE (line 341) | static VALUE
  function ossl_x509name_cmp0 (line 365) | static int
  function VALUE (line 391) | static VALUE
  function VALUE (line 412) | static VALUE
  function VALUE (line 428) | static VALUE
  function VALUE (line 447) | static VALUE
  function VALUE (line 466) | static VALUE
  function Init_ossl_x509name (line 500) | void

FILE: ext/openssl/ossl_x509req.c
  function ossl_x509req_free (line 33) | static void
  function X509_REQ (line 50) | X509_REQ *
  function VALUE (line 63) | static VALUE
  function VALUE (line 78) | static VALUE
  function VALUE (line 107) | static VALUE
  function VALUE (line 125) | static VALUE
  function VALUE (line 143) | static VALUE
  function VALUE (line 163) | static VALUE
  function VALUE (line 185) | static VALUE
  function VALUE (line 201) | static VALUE
  function VALUE (line 213) | static VALUE
  function VALUE (line 230) | static VALUE
  function VALUE (line 244) | static VALUE
  function VALUE (line 267) | static VALUE
  function VALUE (line 280) | static VALUE
  function VALUE (line 294) | static VALUE
  function VALUE (line 308) | static VALUE
  function VALUE (line 329) | static VALUE
  function VALUE (line 349) | static VALUE
  function VALUE (line 373) | static VALUE
  function VALUE (line 398) | static VALUE
  function Init_ossl_x509req (line 414) | void

FILE: ext/openssl/ossl_x509revoked.c
  function ossl_x509rev_free (line 33) | static void
  function VALUE (line 50) | VALUE
  function X509_REVOKED (line 66) | X509_REVOKED *
  function VALUE (line 82) | static VALUE
  function VALUE (line 97) | static VALUE
  function VALUE (line 105) | static VALUE
  function VALUE (line 124) | static VALUE
  function VALUE (line 134) | static VALUE
  function VALUE (line 151) | static VALUE
  function VALUE (line 165) | static VALUE
  function VALUE (line 184) | static VALUE
  function VALUE (line 206) | static VALUE
  function VALUE (line 232) | static VALUE
  function VALUE (line 245) | static VALUE
  function Init_ossl_x509revoked (line 268) | void

FILE: ext/openssl/ossl_x509store.c
  type ossl_verify_cb_args (line 48) | struct ossl_verify_cb_args {
  function VALUE (line 54) | static VALUE
  function VALUE (line 60) | static VALUE
  function ossl_verify_cb_call (line 68) | int
  function ossl_x509store_mark (line 115) | static void
  function ossl_x509store_free (line 125) | static void
  function X509_STORE (line 142) | X509_STORE *
  function x509store_verify_cb (line 155) | static int
  function VALUE (line 170) | static VALUE
  function VALUE (line 187) | static VALUE
  function VALUE (line 208) | static VALUE
  function VALUE (line 242) | static VALUE
  function VALUE (line 277) | static VALUE
  function VALUE (line 301) | static VALUE
  function VALUE (line 325) | static VALUE
  function VALUE (line 347) | static VALUE
  function VALUE (line 373) | static VALUE
  function VALUE (line 404) | static VALUE
  function VALUE (line 424) | static VALUE
  function VALUE (line 446) | static VALUE
  function VALUE (line 479) | static VALUE
  function ossl_x509stctx_mark (line 502) | static void
  function ossl_x509stctx_free (line 512) | static void
  function VALUE (line 529) | static VALUE
  function VALUE (line 543) | static VALUE
  function VALUE (line 564) | static VALUE
  function VALUE (line 605) | static VALUE
  function VALUE (line 635) | static VALUE
  function VALUE (line 658) | static VALUE
  function VALUE (line 677) | static VALUE
  function VALUE (line 697) | static VALUE
  function VALUE (line 717) | static VALUE
  function VALUE (line 735) | static VALUE
  function VALUE (line 757) | static VALUE
  function VALUE (line 780) | static VALUE
  function VALUE (line 801) | static VALUE
  function VALUE (line 822) | static VALUE
  function VALUE (line 842) | static VALUE
  function Init_ossl_x509store (line 858) | void

FILE: lib/openssl.rb
  type OpenSSL (line 25) | module OpenSSL
    function secure_compare (line 36) | def self.secure_compare(a, b)

FILE: lib/openssl/bn.rb
  type OpenSSL (line 16) | module OpenSSL
    class BN (line 17) | class BN
      method pretty_print (line 20) | def pretty_print(q)
  class Integer (line 33) | class Integer
    method to_bn (line 37) | def to_bn

FILE: lib/openssl/buffering.rb
  type OpenSSL::Buffering (line 22) | module OpenSSL::Buffering
    class Buffer (line 26) | class Buffer < String
      method append_as_bytes (line 29) | def append_as_bytes(string)
    function initialize (line 59) | def initialize(*)
    function fill_rbuff (line 74) | def fill_rbuff
    function consume_rbuff (line 87) | def consume_rbuff(size=nil)
    function getbyte (line 102) | def getbyte
    function readbyte (line 107) | def readbyte
    function read (line 118) | def read(size=nil, buf=nil)
    function readpartial (line 145) | def readpartial(maxlen, buf=nil)
    function read_nonblock (line 203) | def read_nonblock(maxlen, buf=nil, exception: true)
    function gets (line 234) | def gets(eol=$/, limit=nil, chomp: false)
    function each (line 262) | def each(eol=$/)
    function readlines (line 274) | def readlines(eol=$/)
    function readline (line 287) | def readline(eol=$/)
    function getc (line 296) | def getc
    function each_byte (line 303) | def each_byte # :yields: byte
    function readchar (line 313) | def readchar
    function ungetc (line 326) | def ungetc(c)
    function eof? (line 334) | def eof?
    function do_write (line 349) | def do_write(s)
    function write (line 387) | def write(*s)
    function write_nonblock (line 431) | def write_nonblock(s, exception: true)
    function << (line 440) | def <<(s)
    function puts (line 450) | def puts(*args)
    function print (line 468) | def print(*args)
    function printf (line 481) | def printf(s, *args)
    function flush (line 489) | def flush
    function close (line 501) | def close

FILE: lib/openssl/cipher.rb
  type OpenSSL (line 15) | module OpenSSL
    class Cipher (line 16) | class Cipher
      method random_key (line 43) | def random_key
      method random_iv (line 55) | def random_iv
      class Cipher (line 64) | class Cipher < Cipher; end

FILE: lib/openssl/digest.rb
  type OpenSSL (line 15) | module OpenSSL
    class Digest (line 16) | class Digest
      method digest (line 25) | def self.digest(name, data)
      class Digest (line 48) | class Digest < Digest; end
    function Digest (line 63) | def Digest(name)
      method digest (line 25) | def self.digest(name, data)
      class Digest (line 48) | class Digest < Digest; end

FILE: lib/openssl/hmac.rb
  type OpenSSL (line 3) | module OpenSSL
    class HMAC (line 4) | class HMAC
      method == (line 6) | def ==(other)
      method base64digest (line 17) | def base64digest
      method digest (line 35) | def digest(digest, key, data)
      method hexdigest (line 54) | def hexdigest(digest, key, data)
      method base64digest (line 73) | def base64digest(digest, key, data)

FILE: lib/openssl/marshal.rb
  type OpenSSL (line 14) | module OpenSSL
    type Marshal (line 15) | module Marshal
      function included (line 16) | def self.included(base)
      type ClassMethods (line 20) | module ClassMethods
        function _load (line 21) | def _load(string)
      function _dump (line 26) | def _dump(_level)

FILE: lib/openssl/pkcs5.rb
  type OpenSSL (line 7) | module OpenSSL
    type PKCS5 (line 8) | module PKCS5
      function pbkdf2_hmac (line 13) | def pbkdf2_hmac(pass, salt, iter, keylen, digest)
      function pbkdf2_hmac_sha1 (line 18) | def pbkdf2_hmac_sha1(pass, salt, iter, keylen)

FILE: lib/openssl/pkey.rb
  type OpenSSL::PKey (line 9) | module OpenSSL::PKey
    class DH (line 13) | class DH
      method public_key (line 36) | def public_key
      method params (line 46) | def params
      method compute_key (line 64) | def compute_key(pub_bn)
      method generate_key! (line 106) | def generate_key!
      method generate (line 133) | def generate(size, generator = 2, &blk)
      method new (line 143) | def new(*args, &blk) # :nodoc:
    class DSA (line 156) | class DSA
      method public_key (line 171) | def public_key
      method params (line 181) | def params
      method generate (line 199) | def generate(size, &blk)
      method new (line 216) | def new(*args, &blk) # :nodoc:
      method syssign (line 250) | def syssign(string)
      method sysverify (line 269) | def sysverify(digest, sig)
    class EC (line 278) | class EC
      method dsa_sign_asn1 (line 286) | def dsa_sign_asn1(data)
      method dsa_verify_asn1 (line 295) | def dsa_verify_asn1(data, sig)
      method dh_compute_key (line 307) | def dh_compute_key(pubkey)
    class EC::Point (line 319) | class EC::Point
      method to_bn (line 330) | def to_bn(conversion_form = group.point_conversion_form)
    class RSA (line 339) | class RSA
      method public_key (line 353) | def public_key
      method params (line 363) | def params
      method generate (line 381) | def generate(size, exp = 0x10001, &blk)
      method new (line 390) | def new(*args, &blk) # :nodoc:
      method private_encrypt (line 411) | def private_encrypt(string, padding = PKCS1_PADDING)
      method public_decrypt (line 430) | def public_decrypt(string, padding = PKCS1_PADDING)
      method public_encrypt (line 448) | def public_encrypt(data, padding = PKCS1_PADDING)
      method private_decrypt (line 465) | def private_decrypt(data, padding = PKCS1_PADDING)
      method translate_padding_mode (line 478) | def translate_padding_mode(num)

FILE: lib/openssl/ssl.rb
  type OpenSSL (line 21) | module OpenSSL
    type SSL (line 22) | module SSL
      class SSLContext (line 23) | class SSLContext
        method initialize (line 94) | def initialize(version = nil)
        method set_params (line 112) | def set_params(params={})
        method ssl_version= (line 145) | def ssl_version=(meth)
      type SocketForwarder (line 176) | module SocketForwarder
        function fileno (line 178) | def fileno
        function addr (line 182) | def addr
        function peeraddr (line 186) | def peeraddr
        function local_address (line 190) | def local_address
        function remote_address (line 194) | def remote_address
        function setsockopt (line 198) | def setsockopt(level, optname, optval)
        function getsockopt (line 202) | def getsockopt(level, optname)
        function fcntl (line 206) | def fcntl(*args)
        function closed? (line 210) | def closed?
        function do_not_reverse_lookup= (line 214) | def do_not_reverse_lookup=(flag)
        function close_on_exec= (line 218) | def close_on_exec=(value)
        function close_on_exec? (line 222) | def close_on_exec?
        function wait (line 226) | def wait(*args)
        function wait_readable (line 230) | def wait_readable(*args)
        function wait_writable (line 234) | def wait_writable(*args)
        function timeout (line 239) | def timeout
        function timeout= (line 243) | def timeout=(value)
      function verify_certificate_identity (line 249) | def verify_certificate_identity(cert, hostname)
      function verify_hostname (line 282) | def verify_hostname(hostname, san) # :nodoc:
      function verify_wildcard (line 315) | def verify_wildcard(domain_component, san_component) # :nodoc:
      class SSLSocket (line 333) | class SSLSocket
        method sysclose (line 357) | def sysclose
        method post_connection_check (line 370) | def post_connection_check(hostname)
        method session (line 391) | def session
        method close_read (line 400) | def close_read
        method close_write (line 419) | def close_write
        method using_anon_cipher? (line 425) | def using_anon_cipher?
        method client_cert_cb (line 431) | def client_cert_cb
        method session_new_cb (line 435) | def session_new_cb
        method session_get_cb (line 439) | def session_get_cb
        method open (line 465) | def open(remote_host, remote_port, local_host=nil, local_port=nil,...
      class SSLServer (line 478) | class SSLServer
        method initialize (line 486) | def initialize(svr, ctx)
        method to_io (line 499) | def to_io
        method listen (line 504) | def listen(backlog=Socket::SOMAXCONN)
        method shutdown (line 509) | def shutdown(how=Socket::SHUT_RDWR)
        method accept (line 514) | def accept
        method close (line 535) | def close

FILE: lib/openssl/version.rb
  type OpenSSL (line 3) | module OpenSSL

FILE: lib/openssl/x509.rb
  type OpenSSL (line 17) | module OpenSSL
    type X509 (line 18) | module X509
      class ExtensionFactory (line 19) | class ExtensionFactory
        method create_extension (line 20) | def create_extension(*arg)
        method create_ext_from_array (line 28) | def create_ext_from_array(ary)
        method create_ext_from_string (line 33) | def create_ext_from_string(str) # "oid = critical, value"
        method create_ext_from_hash (line 40) | def create_ext_from_hash(hash)
      class Extension (line 45) | class Extension
        method == (line 48) | def ==(other)
        method to_s (line 53) | def to_s # "oid = critical, value"
        method to_h (line 60) | def to_h # {"oid"=>sn|ln, "value"=>value, "critical"=>true|false}
        method to_a (line 64) | def to_a
        type Helpers (line 68) | module Helpers
          function find_extension (line 69) | def find_extension(oid)
        type SubjectKeyIdentifier (line 74) | module SubjectKeyIdentifier
          function subject_key_identifier (line 82) | def subject_key_identifier
        type AuthorityKeyIdentifier (line 95) | module AuthorityKeyIdentifier
          function authority_key_identifier (line 104) | def authority_key_identifier
        type CRLDistributionPoints (line 121) | module CRLDistributionPoints
          function crl_uris (line 129) | def crl_uris
        type AuthorityInfoAccess (line 154) | module AuthorityInfoAccess
          function ca_issuer_uris (line 162) | def ca_issuer_uris
          function ocsp_uris (line 177) | def ocsp_uris
          function parse_aia_asn1 (line 190) | def parse_aia_asn1
      class Name (line 204) | class Name
        type RFC2253DN (line 207) | module RFC2253DN
          function expand_pair (line 225) | def expand_pair(str)
          function expand_hexstring (line 237) | def expand_hexstring(str)
          function expand_value (line 244) | def expand_value(str1, str2, str3)
          function scan (line 251) | def scan(dn)
        method parse_rfc2253 (line 286) | def parse_rfc2253(str, template=OBJECT_TYPE_TEMPLATE)
        method parse_openssl (line 305) | def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE)
        method pretty_print (line 319) | def pretty_print(q)
      class Attribute (line 327) | class Attribute
        method == (line 330) | def ==(other)
      class StoreContext (line 336) | class StoreContext
        method cleanup (line 337) | def cleanup
      class Certificate (line 342) | class Certificate
        method inspect (line 349) | def inspect
        method pretty_print (line 358) | def pretty_print(q)
        method load_file (line 369) | def self.load_file(path)
      class CRL (line 374) | class CRL
        method == (line 378) | def ==(other)
      class Revoked (line 384) | class Revoked
        method == (line 385) | def ==(other)
      class Request (line 391) | class Request
        method == (line 394) | def ==(other)

FILE: sample/c_rehash.rb
  class CHashDir (line 5) | class CHashDir
    method initialize (line 8) | def initialize(dirpath)
    method hash_dir (line 13) | def hash_dir(silent = false)
    method get_certs (line 22) | def get_certs(name = nil)
    method get_crls (line 30) | def get_crls(name = nil)
    method delete_crl (line 38) | def delete_crl(crl)
    method add_crl (line 43) | def add_crl(crl)
    method load_pem_file (line 50) | def load_pem_file(filepath)
    method crl_filename (line 69) | def crl_filename(crl)
    method do_hash_dir (line 73) | def do_hash_dir
    method delete_symlink (line 90) | def delete_symlink
    method link_hash_cert (line 97) | def link_hash_cert(org_filename, cert)
    method link_hash_crl (line 112) | def link_hash_crl(org_filename, crl)
    method link_hash (line 127) | def link_hash(org_filename, name, fingerprint)
    method symlink (line 144) | def symlink(from, to)
    method path (line 154) | def path(filename)
    method hash_name (line 158) | def hash_name(name)
    method fingerprint (line 162) | def fingerprint(der)

FILE: sample/cert2text.rb
  function cert2text (line 5) | def cert2text(cert_str)

FILE: sample/certstore.rb
  class CertStore (line 5) | class CertStore
    method initialize (line 12) | def initialize(certs_dir)
    method generate_cert (line 27) | def generate_cert(filename)
    method verify (line 31) | def verify(cert)
    method match_cert (line 40) | def match_cert(cert1, cert2)
    method is_ca? (line 44) | def is_ca?(cert)
    method scan_certs (line 55) | def scan_certs
    method add_path (line 66) | def add_path
    method do_verify (line 70) | def do_verify(cert)
    method load_certs (line 100) | def load_certs
    method guess_cert_type (line 122) | def guess_cert_type(cert)
    method is_cert_self_signed (line 149) | def is_cert_self_signed(cert)

FILE: sample/cipher.rb
  function crypt_by_password (line 4) | def crypt_by_password(alg, pass, salt, text)
  function ciphers (line 31) | def ciphers

FILE: sample/crlstore.rb
  class CrlStore (line 9) | class CrlStore
    method initialize (line 10) | def initialize(c_store)
    method find_crl (line 15) | def find_crl(cert)
    method do_find_crl (line 21) | def do_find_crl(cert)
    method find_ca (line 48) | def find_ca(cert)
    method fetch (line 58) | def fetch(location)
    method load_cert (line 71) | def load_cert(certfile)
    method load_crl (line 75) | def load_crl(crlfile)
    method load_cert_str (line 79) | def load_cert_str(cert_str)
    method load_crl_str (line 83) | def load_crl_str(crl_str)
    method check_valid (line 87) | def check_valid(crl, ca)
    method get_cdp (line 95) | def get_cdp(cert)
    method renew_crl (line 103) | def renew_crl(cert, ca)

FILE: sample/gen_csr.rb
  function usage (line 6) | def usage

FILE: test/openssl/test_asn1.rb
  class OpenSSL::TestASN1 (line 6) | class  OpenSSL::TestASN1 < OpenSSL::TestCase
    method test_decode_x509_certificate (line 7) | def test_decode_x509_certificate
    method test_decode_all (line 196) | def test_decode_all
    method test_object_id_register (line 206) | def test_object_id_register
    method test_end_of_content (line 218) | def test_end_of_content
    method test_boolean (line 225) | def test_boolean
    method test_integer (line 234) | def test_integer
    method test_enumerated (line 252) | def test_enumerated
    method test_bitstring (line 259) | def test_bitstring
    method test_string_basic (line 282) | def test_string_basic
    method test_null (line 301) | def test_null
    method test_object_identifier (line 308) | def test_object_identifier
    method test_object_identifier_equality (line 336) | def test_object_identifier_equality
    method test_sequence (line 369) | def test_sequence
    method test_set (line 404) | def test_set
    method test_utctime (line 416) | def test_utctime
    method test_generalizedtime (line 453) | def test_generalizedtime
    method test_basic_asn1data (line 500) | def test_basic_asn1data
    method test_basic_primitive (line 526) | def test_basic_primitive
    method test_basic_constructed (line 538) | def test_basic_constructed
    method test_prim_explicit_tagging (line 552) | def test_prim_explicit_tagging
    method test_prim_implicit_tagging (line 567) | def test_prim_implicit_tagging
    method test_cons_explicit_tagging (line 583) | def test_cons_explicit_tagging
    method test_cons_implicit_tagging (line 597) | def test_cons_implicit_tagging
    method test_octet_string_constructed_tagging (line 616) | def test_octet_string_constructed_tagging
    method test_recursive_octet_string_indefinite_length (line 628) | def test_recursive_octet_string_indefinite_length
    method test_recursive_octet_string_parse (line 648) | def test_recursive_octet_string_parse
    method test_decode_constructed_overread (line 676) | def test_decode_constructed_overread
    method test_constructive_each (line 699) | def test_constructive_each
    method B (line 713) | def B(ary)
    method assert_asn1_equal (line 717) | def assert_asn1_equal(a, b)
    method encode_test (line 738) | def encode_test(der, obj)
    method decode_test (line 742) | def decode_test(der, obj)
    method encode_decode_test (line 748) | def encode_decode_test(der, obj)
    method assert_universal (line 753) | def assert_universal(tag, asn1)

FILE: test/openssl/test_bn.rb
  class OpenSSL::TestBN (line 7) | class OpenSSL::TestBN < OpenSSL::TestCase
    method setup (line 8) | def setup
    method test_new (line 16) | def test_new
    method test_to_str (line 52) | def test_to_str
    method test_to_int (line 75) | def test_to_int
    method test_coerce (line 84) | def test_coerce
    method test_zero_p (line 90) | def test_zero_p
    method test_one_p (line 95) | def test_one_p
    method test_odd_p (line 100) | def test_odd_p
    method test_negative_p (line 105) | def test_negative_p
    method test_sqr (line 111) | def test_sqr
    method test_four_ops (line 116) | def test_four_ops
    method test_unary_plus_minus (line 128) | def test_unary_plus_minus
    method test_abs (line 143) | def test_abs
    method test_mod (line 156) | def test_mod
    method test_exp (line 162) | def test_exp
    method test_gcd (line 167) | def test_gcd
    method test_mod_sqr (line 172) | def test_mod_sqr
    method test_mod_sqrt (line 177) | def test_mod_sqrt
    method test_mod_inverse (line 185) | def test_mod_inverse
    method test_mod_add (line 190) | def test_mod_add
    method test_mod_sub (line 196) | def test_mod_sub
    method test_mod_mul (line 202) | def test_mod_mul
    method test_mod_exp (line 207) | def test_mod_exp
    method test_bit_operations (line 212) | def test_bit_operations
    method test_random (line 244) | def test_random
    method test_prime (line 268) | def test_prime
    method test_num_bits_bytes (line 290) | def test_num_bits_bytes
    method test_comparison (line 301) | def test_comparison
    method test_argument_error (line 318) | def test_argument_error
    method test_get_flags_and_set_flags (line 323) | def test_get_flags_and_set_flags
    method test_ractor (line 358) | def test_ractor

FILE: test/openssl/test_buffering.rb
  class OpenSSL::TestBuffering (line 6) | class OpenSSL::TestBuffering < OpenSSL::TestCase
    class IO (line 7) | class IO
      method initialize (line 12) | def initialize
      method string (line 23) | def string
      method sysread (line 27) | def sysread(size)
      method syswrite (line 33) | def syswrite(str)
    method setup (line 39) | def setup
    method test_encoding (line 44) | def test_encoding
    method test_flush (line 51) | def test_flush
    method test_flush_error (line 63) | def test_flush_error
    method test_getc (line 80) | def test_getc
    method test_each_byte (line 87) | def test_each_byte

FILE: test/openssl/test_cipher.rb
  class OpenSSL::TestCipher (line 6) | class OpenSSL::TestCipher < OpenSSL::TestCase
    type Helper (line 7) | module Helper
      function has_cipher? (line 8) | def has_cipher?(name)
    method test_encrypt_decrypt (line 16) | def test_encrypt_decrypt
    method test_pkcs5_keyivgen (line 30) | def test_pkcs5_keyivgen
    method test_info (line 52) | def test_info
    method test_dup (line 59) | def test_dup
    method test_reset (line 71) | def test_reset
    method test_key_iv_set (line 82) | def test_key_iv_set
    method test_random_key_iv (line 92) | def test_random_key_iv
    method test_initialize (line 111) | def test_initialize
    method test_ctr_if_exists (line 120) | def test_ctr_if_exists
    method test_update_with_buffer (line 134) | def test_update_with_buffer
    method test_ciphers (line 159) | def test_ciphers
    method test_AES (line 167) | def test_AES
    method test_update_raise_if_key_not_set (line 182) | def test_update_raise_if_key_not_set
    method test_auth_tag_error_inheritance (line 189) | def test_auth_tag_error_inheritance
    method test_authenticated (line 193) | def test_authenticated
    method test_aes_ccm (line 200) | def test_aes_ccm
    method test_aes_gcm (line 243) | def test_aes_gcm
    method test_aes_gcm_variable_iv_len (line 292) | def test_aes_gcm_variable_iv_len
    method test_aes_ocb_tag_len (line 315) | def test_aes_ocb_tag_len
    method test_aes_gcm_siv (line 352) | def test_aes_gcm_siv
    method test_aes_gcm_key_iv_order_issue (line 373) | def test_aes_gcm_key_iv_order_issue
    method test_aes_keywrap_pad (line 391) | def test_aes_keywrap_pad
    method test_non_aead_cipher_set_auth_data (line 407) | def test_non_aead_cipher_set_auth_data
    method test_crypt_after_key (line 414) | def test_crypt_after_key
    method new_encryptor (line 431) | def new_encryptor(algo, **kwargs)
    method new_decryptor (line 438) | def new_decryptor(algo, **kwargs)

FILE: test/openssl/test_config.rb
  class OpenSSL::TestConfig (line 6) | class OpenSSL::TestConfig < OpenSSL::TestCase
    method setup (line 7) | def setup
    method teardown (line 23) | def teardown
    method test_constants (line 28) | def test_constants
    method test_s_parse (line 37) | def test_s_parse
    method test_s_parse_format (line 45) | def test_s_parse_format
    method test_s_parse_include (line 123) | def test_s_parse_include
    method test_s_load (line 171) | def test_s_load
    method test_s_parse_config (line 185) | def test_s_parse_config
    method test_initialize (line 191) | def test_initialize
    method test_initialize_with_empty_file (line 198) | def test_initialize_with_empty_file
    method test_initialize_with_example_file (line 207) | def test_initialize_with_example_file
    method test_get_value (line 211) | def test_get_value
    method test_get_value_ENV (line 225) | def test_get_value_ENV
    method test_aref (line 234) | def test_aref
    method test_sections (line 241) | def test_sections
    method test_each (line 256) | def test_each
    method test_to_s (line 266) | def test_to_s
    method test_inspect (line 271) | def test_inspect
    method test_dup (line 275) | def test_dup
    method test_ractor (line 287) | def test_ractor
    method in_tmpdir (line 296) | def in_tmpdir(*args)

FILE: test/openssl/test_digest.rb
  class OpenSSL::TestDigest (line 6) | class OpenSSL::TestDigest < OpenSSL::TestCase
    method setup (line 7) | def setup
    method test_initialize (line 13) | def test_initialize
    method test_digest (line 19) | def test_digest
    method test_eql (line 36) | def test_eql
    method test_info (line 42) | def test_info
    method test_dup (line 48) | def test_dup
    method test_reset (line 55) | def test_reset
    method test_digest_constants (line 64) | def test_digest_constants
    method test_digest_by_oid_and_name (line 75) | def test_digest_by_oid_and_name
    method encode16 (line 89) | def encode16(str)
    method test_sha2 (line 93) | def test_sha2
    method test_sha512_truncate (line 110) | def test_sha512_truncate
    method test_sha3 (line 121) | def test_sha3
    method test_fetched_evp_md (line 132) | def test_fetched_evp_md
    method test_openssl_digest (line 142) | def test_openssl_digest
    method test_digests (line 150) | def test_digests

FILE: test/openssl/test_engine.rb
  class OpenSSL::TestEngine (line 6) | class OpenSSL::TestEngine < OpenSSL::TestCase
    method test_engines_free (line 7) | def test_engines_free # [ruby-dev:44173]
    method test_openssl_engine_builtin (line 15) | def test_openssl_engine_builtin
    method test_openssl_engine_by_id_string (line 25) | def test_openssl_engine_by_id_string
    method test_openssl_engine_id_name_inspect (line 35) | def test_openssl_engine_id_name_inspect
    method test_openssl_engine_digest_sha1 (line 44) | def test_openssl_engine_digest_sha1
    method test_openssl_engine_cipher_rc4 (line 54) | def test_openssl_engine_cipher_rc4
    method with_openssl (line 84) | def with_openssl(code, **opts)

FILE: test/openssl/test_fips.rb
  class OpenSSL::TestFIPS (line 6) | class OpenSSL::TestFIPS < OpenSSL::TestCase
    method test_fips_mode_get_is_true_on_fips_mode_enabled (line 7) | def test_fips_mode_get_is_true_on_fips_mode_enabled
    method test_fips_mode_get_is_false_on_fips_mode_disabled (line 17) | def test_fips_mode_get_is_false_on_fips_mode_disabled
    method test_fips_mode_is_reentrant (line 30) | def test_fips_mode_is_reentrant
    method test_fips_mode_get_with_fips_mode_set (line 39) | def test_fips_mode_get_with_fips_mode_set

FILE: test/openssl/test_hmac.rb
  class OpenSSL::TestHMAC (line 6) | class OpenSSL::TestHMAC < OpenSSL::TestCase
    method test_hmac (line 7) | def test_hmac
    method test_dup (line 23) | def test_dup
    method test_binary_update (line 30) | def test_binary_update
    method test_reset_keep_key (line 37) | def test_reset_keep_key
    method test_eq (line 45) | def test_eq
    method test_singleton_methods (line 55) | def test_singleton_methods
    method test_zero_length_key (line 66) | def test_zero_length_key

FILE: test/openssl/test_kdf.rb
  class OpenSSL::TestKDF (line 6) | class OpenSSL::TestKDF < OpenSSL::TestCase
    method test_pkcs5_pbkdf2_hmac_compatibility (line 7) | def test_pkcs5_pbkdf2_hmac_compatibility
    method test_pbkdf2_hmac_sha1_rfc6070_c_1_len_20 (line 13) | def test_pbkdf2_hmac_sha1_rfc6070_c_1_len_20
    method test_pbkdf2_hmac_sha1_rfc6070_c_2_len_20 (line 26) | def test_pbkdf2_hmac_sha1_rfc6070_c_2_len_20
    method test_pbkdf2_hmac_sha1_rfc6070_c_4096_len_20 (line 39) | def test_pbkdf2_hmac_sha1_rfc6070_c_4096_len_20
    method test_pbkdf2_hmac_sha1_rfc6070_c_4096_len_25 (line 66) | def test_pbkdf2_hmac_sha1_rfc6070_c_4096_len_25
    method test_pbkdf2_hmac_sha1_rfc6070_c_4096_len_16 (line 81) | def test_pbkdf2_hmac_sha1_rfc6070_c_4096_len_16
    method test_pbkdf2_hmac_sha256_c_20000_len_32 (line 93) | def test_pbkdf2_hmac_sha256_c_20000_len_32
    method test_scrypt_rfc7914_first (line 104) | def test_scrypt_rfc7914_first
    method test_scrypt_rfc7914_second (line 119) | def test_scrypt_rfc7914_second
    method test_hkdf_rfc5869_test_case_1 (line 134) | def test_hkdf_rfc5869_test_case_1
    method test_hkdf_rfc5869_test_case_3 (line 147) | def test_hkdf_rfc5869_test_case_3
    method test_hkdf_rfc5869_test_case_4 (line 160) | def test_hkdf_rfc5869_test_case_4
    method B (line 175) | def B(ary)

FILE: test/openssl/test_ns_spki.rb
  class OpenSSL::TestNSSPI (line 6) | class OpenSSL::TestNSSPI < OpenSSL::TestCase
    method setup (line 7) | def setup
    method test_build_data (line 19) | def test_build_data
    method test_decode_data (line 38) | def test_decode_data

FILE: test/openssl/test_ocsp.rb
  class OpenSSL::TestOCSP (line 6) | class OpenSSL::TestOCSP < OpenSSL::TestCase
    method setup (line 7) | def setup
    method test_new_certificate_id (line 49) | def test_new_certificate_id
    method test_certificate_id_issuer_name_hash (line 58) | def test_certificate_id_issuer_name_hash
    method test_certificate_id_issuer_key_hash (line 64) | def test_certificate_id_issuer_key_hash
    method test_certificate_id_hash_algorithm (line 72) | def test_certificate_id_hash_algorithm
    method test_certificate_id_der (line 79) | def test_certificate_id_der
    method test_certificate_id_dup (line 92) | def test_certificate_id_dup
    method test_request_der (line 97) | def test_request_der
    method test_request_sign_verify (line 110) | def test_request_sign_verify
    method test_request_is_signed (line 135) | def test_request_is_signed
    method test_request_nonce (line 146) | def test_request_nonce
    method test_request_dup (line 160) | def test_request_dup
    method test_basic_response_der (line 167) | def test_basic_response_der
    method test_basic_response_sign_verify (line 185) | def test_basic_response_sign_verify
    method test_basic_response_dup (line 210) | def test_basic_response_dup
    method test_basic_response_status_good (line 218) | def test_basic_response_status_good
    method test_basic_response_status_revoked (line 232) | def test_basic_response_status_revoked
    method test_basic_response_response_operations (line 247) | def test_basic_response_response_operations
    method test_single_response_der (line 270) | def test_single_response_der
    method test_single_response_check_validity (line 282) | def test_single_response_check_validity
    method test_response (line 302) | def test_response
    method test_response_der (line 313) | def test_response_der
    method test_response_dup (line 327) | def test_response_dup

FILE: test/openssl/test_ossl.rb
  class OpenSSL::TestOSSL (line 6) | class OpenSSL::TestOSSL < OpenSSL::TestCase
    method test_fixed_length_secure_compare (line 7) | def test_fixed_length_secure_compare
    method test_fixed_length_secure_compare_uaf (line 27) | def test_fixed_length_secure_compare_uaf
    method test_secure_compare (line 37) | def test_secure_compare
    method test_memcmp_timing (line 54) | def test_memcmp_timing
    method test_error_data (line 78) | def test_error_data

FILE: test/openssl/test_pair.rb
  type OpenSSL::SSLPairM (line 7) | module OpenSSL::SSLPairM
    function setup (line 8) | def setup
    function ssl_pair (line 17) | def ssl_pair
  type OpenSSL::SSLPair (line 46) | module OpenSSL::SSLPair
    function create_tcp_server (line 49) | def create_tcp_server(host, port)
    function create_tcp_client (line 53) | def create_tcp_client(host, port)
  type OpenSSL::SSLPairLowlevelSocket (line 58) | module OpenSSL::SSLPairLowlevelSocket
    function create_tcp_server (line 61) | def create_tcp_server(host, port)
    function create_tcp_client (line 65) | def create_tcp_client(host, port)
  type OpenSSL::TestEOF1M (line 70) | module OpenSSL::TestEOF1M
    function open_file (line 71) | def open_file(content)
  type OpenSSL::TestEOF2M (line 83) | module OpenSSL::TestEOF2M
    function open_file (line 84) | def open_file(content)
  type OpenSSL::TestPairM (line 96) | module OpenSSL::TestPairM
    function test_getc (line 97) | def test_getc
    function test_getbyte (line 104) | def test_getbyte
    function test_readbyte (line 111) | def test_readbyte
    function test_readbyte_eof (line 118) | def test_readbyte_eof
    function test_gets (line 125) | def test_gets
    function test_gets_chomp (line 139) | def test_gets_chomp
    function test_gets_eof_limit (line 150) | def test_gets_eof_limit
    function test_readpartial (line 158) | def test_readpartial
    function test_readall (line 176) | def test_readall
    function test_readline (line 183) | def test_readline
    function test_puts_empty (line 190) | def test_puts_empty
    function test_multibyte_read_write (line 198) | def test_multibyte_read_write
    function test_read_nonblock (line 219) | def test_read_nonblock
    function test_read_nonblock_no_exception (line 243) | def test_read_nonblock_no_exception
    function test_read_with_outbuf (line 259) | def test_read_with_outbuf
    function test_write_nonblock (line 288) | def test_write_nonblock
    function test_write_nonblock_no_exceptions (line 307) | def test_write_nonblock_no_exceptions
    function test_write_nonblock_with_buffered_data (line 327) | def test_write_nonblock_with_buffered_data
    function test_write_nonblock_with_buffered_data_no_exceptions (line 337) | def test_write_nonblock_with_buffered_data_no_exceptions
    function test_write_nonblock_retry (line 347) | def test_write_nonblock_retry
    function test_write_zero (line 376) | def test_write_zero
    function test_write_multiple_arguments (line 387) | def test_write_multiple_arguments
    function test_partial_tls_record_read_nonblock (line 396) | def test_partial_tls_record_read_nonblock
    function tcp_pair (line 406) | def tcp_pair
    function test_connect_accept_nonblock_no_exception (line 418) | def test_connect_accept_nonblock_no_exception
    function test_connect_accept_nonblock (line 465) | def test_connect_accept_nonblock
  class OpenSSL::TestEOF1 (line 509) | class OpenSSL::TestEOF1 < OpenSSL::TestCase
  class OpenSSL::TestEOF1LowlevelSocket (line 515) | class OpenSSL::TestEOF1LowlevelSocket < OpenSSL::TestCase
  class OpenSSL::TestEOF2 (line 521) | class OpenSSL::TestEOF2 < OpenSSL::TestCase
  class OpenSSL::TestEOF2LowlevelSocket (line 527) | class OpenSSL::TestEOF2LowlevelSocket < OpenSSL::TestCase
  class OpenSSL::TestPair (line 533) | class OpenSSL::TestPair < OpenSSL::TestCase
  class OpenSSL::TestPairLowlevelSocket (line 538) | class OpenSSL::TestPairLowlevelSocket < OpenSSL::TestCase

FILE: test/openssl/test_pkcs12.rb
  type OpenSSL (line 29) | module OpenSSL
    class TestPKCS12 (line 30) | class TestPKCS12 < OpenSSL::TestCase
      method setup (line 34) | def setup
      method test_create_single_key_single_cert (line 59) | def test_create_single_key_single_cert
      method test_create_no_pass (line 80) | def test_create_no_pass
      method test_create_with_chain (line 98) | def test_create_with_chain
      method test_create_with_chain_decode (line 113) | def test_create_with_chain_decode
      method test_create_with_bad_nid (line 136) | def test_create_with_bad_nid
      method test_create_with_itr (line 149) | def test_create_with_itr
      method test_create_with_mac_itr (line 175) | def test_create_with_mac_itr
      method test_create_with_keytype (line 203) | def test_create_with_keytype
      method test_new_with_no_keys (line 235) | def test_new_with_no_keys
      method test_new_with_no_certs (line 289) | def test_new_with_no_certs
      method test_dup (line 360) | def test_dup
      method test_set_mac_pkcs12kdf (line 373) | def test_set_mac_pkcs12kdf
      method macdata (line 401) | def macdata(p12)

FILE: test/openssl/test_pkcs7.rb
  class OpenSSL::TestPKCS7 (line 6) | class OpenSSL::TestPKCS7 < OpenSSL::TestCase
    method setup (line 7) | def setup
    method test_signed (line 32) | def test_signed
    method test_signed_flags (line 67) | def test_signed_flags
    method test_signed_multiple_signers (line 96) | def test_signed_multiple_signers
    method test_signed_add_signer (line 125) | def test_signed_add_signer
    method test_detached_sign (line 143) | def test_detached_sign
    method test_signed_authenticated_attributes (line 175) | def test_signed_authenticated_attributes
    method test_enveloped (line 219) | def test_enveloped
    method test_enveloped_add_recipient (line 253) | def test_enveloped_add_recipient
    method test_data (line 275) | def test_data
    method test_empty_signed_data_ruby_bug_19974 (line 305) | def test_empty_signed_data_ruby_bug_19974
    method test_graceful_parsing_failure (line 320) | def test_graceful_parsing_failure #[ruby-core:43250]
    method test_set_type_signed (line 325) | def test_set_type_signed
    method test_set_type_data (line 331) | def test_set_type_data
    method test_set_type_signed_and_enveloped (line 337) | def test_set_type_signed_and_enveloped
    method test_set_type_encrypted (line 343) | def test_set_type_encrypted
    method test_smime (line 349) | def test_smime
    method test_to_text (line 373) | def test_to_text
    method test_degenerate_pkcs7 (line 381) | def test_degenerate_pkcs7
    method test_decode_ber_constructed_string (line 418) | def test_decode_ber_constructed_string

FILE: test/openssl/test_pkey.rb
  class OpenSSL::TestPKey (line 4) | class OpenSSL::TestPKey < OpenSSL::PKeyTestCase
    method test_generic_oid_inspect_rsa (line 5) | def test_generic_oid_inspect_rsa
    method test_s_generate_parameters (line 14) | def test_s_generate_parameters
    method test_s_generate_parameters_with_block (line 28) | def test_s_generate_parameters_with_block
    method test_s_generate_key (line 49) | def test_s_generate_key
    method test_s_read_pem_unknown_block (line 63) | def test_s_read_pem_unknown_block
    method test_s_read_der_then_pem (line 75) | def test_s_read_der_then_pem
    method test_s_read_passphrase (line 88) | def test_s_read_passphrase
    method test_s_read_passphrase_tty (line 129) | def test_s_read_passphrase_tty
    method test_hmac_sign_verify (line 168) | def test_hmac_sign_verify
    method test_ed25519 (line 180) | def test_ed25519
    method test_x25519 (line 232) | def test_x25519
    method test_ml_dsa (line 269) | def test_ml_dsa
    method test_raw_initialize_errors (line 288) | def test_raw_initialize_errors
    method test_compare? (line 295) | def test_compare?
    method test_to_text (line 313) | def test_to_text
    method test_legacy_error_classes (line 318) | def test_legacy_error_classes

FILE: test/openssl/test_pkey_dh.rb
  class OpenSSL::TestPKeyDH (line 6) | class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
    method test_new_empty (line 7) | def test_new_empty
    method test_new_generate (line 18) | def test_new_generate
    method test_new_break (line 34) | def test_new_break
    method test_derive_key (line 46) | def test_derive_key
    method test_DHparams (line 64) | def test_DHparams
    method test_public_key (line 101) | def test_public_key
    method test_generate_key (line 109) | def test_generate_key
    method test_params_ok? (line 122) | def test_params_ok?
    method test_params (line 159) | def test_params
    method test_dup (line 178) | def test_dup
    method test_marshal (line 207) | def test_marshal
    method assert_no_key (line 216) | def assert_no_key(dh)
    method assert_key (line 223) | def assert_key(dh)
    method assert_same_dh_params (line 230) | def assert_same_dh_params(expected, key)

FILE: test/openssl/test_pkey_dsa.rb
  class OpenSSL::TestPKeyDSA (line 6) | class OpenSSL::TestPKeyDSA < OpenSSL::PKeyTestCase
    method setup (line 7) | def setup
    method test_private (line 12) | def test_private
    method test_new (line 23) | def test_new
    method test_new_break (line 29) | def test_new_break
    method test_new_empty (line 36) | def test_new_empty
    method test_generate (line 47) | def test_generate
    method test_sign_verify (line 66) | def test_sign_verify
    method test_sign_verify_raw (line 88) | def test_sign_verify_raw
    method test_DSAPrivateKey (line 115) | def test_DSAPrivateKey
    method test_DSAPrivateKey_encrypted (line 138) | def test_DSAPrivateKey_encrypted
    method test_PUBKEY (line 156) | def test_PUBKEY
    method test_read_DSAPublicKey_pem (line 190) | def test_read_DSAPublicKey_pem
    method test_params (line 215) | def test_params
    method test_dup (line 236) | def test_dup
    method test_marshal (line 248) | def test_marshal
    method assert_same_dsa (line 256) | def assert_same_dsa(expected, key)

FILE: test/openssl/test_pkey_ec.rb
  class OpenSSL::TestEC (line 6) | class OpenSSL::TestEC < OpenSSL::PKeyTestCase
    method test_ec_key_new (line 7) | def test_ec_key_new
    method test_ec_key_new_empty (line 28) | def test_ec_key_new_empty
    method test_builtin_curves (line 45) | def test_builtin_curves
    method test_generate (line 56) | def test_generate
    method test_generate_key (line 67) | def test_generate_key
    method test_marshal (line 76) | def test_marshal
    method test_check_key (line 83) | def test_check_key
    method test_sign_verify (line 124) | def test_sign_verify
    method test_derive_key (line 139) | def test_derive_key
    method test_sign_verify_raw (line 155) | def test_sign_verify_raw
    method test_dsa_sign_asn1_FIPS186_3 (line 181) | def test_dsa_sign_asn1_FIPS186_3
    method test_dh_compute_key (line 190) | def test_dh_compute_key
    method test_ECPrivateKey (line 201) | def test_ECPrivateKey
    method test_ECPrivateKey_with_parameters (line 228) | def test_ECPrivateKey_with_parameters
    method test_ECPrivateKey_encrypted (line 251) | def test_ECPrivateKey_encrypted
    method test_PUBKEY (line 279) | def test_PUBKEY
    method test_ec_group (line 314) | def test_ec_group
    method test_ec_group_initialize_error_message (line 348) | def test_ec_group_initialize_error_message
    method test_ec_point (line 357) | def test_ec_point
    method test_small_curve (line 383) | def test_small_curve
    method test_ec_point_add (line 427) | def test_ec_point_add
    method test_ec_point_mul (line 448) | def test_ec_point_mul
    method B (line 485) | def B(ary)
    method assert_same_ec (line 489) | def assert_same_ec(expected, key)

FILE: test/openssl/test_pkey_rsa.rb
  class OpenSSL::TestPKeyRSA (line 6) | class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase
    method test_no_private_exp (line 7) | def test_no_private_exp
    method test_private (line 16) | def test_private
    method test_new (line 44) | def test_new
    method test_new_public_exponent (line 52) | def test_new_public_exponent
    method test_new_empty (line 62) | def test_new_empty
    method test_s_generate (line 72) | def test_s_generate
    method test_s_generate_public_exponent (line 78) | def test_s_generate_public_exponent
    method test_new_break (line 88) | def test_new_break
    method test_sign_verify (line 95) | def test_sign_verify
    method test_sign_verify_options (line 113) | def test_sign_verify_options
    method test_sign_verify_raw (line 135) | def test_sign_verify_raw
    method test_sign_verify_raw_legacy (line 159) | def test_sign_verify_raw_legacy
    method test_verify_empty_rsa (line 187) | def test_verify_empty_rsa
    method test_sign_verify_pss (line 194) | def test_sign_verify_pss
    method test_encrypt_decrypt (line 239) | def test_encrypt_decrypt
    method test_encrypt_decrypt_legacy (line 259) | def test_encrypt_decrypt_legacy
    method test_export (line 280) | def test_export
    method test_to_der (line 305) | def test_to_der
    method test_RSAPrivateKey (line 330) | def test_RSAPrivateKey
    method test_RSAPrivateKey_encrypted (line 361) | def test_RSAPrivateKey_encrypted
    method test_RSAPublicKey (line 381) | def test_RSAPublicKey
    method test_PUBKEY (line 399) | def test_PUBKEY
    method test_pem_passwd (line 432) | def test_pem_passwd
    method test_private_encoding (line 445) | def test_private_encoding
    method test_private_encoding_encrypted (line 463) | def test_private_encoding_encrypted
    method test_params (line 515) | def test_params
    method test_dup (line 535) | def test_dup
    method test_marshal (line 547) | def test_marshal
    method assert_same_rsa (line 555) | def assert_same_rsa(expected, key)

FILE: test/openssl/test_provider.rb
  class OpenSSL::TestProvider (line 5) | class OpenSSL::TestProvider < OpenSSL::TestCase
    method test_openssl_provider_name_inspect (line 6) | def test_openssl_provider_name_inspect
    method test_openssl_provider_names (line 14) | def test_openssl_provider_names
    method test_unloaded_openssl_provider (line 34) | def test_unloaded_openssl_provider
    method test_openssl_legacy_provider (line 43) | def test_openssl_legacy_provider
    method with_openssl (line 77) | def with_openssl(code, **opts)

FILE: test/openssl/test_random.rb
  class OpenSSL::TestRandom (line 6) | class OpenSSL::TestRandom < OpenSSL::TestCase
    method test_random_bytes (line 7) | def test_random_bytes
    method test_pseudo_bytes (line 12) | def test_pseudo_bytes

FILE: test/openssl/test_ssl.rb
  class OpenSSL::TestSSL (line 6) | class OpenSSL::TestSSL < OpenSSL::SSLTestCase
    method test_bad_socket (line 7) | def test_bad_socket
    method test_ctx_setup (line 18) | def test_ctx_setup
    method test_ctx_options (line 25) | def test_ctx_options
    method test_ctx_options_config (line 41) | def test_ctx_options_config
    method test_ssl_with_server_cert (line 65) | def test_ssl_with_server_cert
    method test_socket_open (line 99) | def test_socket_open
    method test_socket_open_with_context (line 113) | def test_socket_open_with_context
    method test_socket_open_with_local_address_port_context (line 129) | def test_socket_open_with_local_address_port_context
    method test_socket_close_write (line 149) | def test_socket_close_write
    method test_add_certificate (line 173) | def test_add_certificate
    method test_add_certificate_multiple_certs (line 190) | def test_add_certificate_multiple_certs
    method test_extra_chain_cert_auto_chain (line 233) | def test_extra_chain_cert_auto_chain
    method test_sysread_and_syswrite (line 261) | def test_sysread_and_syswrite
    method test_read_with_timeout (line 282) | def test_read_with_timeout
    method test_getbyte (line 305) | def test_getbyte
    method test_readbyte (line 318) | def test_readbyte
    method test_sync_close (line 331) | def test_sync_close
    method test_sync_close_initialize_opt (line 358) | def test_sync_close_initialize_opt
    method test_copy_stream (line 374) | def test_copy_stream
    method test_verify_mode_default (line 388) | def test_verify_mode_default
    method test_verify_mode_server_cert (line 393) | def test_verify_mode_server_cert
    method test_verify_mode_client_cert_required (line 425) | def test_verify_mode_client_cert_required
    method test_client_auth_success (line 446) | def test_client_auth_success
    method test_client_cert_cb_ignore_error (line 481) | def test_client_cert_cb_ignore_error
    method test_client_ca (line 497) | def test_client_ca
    method test_unstarted_session (line 523) | def test_unstarted_session
    method test_parallel (line 540) | def test_parallel
    method test_verify_result (line 561) | def test_verify_result
    method test_exception_in_verify_callback_is_ignored (line 608) | def test_exception_in_verify_callback_is_ignored
    method test_ca_file (line 631) | def test_ca_file
    method test_ca_file_not_found (line 655) | def test_ca_file_not_found
    method test_finished_messages (line 665) | def test_finished_messages
    method test_sslctx_set_params (line 690) | def test_sslctx_set_params
    method test_post_connect_check_with_anon_ciphers (line 703) | def test_post_connect_check_with_anon_ciphers
    method test_post_connection_check (line 728) | def test_post_connection_check
    method test_verify_certificate_identity (line 792) | def test_verify_certificate_identity
    method test_verify_hostname (line 808) | def test_verify_hostname
    method test_verify_wildcard (line 813) | def test_verify_wildcard
    method test_post_connection_check_wildcard_san (line 825) | def test_post_connection_check_wildcard_san
    method test_post_connection_check_wildcard_cn (line 898) | def test_post_connection_check_wildcard_cn
    method create_cert_with_san (line 943) | def create_cert_with_san(san)
    method create_cert_with_name (line 958) | def create_cert_with_name(name)
    method create_null_byte_SAN_certificate (line 966) | def create_null_byte_SAN_certificate(critical = false)
    method socketpair (line 982) | def socketpair
    method test_keylog_cb (line 990) | def test_keylog_cb
    method test_tlsext_hostname (line 1036) | def test_tlsext_hostname
    method test_servername_cb_exception (line 1083) | def test_servername_cb_exception
    method test_servername_cb_raises_an_exception_on_unknown_objects (line 1105) | def test_servername_cb_raises_an_exception_on_unknown_objects
    method test_accept_errors_include_peeraddr (line 1125) | def test_accept_errors_include_peeraddr
    method test_verify_hostname_on_connect (line 1150) | def test_verify_hostname_on_connect
    method test_verify_hostname_failure_error_code (line 1196) | def test_verify_hostname_failure_error_code
    method test_connect_certificate_verify_failed_exception_message (line 1233) | def test_connect_certificate_verify_failed_exception_message
    method test_unset_OP_ALL (line 1258) | def test_unset_OP_ALL
    method check_supported_protocol_versions (line 1273) | def check_supported_protocol_versions
    method test_set_params_min_version (line 1310) | def test_set_params_min_version
    method test_minmax_version (line 1328) | def test_minmax_version
    method test_minmax_version_system_default (line 1467) | def test_minmax_version_system_default
    method test_respect_system_default_min (line 1511) | def test_respect_system_default_min
    method test_options_disable_versions (line 1560) | def test_options_disable_versions
    method test_ssl_methods_constant (line 1606) | def test_ssl_methods_constant
    method test_renegotiation_cb (line 1617) | def test_renegotiation_cb
    method test_alpn_protocol_selection_ary (line 1629) | def test_alpn_protocol_selection_ary
    method test_alpn_protocol_selection_cancel (line 1647) | def test_alpn_protocol_selection_cancel
    method test_npn_protocol_selection_ary (line 1674) | def test_npn_protocol_selection_ary
    method test_npn_protocol_selection_enum (line 1693) | def test_npn_protocol_selection_enum
    method test_npn_protocol_selection_cancel (line 1716) | def test_npn_protocol_selection_cancel
    method test_npn_advertised_protocol_too_long (line 1728) | def test_npn_advertised_protocol_too_long
    method test_npn_selected_protocol_too_long (line 1738) | def test_npn_selected_protocol_too_long
    method readwrite_loop_safe (line 1750) | def readwrite_loop_safe(ctx, ssl)
    method test_close_after_socket_close (line 1755) | def test_close_after_socket_close
    method test_sync_close_without_connect (line 1768) | def test_sync_close_without_connect
    method test_get_ephemeral_key (line 1777) | def test_get_ephemeral_key
    method test_fallback_scsv (line 1826) | def test_fallback_scsv
    method test_tmp_dh_callback (line 1896) | def test_tmp_dh_callback
    method test_ciphersuites_method_tls_connection (line 1921) | def test_ciphersuites_method_tls_connection
    method test_ciphersuites_method_nil_argument (line 1940) | def test_ciphersuites_method_nil_argument
    method test_ciphersuites_method_frozen_object (line 1945) | def test_ciphersuites_method_frozen_object
    method test_ciphersuites_method_bogus_csuite (line 1951) | def test_ciphersuites_method_bogus_csuite
    method test_ciphers_method_tls_connection (line 1960) | def test_ciphers_method_tls_connection
    method test_ciphers_method_nil_argument (line 1979) | def test_ciphers_method_nil_argument
    method test_ciphers_method_frozen_object (line 1984) | def test_ciphers_method_frozen_object
    method test_ciphers_method_bogus_csuite (line 1991) | def test_ciphers_method_bogus_csuite
    method test_sigalgs (line 2001) | def test_sigalgs
    method test_client_sigalgs (line 2044) | def test_client_sigalgs
    method test_get_sigalg (line 2079) | def test_get_sigalg
    method test_pqc_sigalg (line 2100) | def test_pqc_sigalg
    method test_connect_works_when_setting_dh_callback_to_nil (line 2152) | def test_connect_works_when_setting_dh_callback_to_nil
    method test_tmp_dh (line 2165) | def test_tmp_dh
    method test_set_groups_tls12 (line 2185) | def test_set_groups_tls12
    method test_set_groups_tls13 (line 2229) | def test_set_groups_tls13
    method test_pqc_group (line 2248) | def test_pqc_group
    method test_security_level (line 2271) | def test_security_level
    method test_dup (line 2307) | def test_dup
    method test_freeze_calls_setup (line 2320) | def test_freeze_calls_setup
    method test_fileno (line 2332) | def test_fileno
    method test_export_keying_material (line 2346) | def test_export_keying_material
    method test_ractor_client (line 2366) | def test_ractor_client
    method test_ractor_set_params (line 2390) | def test_ractor_set_params
    method server_connect (line 2405) | def server_connect(port, ctx = nil)
    method assert_handshake_error (line 2419) | def assert_handshake_error

FILE: test/openssl/test_ssl_session.rb
  class OpenSSL::TestSSLSession (line 6) | class OpenSSL::TestSSLSession < OpenSSL::SSLTestCase
    method test_session (line 7) | def test_session
    method test_session_time (line 84) | def test_session_time
    method test_session_timeout (line 97) | def test_session_timeout
    method test_session_exts_read (line 110) | def test_session_exts_read
    method test_resumption (line 114) | def test_resumption
    method test_server_session_cache (line 149) | def test_server_session_cache
    method test_ctx_client_session_cb_tls12 (line 227) | def test_ctx_client_session_cb_tls12
    method test_ctx_client_session_cb_tls13 (line 261) | def test_ctx_client_session_cb_tls13
    method test_ctx_client_session_cb_tls13_exception (line 285) | def test_ctx_client_session_cb_tls13_exception
    method test_ctx_server_session_cb (line 308) | def test_ctx_server_session_cb
    method test_dup (line 421) | def test_dup
    method server_connect_with_session (line 429) | def server_connect_with_session(port, ctx = nil, sess = nil)

FILE: test/openssl/test_ts.rb
  class OpenSSL::TestTimestamp (line 5) | class OpenSSL::TestTimestamp < OpenSSL::TestCase
    method intermediate_key (line 6) | def intermediate_key
    method ee_key (line 26) | def ee_key
    method ca_cert (line 46) | def ca_cert
    method ca_store (line 50) | def ca_store
    method ts_cert_direct (line 54) | def ts_cert_direct
    method intermediate_cert (line 58) | def intermediate_cert
    method intermediate_store (line 62) | def intermediate_store
    method ts_cert_ee (line 66) | def ts_cert_ee
    method test_request_mandatory_fields (line 70) | def test_request_mandatory_fields
    method test_request_assignment (line 83) | def test_request_assignment
    method test_request_serialization (line 121) | def test_request_serialization
    method test_request_re_assignment (line 142) | def test_request_re_assignment
    method test_request_encode_decode (line 160) | def test_request_encode_decode
    method test_request_invalid_asn1 (line 184) | def test_request_invalid_asn1
    method test_response_constants (line 190) | def test_response_constants
    method test_response_creation (line 199) | def test_response_creation
    method test_response_failure_info (line 231) | def test_response_failure_info
    method test_response_mandatory_fields (line 236) | def test_response_mandatory_fields
    method test_response_allowed_digests (line 269) | def test_response_allowed_digests
    method test_response_default_policy (line 311) | def test_response_default_policy
    method test_response_bad_purpose (line 330) | def test_response_bad_purpose
    method test_response_invalid_asn1 (line 349) | def test_response_invalid_asn1
    method test_no_cert_requested (line 355) | def test_no_cert_requested
    method test_response_no_policy_defined (line 373) | def test_response_no_policy_defined
    method test_verify_ee_no_req (line 389) | def test_verify_ee_no_req
    method test_verify_ee_no_store (line 396) | def test_verify_ee_no_store
    method test_verify_ee_wrong_root_no_intermediate (line 403) | def test_verify_ee_wrong_root_no_intermediate
    method test_verify_ee_wrong_root_wrong_intermediate (line 410) | def test_verify_ee_wrong_root_wrong_intermediate
    method test_verify_ee_nonce_mismatch (line 417) | def test_verify_ee_nonce_mismatch
    method test_verify_ee_intermediate_missing (line 425) | def test_verify_ee_intermediate_missing
    method test_verify_ee_intermediate (line 432) | def test_verify_ee_intermediate
    method test_verify_ee_intermediate_type_error (line 437) | def test_verify_ee_intermediate_type_error
    method test_verify_ee_def_policy (line 442) | def test_verify_ee_def_policy
    method test_verify_direct (line 459) | def test_verify_direct
    method test_verify_direct_redundant_untrusted (line 464) | def test_verify_direct_redundant_untrusted
    method test_verify_direct_unrelated_untrusted (line 469) | def test_verify_direct_unrelated_untrusted
    method test_verify_direct_wrong_root (line 474) | def test_verify_direct_wrong_root
    method test_verify_direct_no_cert_no_intermediate (line 481) | def test_verify_direct_no_cert_no_intermediate
    method test_verify_ee_no_cert (line 488) | def test_verify_ee_no_cert
    method test_verify_ee_no_cert_no_intermediate (line 493) | def test_verify_ee_no_cert_no_intermediate
    method test_verify_ee_additional_certs_array (line 500) | def test_verify_ee_additional_certs_array
    method test_verify_ee_additional_certs_with_root (line 520) | def test_verify_ee_additional_certs_with_root
    method test_verify_ee_cert_inclusion_not_requested (line 537) | def test_verify_ee_cert_inclusion_not_requested
    method test_reusable (line 556) | def test_reusable
    method test_token_info_creation (line 579) | def test_token_info_creation
    method test_token_info_invalid_asn1 (line 607) | def test_token_info_invalid_asn1
    method assert_cert (line 615) | def assert_cert expected, actual
    method timestamp_ee (line 619) | def timestamp_ee
    method timestamp_ee_no_cert (line 634) | def timestamp_ee_no_cert
    method timestamp_direct (line 650) | def timestamp_direct
    method timestamp_direct_no_cert (line 665) | def timestamp_direct_no_cert

FILE: test/openssl/test_x509attr.rb
  class OpenSSL::TestX509Attribute (line 6) | class OpenSSL::TestX509Attribute < OpenSSL::TestCase
    method test_new (line 7) | def test_new
    method test_from_der (line 20) | def test_from_der
    method test_to_der (line 30) | def test_to_der
    method test_invalid_value (line 43) | def test_invalid_value
    method test_dup (line 62) | def test_dup
    method test_eq (line 70) | def test_eq
    method test_marshal (line 87) | def test_marshal

FILE: test/openssl/test_x509cert.rb
  class OpenSSL::TestX509Certificate (line 6) | class OpenSSL::TestX509Certificate < OpenSSL::TestCase
    method setup (line 7) | def setup
    method test_serial (line 16) | def test_serial
    method test_public_key (line 25) | def test_public_key
    method test_validity (line 38) | def test_validity
    method test_extension_factory (line 64) | def test_extension_factory
    method test_akiski (line 92) | def test_akiski
    method test_akiski_missing (line 118) | def test_akiski_missing
    method test_crl_uris_no_crl_distribution_points (line 124) | def test_crl_uris_no_crl_distribution_points
    method test_crl_uris (line 129) | def test_crl_uris
    method test_crl_uris_multiple_general_names (line 147) | def test_crl_uris_multiple_general_names
    method test_crl_uris_no_uris (line 164) | def test_crl_uris_no_uris
    method test_aia_missing (line 180) | def test_aia_missing
    method test_aia (line 186) | def test_aia
    method test_invalid_extension (line 211) | def test_invalid_extension
    method test_sign_and_verify (line 237) | def test_sign_and_verify
    method test_sign_and_verify_nil_digest (line 247) | def test_sign_and_verify_nil_digest
    method test_check_private_key (line 255) | def test_check_private_key
    method test_read_from_file (line 260) | def test_read_from_file
    method test_read_der_then_pem (line 269) | def test_read_der_then_pem
    method test_eq (line 281) | def test_eq
    method test_inspect (line 301) | def test_inspect
    method test_marshal (line 309) | def test_marshal
    method test_load_file_empty_pem (line 320) | def test_load_file_empty_pem
    method test_load_file_fullchain_pem (line 330) | def test_load_file_fullchain_pem
    method test_load_file_certificate_der (line 346) | def test_load_file_certificate_der
    method test_load_file_fullchain_garbage (line 360) | def test_load_file_fullchain_garbage
    method test_tbs_precert_bytes (line 371) | def test_tbs_precert_bytes
    method certificate_error_returns_false (line 380) | def certificate_error_returns_false

FILE: test/openssl/test_x509crl.rb
  class OpenSSL::TestX509CRL (line 6) | class OpenSSL::TestX509CRL < OpenSSL::TestCase
    method setup (line 7) | def setup
    method test_basic (line 14) | def test_basic
    method test_revoked (line 32) | def test_revoked
    method test_extension (line 108) | def test_extension
    method test_crlnumber (line 163) | def test_crlnumber
    method test_sign_and_verify (line 180) | def test_sign_and_verify
    method test_sign_and_verify_nil_digest (line 200) | def test_sign_and_verify_nil_digest
    method test_revoked_to_der (line 214) | def test_revoked_to_der
    method test_eq (line 237) | def test_eq
    method test_marshal (line 266) | def test_marshal
    method crl_error_returns_false (line 284) | def crl_error_returns_false

FILE: test/openssl/test_x509ext.rb
  class OpenSSL::TestX509Extension (line 6) | class OpenSSL::TestX509Extension < OpenSSL::TestCase
    method setup (line 7) | def setup
    method test_new (line 20) | def test_new
    method test_create_by_factory (line 31) | def test_create_by_factory
    method test_factory_create_extension_sn_ln (line 71) | def test_factory_create_extension_sn_ln
    method test_factory_create_extension_oid (line 79) | def test_factory_create_extension_oid
    method test_dup (line 90) | def test_dup
    method test_eq (line 96) | def test_eq
    method test_marshal (line 107) | def test_marshal
    method test_value_der (line 115) | def test_value_der

FILE: test/openssl/test_x509name.rb
  class OpenSSL::TestX509Name (line 7) | class OpenSSL::TestX509Name < OpenSSL::TestCase
    method setup (line 8) | def setup
    method test_s_new (line 14) | def test_s_new
    method test_unrecognized_oid (line 98) | def test_unrecognized_oid
    method test_unrecognized_oid_parse_encode_equality (line 133) | def test_unrecognized_oid_parse_encode_equality
    method test_s_parse (line 150) | def test_s_parse
    method test_s_parse_rfc2253 (line 175) | def test_s_parse_rfc2253
    method test_add_entry (line 274) | def test_add_entry
    method test_add_entry_street (line 303) | def test_add_entry_street
    method test_add_entry_placing (line 320) | def test_add_entry_placing
    method test_to_s (line 354) | def test_to_s
    method test_to_utf8 (line 382) | def test_to_utf8
    method test_equals2 (line 400) | def test_equals2
    method test_spaceship (line 410) | def test_spaceship
    method test_hash_old (line 426) | def test_hash_old
    method test_equality (line 436) | def test_equality
    method test_marshal (line 446) | def test_marshal
    method test_dup (line 453) | def test_dup

FILE: test/openssl/test_x509req.rb
  class OpenSSL::TestX509Request (line 6) | class OpenSSL::TestX509Request < OpenSSL::TestCase
    method setup (line 7) | def setup
    method issue_csr (line 14) | def issue_csr(ver, dn, key, digest)
    method test_public_key (line 23) | def test_public_key
    method test_version (line 31) | def test_version
    method test_subject (line 38) | def test_subject
    method test_signature_algorithm (line 45) | def test_signature_algorithm
    method create_ext_req (line 50) | def create_ext_req(exts)
    method get_ext_req (line 56) | def get_ext_req(ext_req_value)
    method test_attr (line 64) | def test_attr
    method test_sign_digest_instance (line 97) | def test_sign_digest_instance
    method test_sign_and_verify (line 103) | def test_sign_and_verify
    method test_sign_and_verify_nil_digest (line 113) | def test_sign_and_verify_nil_digest
    method test_dup (line 126) | def test_dup
    method test_eq (line 131) | def test_eq
    method test_marshal (line 141) | def test_marshal
    method request_error_returns_false (line 150) | def request_error_returns_false

FILE: test/openssl/test_x509store.rb
  class OpenSSL::TestX509Store (line 6) | class OpenSSL::TestX509Store < OpenSSL::TestCase
    method test_store_new (line 7) | def test_store_new
    method test_add_file_path (line 14) | def test_add_file_path
    method test_verify_simple (line 56) | def test_verify_simple
    method test_verify_callback (line 108) | def test_verify_callback
    method test_verify_purpose (line 174) | def test_verify_purpose
    method test_verify_validity_period (line 204) | def test_verify_validity_period
    method test_verify_with_crl (line 257) | def test_verify_with_crl
    method test_add_cert_duplicate (line 343) | def test_add_cert_duplicate
    method test_dup (line 366) | def test_dup
    method test_ctx_cleanup (line 373) | def test_ctx_cleanup

FILE: test/openssl/ut_eof.rb
  type OpenSSL::TestEOF (line 6) | module OpenSSL::TestEOF
    function test_getbyte_eof (line 7) | def test_getbyte_eof
    function test_readbyte_eof (line 11) | def test_readbyte_eof
    function test_eof_0 (line 15) | def test_eof_0
    function test_eof_0_rw (line 40) | def test_eof_0_rw
    function test_eof_1 (line 50) | def test_eof_1
    function test_eof_2 (line 97) | def test_eof_2
    function test_eof_3 (line 104) | def test_eof_3
    type Seek (line 110) | module Seek
      function open_file_seek (line 111) | def open_file_seek(content, pos)
      function test_eof_0_seek (line 118) | def test_eof_0_seek
      function test_eof_1_seek (line 128) | def test_eof_1_seek

FILE: test/openssl/utils.rb
  type OpenSSL::TestUtils (line 14) | module OpenSSL::TestUtils
    type Fixtures (line 15) | module Fixtures
      function pkey (line 18) | def pkey(name)
      function read_file (line 22) | def read_file(category, name)
    function generate_cert (line 31) | def generate_cert(dn, key, serial, issuer,
    function issue_cert (line 47) | def issue_cert(dn, key, serial, extensions, issuer, issuer_key,
    function issue_crl (line 63) | def issue_crl(revoke_info, serial, lastup, nextup, extensions,
    function get_subject_key_id (line 91) | def get_subject_key_id(cert, hex: true)
    function openssl? (line 105) | def openssl?(major = nil, minor = nil, fix = nil, patch = 0, status = 0)
    function libressl? (line 113) | def libressl?(major = nil, minor = nil, fix = nil)
    function aws_lc? (line 119) | def aws_lc?
  class OpenSSL::TestCase (line 124) | class OpenSSL::TestCase < Test::Unit::TestCase
    method setup (line 129) | def setup
    method teardown (line 135) | def teardown
    method omit_on_fips (line 151) | def omit_on_fips
    method omit_on_non_fips (line 161) | def omit_on_non_fips
  class OpenSSL::SSLTestCase (line 168) | class OpenSSL::SSLTestCase < OpenSSL::TestCase
    method setup (line 172) | def setup
    method readwrite_loop (line 193) | def readwrite_loop(ctx, ssl)
    method start_server (line 199) | def start_server(verify_mode: OpenSSL::SSL::VERIFY_NONE,
  class OpenSSL::PKeyTestCase (line 283) | class OpenSSL::PKeyTestCase < OpenSSL::TestCase
    method check_component (line 284) | def check_component(base, test, keys)
    method assert_sign_verify_false_or_error (line 290) | def assert_sign_verify_false_or_error
    method der_to_pem (line 298) | def der_to_pem(der, pem_header)
    method der_to_encrypted_pem (line 307) | def der_to_encrypted_pem(der, pem_header, password)
  type OpenSSL::Certs (line 326) | module OpenSSL::Certs
    function ca_cert (line 331) | def ca_cert
    function ts_cert_direct (line 343) | def ts_cert_direct(key, ca_cert)
    function intermediate_cert (line 357) | def intermediate_cert(key, ca_cert)
    function ts_cert_ee (line 370) | def ts_cert_ee(key, intermediate, im_key)
Condensed preview — 139 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,454K chars).
[
  {
    "path": ".git-blame-ignore-revs",
    "chars": 287,
    "preview": "# This is a file used by GitHub to ignore the following commits on `git blame`.\n#\n# You can also do the same thing in yo"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 118,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: 'github-actions'\n    directory: '/'\n    schedule:\n      interval: 'weekly'\n"
  },
  {
    "path": ".github/workflows/github-pages.yml",
    "chars": 786,
    "preview": "name: GitHub Pages\n\non:\n  push:\n    branches:\n      - master\n  workflow_dispatch:\n\njobs:\n  build:\n    runs-on: ubuntu-la"
  },
  {
    "path": ".github/workflows/push_gem.yml",
    "chars": 1129,
    "preview": "name: Publish gem to rubygems.org\n\non:\n  push:\n    tags:\n      - 'v*'\n\npermissions:\n  contents: read\n\njobs:\n  push:\n    "
  },
  {
    "path": ".github/workflows/sync-ruby.yml",
    "chars": 987,
    "preview": "name: Sync ruby\non:\n  push:\n    branches: [master]\njobs:\n  sync:\n    name: Sync ruby\n    runs-on: ubuntu-latest\n    if: "
  },
  {
    "path": ".github/workflows/test.yml",
    "chars": 7998,
    "preview": "name: CI\n\non: [push, pull_request, workflow_dispatch]\n\njobs:\n  ruby-versions:\n    uses: ruby/actions/.github/workflows/r"
  },
  {
    "path": ".gitignore",
    "chars": 130,
    "preview": "/.bundle\n/Gemfile.lock\n/doc/\n/pkg/\n/tmp/\n/html/\n*.bundle\n*.so\n*.o\next/openssl/mkmf.log\next/openssl/Makefile\next/openssl/"
  },
  {
    "path": "BSDL",
    "chars": 1282,
    "preview": "Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.\n\nRedistribution and use in source and binary forms, wit"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 8949,
    "preview": "# Contributing to Ruby OpenSSL\n\nThank you for your interest in contributing to Ruby OpenSSL!\n\nThis documentation provide"
  },
  {
    "path": "COPYING",
    "chars": 2502,
    "preview": "Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.\nYou can redistribute it and/or modify it under"
  },
  {
    "path": "Gemfile",
    "chars": 264,
    "preview": "source \"https://rubygems.org\"\n\ngem \"rake\"\ngem \"rake-compiler\"\ngem \"test-unit\", \"~> 3.0\", \">= 3.4.6\"\ngem \"test-unit-ruby-"
  },
  {
    "path": "History.md",
    "chars": 39472,
    "preview": "Version 4.0.1\n=============\n\nNotable changes\n---------------\n\n* Add `sync_close` keyword argument to `OpenSSL::SSL::SSLS"
  },
  {
    "path": "README.md",
    "chars": 3039,
    "preview": "# OpenSSL for Ruby\n\n[![Actions Status](https://github.com/ruby/openssl/workflows/CI/badge.svg)](https://github.com/ruby/"
  },
  {
    "path": "Rakefile",
    "chars": 2110,
    "preview": "require 'rake/testtask'\nrequire 'rdoc/task'\nrequire 'bundler/gem_tasks'\n\nbegin\n  require 'rake/extensiontask'\n  Rake::Ex"
  },
  {
    "path": "ext/openssl/extconf.rb",
    "chars": 6158,
    "preview": "# -*- coding: us-ascii -*-\n# frozen_string_literal: true\n=begin\n= Info\n  'OpenSSL for Ruby 2' project\n  Copyright (C) 20"
  },
  {
    "path": "ext/openssl/openssl_missing.h",
    "chars": 1440,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl.c",
    "chars": 35053,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl.h",
    "chars": 5275,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_asn1.c",
    "chars": 63010,
    "preview": "/*\n * 'OpenSSL for Ruby' team members\n * Copyright (C) 2003\n * All rights reserved.\n */\n/*\n * This program is licensed u"
  },
  {
    "path": "ext/openssl/ossl_asn1.h",
    "chars": 1468,
    "preview": "/*\n * 'OpenSSL for Ruby' team members\n * Copyright (C) 2003\n * All rights reserved.\n */\n/*\n * This program is licensed u"
  },
  {
    "path": "ext/openssl/ossl_bio.c",
    "chars": 909,
    "preview": "/*\n * 'OpenSSL for Ruby' team members\n * Copyright (C) 2003\n * All rights reserved.\n */\n/*\n * This program is licensed u"
  },
  {
    "path": "ext/openssl/ossl_bio.h",
    "chars": 307,
    "preview": "/*\n * 'OpenSSL for Ruby' team members\n * Copyright (C) 2003\n * All rights reserved.\n */\n/*\n * This program is licensed u"
  },
  {
    "path": "ext/openssl/ossl_bn.c",
    "chars": 34380,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Technorama team <oss-ruby@technorama.net>\n * All rights res"
  },
  {
    "path": "ext/openssl/ossl_bn.h",
    "chars": 535,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_cipher.c",
    "chars": 36896,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_cipher.h",
    "chars": 747,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_config.c",
    "chars": 11840,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_config.h",
    "chars": 349,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_digest.c",
    "chars": 13241,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_digest.h",
    "chars": 720,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_engine.c",
    "chars": 12929,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2003  GOTOU Yuuzou <gotoyuzo@notwork.org>\n * All rights reserved.\n */\n"
  },
  {
    "path": "ext/openssl/ossl_engine.h",
    "chars": 381,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2003  Michal Rokos <m.rokos@sh.cvut.cz>\n * Copyright (C) 2003  GOTOU Y"
  },
  {
    "path": "ext/openssl/ossl_hmac.c",
    "chars": 7819,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_hmac.h",
    "chars": 325,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_kdf.c",
    "chars": 12821,
    "preview": "/*\n * Ruby/OpenSSL Project\n * Copyright (C) 2007, 2017 Ruby/OpenSSL Project Authors\n */\n#include \"ossl.h\"\n#include <open"
  },
  {
    "path": "ext/openssl/ossl_kdf.h",
    "chars": 79,
    "preview": "#if !defined(OSSL_KDF_H)\n#define OSSL_KDF_H\n\nvoid Init_ossl_kdf(void);\n\n#endif\n"
  },
  {
    "path": "ext/openssl/ossl_ns_spki.c",
    "chars": 9953,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_ns_spki.h",
    "chars": 337,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_ocsp.c",
    "chars": 55201,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2003  Michal Rokos <m.rokos@sh.cvut.cz>\n * Copyright (C) 2003  GOTOU Y"
  },
  {
    "path": "ext/openssl/ossl_ocsp.h",
    "chars": 379,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2003  Michal Rokos <m.rokos@sh.cvut.cz>\n * Copyright (C) 2003  GOTOU Y"
  },
  {
    "path": "ext/openssl/ossl_pkcs12.c",
    "chars": 9267,
    "preview": "/*\n * This program is licensed under the same licence as Ruby.\n * (See the file 'COPYING'.)\n */\n#include \"ossl.h\"\n\n#defi"
  },
  {
    "path": "ext/openssl/ossl_pkcs12.h",
    "chars": 210,
    "preview": "/*\n * This program is licensed under the same licence as Ruby.\n * (See the file 'COPYING'.)\n */\n#if !defined(_OSSL_PKCS1"
  },
  {
    "path": "ext/openssl/ossl_pkcs7.c",
    "chars": 29117,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_pkcs7.h",
    "chars": 362,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_pkey.c",
    "chars": 52557,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_pkey.h",
    "chars": 9210,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001 Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n"
  },
  {
    "path": "ext/openssl/ossl_pkey_dh.c",
    "chars": 11256,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_pkey_dsa.c",
    "chars": 10121,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_pkey_ec.c",
    "chars": 43905,
    "preview": "/*\n * Copyright (C) 2006-2007 Technorama Ltd. <oss-ruby@technorama.net>\n */\n\n#include \"ossl.h\"\n\n#if !defined(OPENSSL_NO_"
  },
  {
    "path": "ext/openssl/ossl_pkey_rsa.c",
    "chars": 17026,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_provider.c",
    "chars": 5280,
    "preview": "/*\n * This program is licensed under the same licence as Ruby.\n * (See the file 'COPYING'.)\n */\n#include \"ossl.h\"\n\n#ifde"
  },
  {
    "path": "ext/openssl/ossl_provider.h",
    "chars": 93,
    "preview": "#if !defined(OSSL_PROVIDER_H)\n#define OSSL_PROVIDER_H\n\nvoid Init_ossl_provider(void);\n#endif\n"
  },
  {
    "path": "ext/openssl/ossl_rand.c",
    "chars": 4656,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n *\n * All rights reserved"
  },
  {
    "path": "ext/openssl/ossl_rand.h",
    "chars": 325,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_ssl.c",
    "chars": 99350,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2000-2002  GOTOU Yuuzou <gotoyuzo@notwork.org>\n * Copyright (C) 2001-2"
  },
  {
    "path": "ext/openssl/ossl_ssl.h",
    "chars": 959,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_ssl_session.c",
    "chars": 7566,
    "preview": "/*\n *  Copyright (C) 2004-2007 Technorama Ltd. <oss-ruby@technorama.net>\n */\n\n#include \"ossl.h\"\n\n#ifndef OPENSSL_NO_SOCK"
  },
  {
    "path": "ext/openssl/ossl_ts.c",
    "chars": 48377,
    "preview": "/*\n *\n * Copyright (C) 2010 Martin Bosslet <Martin.Bosslet@googlemail.com>\n * All rights reserved.\n */\n/*\n * This progra"
  },
  {
    "path": "ext/openssl/ossl_ts.h",
    "chars": 280,
    "preview": "/*\n *\n * Copyright (C) 2010 Martin Bosslet <Martin.Bosslet@googlemail.com>\n * All rights reserved.\n */\n/*\n * This progra"
  },
  {
    "path": "ext/openssl/ossl_x509.c",
    "chars": 9918,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_x509.h",
    "chars": 1927,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_x509attr.c",
    "chars": 7505,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001 Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n"
  },
  {
    "path": "ext/openssl/ossl_x509cert.c",
    "chars": 25615,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_x509crl.c",
    "chars": 12575,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n *"
  },
  {
    "path": "ext/openssl/ossl_x509ext.c",
    "chars": 12581,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_x509name.c",
    "chars": 15417,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001 Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n"
  },
  {
    "path": "ext/openssl/ossl_x509req.c",
    "chars": 10110,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_x509revoked.c",
    "chars": 6615,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "ext/openssl/ossl_x509store.c",
    "chars": 26410,
    "preview": "/*\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n "
  },
  {
    "path": "lib/openssl/bn.rb",
    "chars": 707,
    "preview": "# frozen_string_literal: true\n#--\n#\n# = Ruby-space definitions that completes C-space funcs for BN\n#\n# = Info\n# 'OpenSSL"
  },
  {
    "path": "lib/openssl/buffering.rb",
    "chars": 11019,
    "preview": "# coding: binary\n# frozen_string_literal: true\n#--\n#= Info\n#  'OpenSSL for Ruby 2' project\n#  Copyright (C) 2001 GOTOU Y"
  },
  {
    "path": "lib/openssl/cipher.rb",
    "chars": 1744,
    "preview": "# frozen_string_literal: true\n#--\n# = Ruby-space predefined Cipher subclasses\n#\n# = Info\n# 'OpenSSL for Ruby 2' project\n"
  },
  {
    "path": "lib/openssl/digest.rb",
    "chars": 1589,
    "preview": "# frozen_string_literal: true\n#--\n# = Ruby-space predefined Digest subclasses\n#\n# = Info\n# 'OpenSSL for Ruby 2' project\n"
  },
  {
    "path": "lib/openssl/hmac.rb",
    "chars": 2556,
    "preview": "# frozen_string_literal: true\n\nmodule OpenSSL\n  class HMAC\n    # Securely compare with another HMAC instance in constant"
  },
  {
    "path": "lib/openssl/marshal.rb",
    "chars": 568,
    "preview": "# frozen_string_literal: true\n#--\n# = Ruby-space definitions to add DER (de)serialization to classes\n#\n# = Info\n# 'OpenS"
  },
  {
    "path": "lib/openssl/pkcs5.rb",
    "chars": 613,
    "preview": "# frozen_string_literal: true\n#--\n# Ruby/OpenSSL Project\n# Copyright (C) 2017 Ruby/OpenSSL Project Authors\n#++\n\nmodule O"
  },
  {
    "path": "lib/openssl/pkey.rb",
    "chars": 15430,
    "preview": "# frozen_string_literal: true\n#--\n# Ruby/OpenSSL Project\n# Copyright (C) 2017 Ruby/OpenSSL Project Authors\n#++\n\nrequire_"
  },
  {
    "path": "lib/openssl/ssl.rb",
    "chars": 16902,
    "preview": "# frozen_string_literal: true\n=begin\n= Info\n  'OpenSSL for Ruby 2' project\n  Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@n"
  },
  {
    "path": "lib/openssl/version.rb",
    "chars": 110,
    "preview": "# frozen_string_literal: true\n\nmodule OpenSSL\n  # The version string of Ruby/OpenSSL.\n  VERSION = \"4.0.1\"\nend\n"
  },
  {
    "path": "lib/openssl/x509.rb",
    "chars": 12222,
    "preview": "# frozen_string_literal: true\n#--\n# = Ruby-space definitions that completes C-space funcs for X509 and subclasses\n#\n# = "
  },
  {
    "path": "lib/openssl.rb",
    "chars": 1272,
    "preview": "# frozen_string_literal: true\n=begin\n= Info\n  'OpenSSL for Ruby 2' project\n  Copyright (C) 2002  Michal Rokos <m.rokos@s"
  },
  {
    "path": "openssl.gemspec",
    "chars": 1224,
    "preview": "Gem::Specification.new do |spec|\n  spec.name          = \"openssl\"\n  spec.version       = \"4.0.1\"\n  spec.authors       = "
  },
  {
    "path": "sample/c_rehash.rb",
    "chars": 3740,
    "preview": "#!/usr/bin/env ruby\n\nrequire 'openssl'\n\nclass CHashDir\n  include Enumerable\n\n  def initialize(dirpath)\n    @dirpath = di"
  },
  {
    "path": "sample/cert2text.rb",
    "chars": 416,
    "preview": "#!/usr/bin/env ruby\n\nrequire 'openssl'\n\ndef cert2text(cert_str)\n  [\n    OpenSSL::X509::Certificate,\n    OpenSSL::X509::C"
  },
  {
    "path": "sample/certstore.rb",
    "chars": 3571,
    "preview": "require 'c_rehash'\nrequire 'crlstore'\n\n\nclass CertStore\n  attr_reader :self_signed_ca\n  attr_reader :other_ca\n  attr_rea"
  },
  {
    "path": "sample/cipher.rb",
    "chars": 1169,
    "preview": "#!/usr/bin/env ruby\nrequire 'openssl'\n\ndef crypt_by_password(alg, pass, salt, text)\n  puts \"--Setup--\"\n  puts %(cipher a"
  },
  {
    "path": "sample/crlstore.rb",
    "chars": 2408,
    "preview": "begin\n  require 'http-access2'\nrescue LoadError\n  STDERR.puts(\"Cannot load http-access2.  CRL might not be fetched.\")\nen"
  },
  {
    "path": "sample/echo_cli.rb",
    "chars": 1096,
    "preview": "#!/usr/bin/env ruby\n\nrequire 'socket'\nrequire 'openssl'\nrequire 'optparse'\n\noptions = ARGV.getopts(\"p:c:k:C:\")\n\nhost    "
  },
  {
    "path": "sample/echo_svr.rb",
    "chars": 1794,
    "preview": "#!/usr/bin/env ruby\n\nrequire 'socket'\nrequire 'openssl'\nrequire 'optparse'\n\noptions = ARGV.getopts(\"p:c:k:C:\")\n\nport    "
  },
  {
    "path": "sample/gen_csr.rb",
    "chars": 1046,
    "preview": "#!/usr/bin/env ruby\n\nrequire 'optparse'\nrequire 'openssl'\n\ndef usage\n  myname = File::basename($0)\n  $stderr.puts <<EOS\n"
  },
  {
    "path": "sample/smime_read.rb",
    "chars": 498,
    "preview": "require 'optparse'\nrequire 'openssl'\n\noptions = ARGV.getopts(\"c:k:C:\")\n\ncert_file = options[\"c\"]\nkey_file  = options[\"k\""
  },
  {
    "path": "sample/smime_write.rb",
    "chars": 632,
    "preview": "require 'openssl'\nrequire 'optparse'\n\noptions = ARGV.getopts(\"c:k:r:\")\n\ncert_file = options[\"c\"]\nkey_file  = options[\"k\""
  },
  {
    "path": "sample/wget.rb",
    "chars": 664,
    "preview": "#!/usr/bin/env ruby\n\nrequire 'net/https'\nrequire 'optparse'\n\noptions = ARGV.getopts('C:')\n\ncert_store = options[\"C\"]\n\nur"
  },
  {
    "path": "test/openssl/fixtures/pkey/dh-1.pem",
    "chars": 769,
    "preview": "-----BEGIN DH PARAMETERS-----\nMIICCAKCAgEAvRzXYxY6L2DjeYmm1eowtMDu1it3j+VwFr6s6PRWzc1apMtztr9G\nxZ2mYndUAJLgNLO3n2fUDCYVM"
  },
  {
    "path": "test/openssl/fixtures/pkey/dh2048_ffdhe2048.pem",
    "chars": 424,
    "preview": "-----BEGIN DH PARAMETERS-----\nMIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz\n+8yTnc4kmz75fS/jY2MMddj2g"
  },
  {
    "path": "test/openssl/fixtures/pkey/dsa2048.pem",
    "chars": 883,
    "preview": "-----BEGIN PRIVATE KEY-----\nMIICXgIBADCCAjYGByqGSM44BAEwggIpAoIBAQDXZhJ/dQoWkQELzjzlx8FtIp96\nvoCYe5NY0H8j0jz7GyHpXt41+Mt"
  },
  {
    "path": "test/openssl/fixtures/pkey/mldsa65-1.pem",
    "chars": 5604,
    "preview": "-----BEGIN PRIVATE KEY-----\nMIIP/gIBADALBglghkgBZQMEAxIEgg/qMIIP5gQg6Xunp08Ia0w6d93rvBnXnlYf\nih3Z+9IDZSRIyAGfjbQEgg/A9DP"
  },
  {
    "path": "test/openssl/fixtures/pkey/mldsa65-2.pem",
    "chars": 5604,
    "preview": "-----BEGIN PRIVATE KEY-----\nMIIP/gIBADALBglghkgBZQMEAxIEgg/qMIIP5gQgDdLfrcKpbcx2qbjvcE+SqUnW\n+y7uWok/WM51jtrhQGIEgg/Az2A"
  },
  {
    "path": "test/openssl/fixtures/pkey/p256.pem",
    "chars": 227,
    "preview": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIID49FDqcf1O1eO8saTgG70UbXQw9Fqwseliit2aWhH1oAoGCCqGSM49\nAwEHoUQDQgAEFglk2c+oVUIK"
  },
  {
    "path": "test/openssl/fixtures/pkey/rsa-1.pem",
    "chars": 3243,
    "preview": "-----BEGIN RSA PRIVATE KEY-----\nMIIJJwIBAAKCAgEArIEJUYZrXhMfUXXdl2gLcXrRB4ciWNEeXt5UVLG0nPhygZwJ\nxis8tOrjXOJEpUXUsfgF35p"
  },
  {
    "path": "test/openssl/fixtures/pkey/rsa-2.pem",
    "chars": 3243,
    "preview": "-----BEGIN RSA PRIVATE KEY-----\nMIIJKAIBAAKCAgEA1HUbx825tG7+/ulC5DpDogzXqM2/KmeCwGXZY4XjiWa+Zj7b\nECkZwQh7zxFUsPixGqQKJSy"
  },
  {
    "path": "test/openssl/fixtures/pkey/rsa-3.pem",
    "chars": 3243,
    "preview": "-----BEGIN RSA PRIVATE KEY-----\nMIIJKAIBAAKCAgEAzn+YCcOh7BIRzrb7TEuhQLD545+/Fx/zCYO3l+y/8ogUxMTg\nLG5HrcXlX3JP796ie90/GHI"
  },
  {
    "path": "test/openssl/fixtures/pkey/rsa2048.pem",
    "chars": 1679,
    "preview": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAuV9ht9J7k4NBs38jOXvvTKY9gW8nLICSno5EETR1cuF7i4pN\ns9I1QJGAFAX0BEO4KbzXmuO"
  },
  {
    "path": "test/openssl/test_asn1.rb",
    "chars": 31628,
    "preview": "# frozen_string_literal: true\nrequire_relative 'utils'\n\nif defined?(OpenSSL)\n\nclass  OpenSSL::TestASN1 < OpenSSL::TestCa"
  },
  {
    "path": "test/openssl/test_bn.rb",
    "chars": 12436,
    "preview": "# coding: us-ascii\n# frozen_string_literal: true\nrequire_relative 'utils'\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestBN <"
  },
  {
    "path": "test/openssl/test_buffering.rb",
    "chars": 1519,
    "preview": "# frozen_string_literal: true\nrequire_relative 'utils'\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestBuffering < OpenSSL::Te"
  },
  {
    "path": "test/openssl/test_cipher.rb",
    "chars": 16601,
    "preview": "# frozen_string_literal: true\nrequire_relative 'utils'\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestCipher < OpenSSL::TestC"
  },
  {
    "path": "test/openssl/test_config.rb",
    "chars": 9171,
    "preview": "# frozen_string_literal: true\nrequire_relative 'utils'\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestConfig < OpenSSL::TestC"
  },
  {
    "path": "test/openssl/test_digest.rb",
    "chars": 5542,
    "preview": "# frozen_string_literal: true\nrequire_relative 'utils'\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestDigest < OpenSSL::TestC"
  },
  {
    "path": "test/openssl/test_engine.rb",
    "chars": 2442,
    "preview": "# frozen_string_literal: true\nrequire_relative 'utils'\n\nif defined?(OpenSSL) && defined?(OpenSSL::Engine)\n\nclass OpenSSL"
  },
  {
    "path": "test/openssl/test_fips.rb",
    "chars": 1822,
    "preview": "# frozen_string_literal: true\nrequire_relative 'utils'\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestFIPS < OpenSSL::TestCas"
  },
  {
    "path": "test/openssl/test_hmac.rb",
    "chars": 2821,
    "preview": "# frozen_string_literal: true\nrequire_relative 'utils'\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestHMAC < OpenSSL::TestCas"
  },
  {
    "path": "test/openssl/test_kdf.rb",
    "chars": 5845,
    "preview": "# frozen_string_literal: true\nrequire_relative 'utils'\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestKDF < OpenSSL::TestCase"
  },
  {
    "path": "test/openssl/test_ns_spki.rb",
    "chars": 1850,
    "preview": "# frozen_string_literal: true\nrequire_relative 'utils'\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestNSSPI < OpenSSL::TestCa"
  },
  {
    "path": "test/openssl/test_ocsp.rb",
    "chars": 14002,
    "preview": "# frozen_string_literal: true\nrequire_relative \"utils\"\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestOCSP < OpenSSL::TestCas"
  },
  {
    "path": "test/openssl/test_ossl.rb",
    "chars": 4503,
    "preview": "# frozen_string_literal: true\nrequire_relative \"utils\"\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestOSSL < OpenSSL::TestCas"
  },
  {
    "path": "test/openssl/test_pair.rb",
    "chars": 12817,
    "preview": "# frozen_string_literal: true\nrequire_relative 'utils'\nrequire_relative 'ut_eof'\n\nif defined?(OpenSSL::SSL)\n\nmodule Open"
  },
  {
    "path": "test/openssl/test_pkcs12.rb",
    "chars": 14333,
    "preview": "# frozen_string_literal: true\nrequire_relative \"utils\"\n\nif defined?(OpenSSL)\n\n# OpenSSL::PKCS12.create calling the PKCS1"
  },
  {
    "path": "test/openssl/test_pkcs7.rb",
    "chars": 16038,
    "preview": "# frozen_string_literal: true\nrequire_relative 'utils'\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestPKCS7 < OpenSSL::TestCa"
  },
  {
    "path": "test/openssl/test_pkey.rb",
    "chars": 11454,
    "preview": "# frozen_string_literal: true\nrequire_relative \"utils\"\n\nclass OpenSSL::TestPKey < OpenSSL::PKeyTestCase\n  def test_gener"
  },
  {
    "path": "test/openssl/test_pkey_dh.rb",
    "chars": 7288,
    "preview": "# frozen_string_literal: true\nrequire_relative 'utils'\n\nif defined?(OpenSSL) && defined?(OpenSSL::PKey::DH)\n\nclass OpenS"
  },
  {
    "path": "test/openssl/test_pkey_dsa.rb",
    "chars": 8850,
    "preview": "# frozen_string_literal: true\nrequire_relative 'utils'\n\nif defined?(OpenSSL) && defined?(OpenSSL::PKey::DSA)\n\nclass Open"
  },
  {
    "path": "test/openssl/test_pkey_ec.rb",
    "chars": 16970,
    "preview": "# frozen_string_literal: true\nrequire_relative 'utils'\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestEC < OpenSSL::PKeyTestC"
  },
  {
    "path": "test/openssl/test_pkey_rsa.rb",
    "chars": 19190,
    "preview": "# frozen_string_literal: true\nrequire_relative \"utils\"\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestPKeyRSA < OpenSSL::PKey"
  },
  {
    "path": "test/openssl/test_provider.rb",
    "chars": 2587,
    "preview": "# frozen_string_literal: true\nrequire_relative 'utils'\nif defined?(OpenSSL) && defined?(OpenSSL::Provider)\n\nclass OpenSS"
  },
  {
    "path": "test/openssl/test_random.rb",
    "chars": 518,
    "preview": "# frozen_string_literal: true\nrequire_relative \"utils\"\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestRandom < OpenSSL::TestC"
  },
  {
    "path": "test/openssl/test_ssl.rb",
    "chars": 81418,
    "preview": "# frozen_string_literal: true\nrequire_relative \"utils\"\n\nif defined?(OpenSSL::SSL)\n\nclass OpenSSL::TestSSL < OpenSSL::SSL"
  },
  {
    "path": "test/openssl/test_ssl_session.rb",
    "chars": 15140,
    "preview": "# frozen_string_literal: true\nrequire_relative \"utils\"\n\nif defined?(OpenSSL::SSL)\n\nclass OpenSSL::TestSSLSession < OpenS"
  },
  {
    "path": "test/openssl/test_ts.rb",
    "chars": 21898,
    "preview": "require_relative \"utils\"\n\nif defined?(OpenSSL) && defined?(OpenSSL::Timestamp)\n\nclass OpenSSL::TestTimestamp < OpenSSL::"
  },
  {
    "path": "test/openssl/test_x509attr.rb",
    "chars": 3113,
    "preview": "# frozen_string_literal: true\nrequire_relative \"utils\"\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestX509Attribute < OpenSSL"
  },
  {
    "path": "test/openssl/test_x509cert.rb",
    "chars": 13206,
    "preview": "# frozen_string_literal: true\nrequire_relative \"utils\"\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestX509Certificate < OpenS"
  },
  {
    "path": "test/openssl/test_x509crl.rb",
    "chars": 10249,
    "preview": "# frozen_string_literal: true\nrequire_relative \"utils\"\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestX509CRL < OpenSSL::Test"
  },
  {
    "path": "test/openssl/test_x509ext.rb",
    "chars": 4304,
    "preview": "# frozen_string_literal: true\nrequire_relative 'utils'\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestX509Extension < OpenSSL"
  },
  {
    "path": "test/openssl/test_x509name.rb",
    "chars": 16893,
    "preview": "# coding: ASCII-8BIT\n# frozen_string_literal: true\nrequire_relative 'utils'\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestX5"
  },
  {
    "path": "test/openssl/test_x509req.rb",
    "chars": 4661,
    "preview": "# frozen_string_literal: true\nrequire_relative \"utils\"\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestX509Request < OpenSSL::"
  },
  {
    "path": "test/openssl/test_x509store.rb",
    "chars": 14537,
    "preview": "# frozen_string_literal: true\nrequire_relative \"utils\"\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestX509Store < OpenSSL::Te"
  },
  {
    "path": "test/openssl/ut_eof.rb",
    "chars": 3030,
    "preview": "# frozen_string_literal: true\nrequire 'test/unit'\n\nif defined?(OpenSSL)\n\nmodule OpenSSL::TestEOF\n  def test_getbyte_eof\n"
  },
  {
    "path": "test/openssl/utils.rb",
    "chars": 11100,
    "preview": "# frozen_string_literal: true\nbegin\n  require \"openssl\"\nrescue LoadError\nend\n\nrequire \"test/unit\"\nrequire \"core_assertio"
  },
  {
    "path": "tool/openssl_fips.cnf.tmpl",
    "chars": 341,
    "preview": "config_diagnostics = 1\nopenssl_conf = openssl_init\n\n# It seems that the .include needs an absolute path.\n.include OPENSS"
  }
]

About this extraction

This page contains the full source code of the ruby/openssl GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 139 files (1.3 MB), approximately 424.5k tokens, and a symbol index with 1858 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!