pax_global_header00006660000000000000000000000064147041107770014522gustar00rootroot0000000000000052 comment=a7534300bb09184fec991b3b4f19a40538b8adea ssldump-1.9/000077500000000000000000000000001470411077700130625ustar00rootroot00000000000000ssldump-1.9/.clang-format000066400000000000000000000114731470411077700154430ustar00rootroot00000000000000--- Language: Cpp # BasedOnStyle: Chromium # with a few modifications AccessModifierOffset: -1 AlignAfterOpenBracket: Align AlignConsecutiveMacros: false AlignConsecutiveAssignments: false AlignConsecutiveBitFields: false AlignConsecutiveDeclarations: false AlignEscapedNewlines: Left AlignOperands: Align AlignTrailingComments: true AllowAllArgumentsOnNextLine: true AllowAllConstructorInitializersOnNextLine: true AllowAllParametersOfDeclarationOnNextLine: false AllowShortEnumsOnASingleLine: true AllowShortBlocksOnASingleLine: Never AllowShortCaseLabelsOnASingleLine: false AllowShortFunctionsOnASingleLine: Inline AllowShortLambdasOnASingleLine: All AllowShortIfStatementsOnASingleLine: Never AllowShortLoopsOnASingleLine: false AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: true AlwaysBreakTemplateDeclarations: Yes BinPackArguments: true BinPackParameters: false BraceWrapping: AfterCaseLabel: false AfterClass: false AfterControlStatement: Never AfterEnum: false AfterFunction: false AfterNamespace: false AfterObjCDeclaration: false AfterStruct: false AfterUnion: false AfterExternBlock: false BeforeCatch: false BeforeElse: false BeforeLambdaBody: false BeforeWhile: false IndentBraces: false SplitEmptyFunction: true SplitEmptyRecord: true SplitEmptyNamespace: true BreakBeforeBinaryOperators: None BreakBeforeBraces: Attach BreakBeforeInheritanceComma: false BreakInheritanceList: BeforeColon BreakBeforeTernaryOperators: true BreakConstructorInitializersBeforeComma: false BreakConstructorInitializers: BeforeColon BreakAfterJavaFieldAnnotations: false BreakStringLiterals: true ColumnLimit: 80 CommentPragmas: '^ IWYU pragma:' CompactNamespaces: false ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerIndentWidth: 4 ContinuationIndentWidth: 4 Cpp11BracedListStyle: true DeriveLineEnding: true DerivePointerAlignment: false DisableFormat: false ExperimentalAutoDetectBinPacking: false FixNamespaceComments: true ForEachMacros: - foreach - Q_FOREACH - BOOST_FOREACH IncludeBlocks: Preserve IncludeCategories: - Regex: '^' Priority: 2 SortPriority: 0 - Regex: '^<.*\.h>' Priority: 1 SortPriority: 0 - Regex: '^<.*' Priority: 2 SortPriority: 0 - Regex: '.*' Priority: 3 SortPriority: 0 IncludeIsMainRegex: '([-_](test|unittest))?$' IncludeIsMainSourceRegex: '' IndentCaseLabels: true IndentCaseBlocks: false IndentGotoLabels: true IndentPPDirectives: None IndentExternBlock: AfterExternBlock IndentWidth: 2 IndentWrappedFunctionNames: false InsertTrailingCommas: None JavaScriptQuotes: Leave JavaScriptWrapImports: true KeepEmptyLinesAtTheStartOfBlocks: false MacroBlockBegin: '' MacroBlockEnd: '' MaxEmptyLinesToKeep: 1 NamespaceIndentation: None ObjCBinPackProtocolList: Never ObjCBlockIndentWidth: 2 ObjCBreakBeforeNestedBlockParam: true ObjCSpaceAfterProperty: false ObjCSpaceBeforeProtocolList: true PenaltyBreakAssignment: 2 PenaltyBreakBeforeFirstCallParameter: 1 PenaltyBreakComment: 300 PenaltyBreakFirstLessLess: 120 PenaltyBreakString: 1000 PenaltyBreakTemplateDeclaration: 10 PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 200 PointerAlignment: Right RawStringFormats: - Language: Cpp Delimiters: - cc - CC - cpp - Cpp - CPP - 'c++' - 'C++' CanonicalDelimiter: '' BasedOnStyle: google - Language: TextProto Delimiters: - pb - PB - proto - PROTO EnclosingFunctions: - EqualsProto - EquivToProto - PARSE_PARTIAL_TEXT_PROTO - PARSE_TEST_PROTO - PARSE_TEXT_PROTO - ParseTextOrDie - ParseTextProtoOrDie - ParseTestProto - ParsePartialTestProto CanonicalDelimiter: '' BasedOnStyle: google ReflowComments: true SortIncludes: false SortUsingDeclarations: true SpaceAfterCStyleCast: false SpaceAfterLogicalNot: false SpaceAfterTemplateKeyword: true SpaceBeforeAssignmentOperators: true SpaceBeforeCpp11BracedList: false SpaceBeforeCtorInitializerColon: true SpaceBeforeInheritanceColon: true SpaceBeforeParens: Never SpaceBeforeRangeBasedForLoopColon: true SpaceInEmptyBlock: false SpaceInEmptyParentheses: false SpacesBeforeTrailingComments: 2 SpacesInAngles: false SpacesInConditionalStatement: false SpacesInContainerLiterals: true SpacesInCStyleCastParentheses: false SpacesInParentheses: false SpacesInSquareBrackets: false SpaceBeforeSquareBrackets: false Standard: Auto StatementMacros: - Q_UNUSED - QT_REQUIRE_VERSION TabWidth: 8 UseCRLF: false UseTab: Never WhitespaceSensitiveMacros: - STRINGIZE - PP_STRINGIZE - BOOST_PP_STRINGIZE ... ssldump-1.9/.gitchangelog.rc000066400000000000000000000141271470411077700161260ustar00rootroot00000000000000## ## Format ## ## ACTION: [AUDIENCE:] COMMIT_MSG [!TAG ...] ## ## Description ## ## ACTION is one of 'chg', 'fix', 'new' ## ## Is WHAT the change is about. ## ## 'chg' is for refactor, small improvement, cosmetic changes... ## 'fix' is for bug fixes ## 'new' is for new features, big improvement ## ## AUDIENCE is optional and one of 'dev', 'usr', 'pkg', 'test', 'doc' ## ## Is WHO is concerned by the change. ## ## 'dev' is for developpers (API changes, refactors...) ## 'usr' is for final users (UI changes) ## 'pkg' is for packagers (packaging changes) ## 'test' is for testers (test only related changes) ## 'doc' is for doc guys (doc only changes) ## ## COMMIT_MSG is ... well ... the commit message itself. ## ## TAGs are additionnal adjective as 'refactor' 'minor' 'cosmetic' ## ## They are preceded with a '!' or a '@' (prefer the former, as the ## latter is wrongly interpreted in github.) Commonly used tags are: ## ## 'refactor' is obviously for refactoring code only ## 'minor' is for a very meaningless change (a typo, adding a comment) ## 'cosmetic' is for cosmetic driven change (re-indentation, 80-col...) ## 'wip' is for partial functionality but complete subfunctionality. ## ## Example: ## ## new: usr: support of bazaar implemented ## chg: re-indentend some lines !cosmetic ## new: dev: updated code to be compatible with last version of killer lib. ## fix: pkg: updated year of licence coverage. ## new: test: added a bunch of test around user usability of feature X. ## fix: typo in spelling my name in comment. !minor ## ## Please note that multi-line commit message are supported, and only the ## first line will be considered as the "summary" of the commit message. So ## tags, and other rules only applies to the summary. The body of the commit ## message will be displayed in the changelog without reformatting. ## ## ``ignore_regexps`` is a line of regexps ## ## Any commit having its full commit message matching any regexp listed here ## will be ignored and won't be reported in the changelog. ## ignore_regexps = [ r'@minor', r'!minor', r'@cosmetic', r'!cosmetic', r'@refactor', r'!refactor', r'@wip', r'!wip', r'^([cC]hg|[fF]ix|[nN]ew)\s*:\s*[p|P]kg:', r'^([cC]hg|[fF]ix|[nN]ew)\s*:\s*[d|D]ev:', r'^(.{3,3}\s*:)?\s*[fF]irst commit.?\s*$', ] ## ``section_regexps`` is a list of 2-tuples associating a string label and a ## list of regexp ## ## Commit messages will be classified in sections thanks to this. Section ## titles are the label, and a commit is classified under this section if any ## of the regexps associated is matching. ## section_regexps = [ ('New', [ r'^[nN]ew\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$', ]), ('Changes', [ r'^[cC]hg\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$', ]), ('Fix', [ r'^[fF]ix\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$', ]), ('Other', None ## Match all lines ), ] ## ``body_process`` is a callable ## ## This callable will be given the original body and result will ## be used in the changelog. ## ## Available constructs are: ## ## - any python callable that take one txt argument and return txt argument. ## ## - ReSub(pattern, replacement): will apply regexp substitution. ## ## - Indent(chars=" "): will indent the text with the prefix ## Please remember that template engines gets also to modify the text and ## will usually indent themselves the text if needed. ## ## - Wrap(regexp=r"\n\n"): re-wrap text in separate paragraph to fill 80-Columns ## ## - noop: do nothing ## ## - ucfirst: ensure the first letter is uppercase. ## (usually used in the ``subject_process`` pipeline) ## ## - final_dot: ensure text finishes with a dot ## (usually used in the ``subject_process`` pipeline) ## ## - strip: remove any spaces before or after the content of the string ## ## Additionally, you can `pipe` the provided filters, for instance: #body_process = Wrap(regexp=r'\n(?=\w+\s*:)') | Indent(chars=" ") #body_process = Wrap(regexp=r'\n(?=\w+\s*:)') #body_process = noop body_process = ReSub(r'((^|\n)[A-Z]\w+(-\w+)*: .*(\n\s+.*)*)+$', r'') | strip ## ``subject_process`` is a callable ## ## This callable will be given the original subject and result will ## be used in the changelog. ## ## Available constructs are those listed in ``body_process`` doc. subject_process = (strip | ReSub(r'^([cC]hg|[fF]ix|[nN]ew)\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n@]*)(@[a-z]+\s+)*$', r'\4') | ucfirst | final_dot) ## ``tag_filter_regexp`` is a regexp ## ## Tags that will be used for the changelog must match this regexp. ## tag_filter_regexp = r'^v[0-9]+\.[0-9]+$' ## ``unreleased_version_label`` is a string ## ## This label will be used as the changelog Title of the last set of changes ## between last valid tag and HEAD if any. unreleased_version_label = "%%version%% (unreleased)" ## ``output_engine`` is a callable ## ## This will change the output format of the generated changelog file ## ## Available choices are: ## ## - rest_py ## ## Legacy pure python engine, outputs ReSTructured text. ## This is the default. ## ## - mustache() ## ## Template name could be any of the available templates in ## ``templates/mustache/*.tpl``. ## Requires python package ``pystache``. ## Examples: ## - mustache("markdown") ## - mustache("restructuredtext") ## ## - makotemplate() ## ## Template name could be any of the available templates in ## ``templates/mako/*.tpl``. ## Requires python package ``mako``. ## Examples: ## - makotemplate("restructuredtext") ## output_engine = rest_py #output_engine = mustache("restructuredtext") #output_engine = mustache("markdown") #output_engine = makotemplate("restructuredtext") ## ``include_merge`` is a boolean ## ## This option tells git-log whether to include merge commits in the log. ## The default is to include them. include_merge = True ssldump-1.9/.github/000077500000000000000000000000001470411077700144225ustar00rootroot00000000000000ssldump-1.9/.github/dependabot.yml000066400000000000000000000001661470411077700172550ustar00rootroot00000000000000version: 2 updates: - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" ssldump-1.9/.github/workflows/000077500000000000000000000000001470411077700164575ustar00rootroot00000000000000ssldump-1.9/.github/workflows/build.yml000066400000000000000000000026141470411077700203040ustar00rootroot00000000000000name: Build CI on: push: branches: [ master ] pull_request: branches: [ master ] schedule: # build the main branch every Monday morning - cron: '37 9 * * 1' workflow_dispatch: jobs: build: runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest, macos-latest] compiler: [cc, clang, gcc-12] exclude: - os: macos-latest compiler: cc - os: macos-latest compiler: gcc-12 steps: - name: Checkout code uses: actions/checkout@v4 - name: Compiler version run: $CC -v env: CC: ${{ matrix.compiler }} - name: Install Linux dependencies run: sudo apt install cmake ninja-build libssl-dev libpcap-dev libnet1-dev libjson-c-dev if: ${{ runner.os == 'Linux' }} - name: Install macOS dependencies run: | brew install cmake ninja openssl@3 libpcap libnet json-c echo "LDFLAGS=-L$(brew --prefix openssl@3)/lib" >> $GITHUB_ENV echo "CPPFLAGS=-I$(brew --prefix openssl@3)/include" >> $GITHUB_ENV if: ${{ runner.os == 'macOS' }} - name: cmake -B ${{github.workspace}}/build -G Ninja run: cmake -B ${{github.workspace}}/build -G Ninja env: CC: ${{ matrix.compiler }} - name: ninja -C ${{github.workspace}}/build run: ninja -C ${{github.workspace}}/build ssldump-1.9/.github/workflows/codeql-analysis.yml000066400000000000000000000020031470411077700222650ustar00rootroot00000000000000name: CodeQL analysis on: push: branches: [ master ] pull_request: branches: [ master ] schedule: # build the main branch every Monday morning - cron: '46 9 * * 1' workflow_dispatch: jobs: analyze: name: Analyze runs-on: ubuntu-latest permissions: actions: read contents: read security-events: write strategy: fail-fast: false matrix: language: [ 'cpp' ] steps: - name: Checkout repository uses: actions/checkout@v4 - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} - name: Build Application using script run: | sudo apt install cmake ninja-build libssl-dev libpcap-dev libnet1-dev libjson-c-dev cmake -B ${{github.workspace}}/build -G Ninja ninja -C ${{github.workspace}}/build - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}" ssldump-1.9/.github/workflows/scorecard.yml000066400000000000000000000060661470411077700211570ustar00rootroot00000000000000# This workflow uses actions that are not certified by GitHub. They are provided # by a third-party and are governed by separate terms of service, privacy # policy, and support documentation. name: Scorecard supply-chain security on: # For Branch-Protection check. Only the default branch is supported. See # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection branch_protection_rule: # To guarantee Maintained check is occasionally updated. See # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained schedule: - cron: '33 14 * * 6' push: branches: [ "master" ] # Declare default permissions as read only. permissions: read-all jobs: analysis: name: Scorecard analysis runs-on: ubuntu-latest permissions: # Needed to upload the results to code-scanning dashboard. security-events: write # Needed to publish results and get a badge (see publish_results below). id-token: write # Uncomment the permissions below if installing in a private repository. # contents: read # actions: read steps: - name: "Checkout code" uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: persist-credentials: false - name: "Run analysis" uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 with: results_file: results.sarif results_format: sarif # (Optional) "write" PAT token. Uncomment the `repo_token` line below if: # - you want to enable the Branch-Protection check on a *public* repository, or # - you are installing Scorecard on a *private* repository # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action?tab=readme-ov-file#authentication-with-fine-grained-pat-optional. # repo_token: ${{ secrets.SCORECARD_TOKEN }} # Public repositories: # - Publish results to OpenSSF REST API for easy access by consumers # - Allows the repository to include the Scorecard badge. # - See https://github.com/ossf/scorecard-action#publishing-results. # For private repositories: # - `publish_results` will always be set to `false`, regardless # of the value entered here. publish_results: true # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: SARIF file path: results.sarif retention-days: 5 # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" uses: github/codeql-action/upload-sarif@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9 with: sarif_file: results.sarif ssldump-1.9/.gitignore000066400000000000000000000006601470411077700150540ustar00rootroot00000000000000*~ .#* *.o ssldump Makefile config.log config.status dist autom4te.cache Makefile.in aclocal.m4 base/.deps/ base/.dirstamp base/Makefile.in common/Makefile.in common/lib/.deps/ common/lib/.dirstamp common/lib/Makefile.in compile config.h config.h.in config.guess config.sub configure depcomp install-sh missing null/.deps/ null/.dirstamp null/Makefile.in ssl/.deps/ ssl/.dirstamp ssl/Makefile.in stamp-h1 pcap/.deps/ pcap/.dirstamp ssldump-1.9/AUTHORS000077700000000000000000000000001470411077700151452CREDITSustar00rootroot00000000000000ssldump-1.9/CMakeLists.txt000066400000000000000000000064441470411077700156320ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.13.4) project( ssldump VERSION 1.8 DESCRIPTION 20230814 LANGUAGES C ) ######## User defined options option(DEBUG_BUILD "Build with debug facilities" OFF) option(DISABLE_OPTIMIZATION "Build without compiler optimizations" OFF) ################ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g") if(DEBUG_BUILD) add_definitions(-DDEBUG) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb3") endif() if(DISABLE_OPTIMIZATION) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0") else() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2") endif() include(CheckSymbolExists) include(GNUInstallDirs) configure_file(base/pcap-snoop.c.in base/pcap-snoop.c) set(SOURCES ${CMAKE_BINARY_DIR}/base/pcap-snoop.c base/network.c base/proto_mod.c base/tcppack.c base/tcpconn.c null/null_analyze.c common/lib/r_data.c common/lib/r_assoc.c common/lib/r_errors.c common/lib/debug.c ssl/ssl_analyze.c ssl/ssldecode.c ssl/sslprint.c ssl/ssl.enums.c ssl/sslxprint.c ssl/ciphersuites.c ssl/ssl_rec.c pcap/logpkt.c pcap/pcap_logger.c pcap/sys.c ) set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules/" ${CMAKE_MODULE_PATH}) find_package(OpenSSL) if(NOT OPENSSL_FOUND) message( FATAL_ERROR "Unable to find OpenSSL development files on this system On Debian and Ubuntu systems you can install the required library and header files with apt install libssl-dev On Fedora systems, with dnf install openssl-devel" ) endif() #dnf install openssl-devel libpcap-devel libnet-devel json-c-devel find_package(PCAP) if(NOT PCAP_FOUND) message( FATAL_ERROR "Unable to find libpcap development files on this system On Debian and Ubuntu systems you can install the required library and header files with apt install libpcap-dev On Fedora systems, with dnf install libpcap-devel" ) endif() find_package(LIBNET) if(NOT LIBNET_FOUND) message( FATAL_ERROR "Unable to find libnet development files on this system On Debian and Ubuntu systems you can install the required library and header files with apt install libnet1-dev On Fedora systems, with dnf install libnet-devel" ) endif() find_package(JSONC) if(NOT JSONC_FOUND) message( FATAL_ERROR "Unable to find libjson-c development files on this system On Debian and Ubuntu systems you can install the required library and header files with apt install libjson-c-dev On Fedora systems, with dnf install json-c-devel" ) endif() add_executable(${PROJECT_NAME} ${SOURCES}) check_symbol_exists(strdup "string.h" HAVE_STRDUP) if(HAVE_STRDUP) add_definitions(-DHAVE_STRDUP) endif() add_definitions(-DLINUX) add_definitions(-DOPENSSL) add_definitions(-D_DEFAULT_SOURCE=1) target_include_directories(ssldump PRIVATE ${PROJECT_SOURCE_DIR}/common/include ${PROJECT_SOURCE_DIR}/common/lib ${PROJECT_SOURCE_DIR}/null ${PROJECT_SOURCE_DIR}/ssl ${PROJECT_SOURCE_DIR}/base ${PROJECT_SOURCE_DIR}/pcap ${OPENSSL_INCLUDE_DIR} ${PCAP_INCLUDE_DIR} ${LIBNET_INCLUDE_DIR} ${JSONC_INCLUDE_DIR} ) target_link_libraries(ssldump PRIVATE ${OPENSSL_LIBRARIES} ${PCAP_LIBRARY} ${LIBNET_LIBRARY} ${JSONC_LIBRARIES} ) install(TARGETS ssldump DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES ssldump.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) ssldump-1.9/COPYING000077700000000000000000000000001470411077700154032COPYRIGHTustar00rootroot00000000000000ssldump-1.9/COPYRIGHT000066400000000000000000000063071470411077700143630ustar00rootroot00000000000000SSLDUMP LICENSE Maintained by a bunch of volunteers, see https://github.com/adulau/ssldump/blob/master/CREDITS Copyright (C) 2015-2021 the aforementioned volunteers Copyright (C) 1999-2001 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE ERIC RESCORLA AND RTFM ``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 REGENTS 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. TCPDUMP LICENSE The manual page for this software is partially excerpted from the tcpdump manual page, which is subject to the following license: Copyright (c) 1987, 1988, 1989, 1990, 1991, 1992, 1994, 1995, 1996, 1997 The Regents of the University of California. All rights reserved. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that: (1) source code distributions retain the above copyright notice and this paragraph in its entirety, (2) distributions including binary code include the above copyright notice and this paragraph in its entirety in the documentation or other materials provided with the distribution, and (3) all advertising materials mentioning features or use of this software display the following acknowledgement: ``This product includes software developed by the University of California, Lawrence Berkeley Laboratory and its contributors.'' Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 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. ssldump-1.9/CREDITS000066400000000000000000000020531470411077700141020ustar00rootroot00000000000000# Contributor to the maintained ssldump on GitHub version - Alexandre Dulaunoy https://github.com/adulau - William Robinet https://github.com/wllm-rbnt - Mathew Marcus https://github.com/mathewmarcus - Ulrik Haugen https://github.com/qha - Thomas Deutschmann https://github.com/Whissi - Alper Akcan https://github.com/alperakcan - Matt Slot https://github.com/mattslot - TheZ3ro https://github.com/TheZ3ro - EastTheWorld https://github.com/EaseTheWorld - David Kretch https://github.com/davidkretch - Vishwa Pravin https://github.com/lord8266 - Robert Scheck https://github.com/robert-scheck # Original credits from ssldump ssldump was written by Eric Rescorla The Windows port of ssldump was provided by Greg Stark. The following people have provided bug fixes, bug reports, or suggestions. Adam Cain Pavel Curtis Chris Jepeway Alexander Fetke Jeffrey Hafey Lutz Jaenicke Dave Jagoda Norbert Klasen Richard Levitte Hugh Mandeville Eric Murray Henrik Nordstrom Alper Akcan If you think you should be on this list, send me mail at . ssldump-1.9/ChangeLog000066400000000000000000000547201470411077700146440ustar00rootroot00000000000000# Changelog ## v1.8 (2023-08-14) ### Changes * [doc] typo fixed. [Alexandre Dulaunoy] * [doc] v1.7 released + new changelog. [Alexandre Dulaunoy] ### Other * Merge pull request #82 from wllm-rbnt/cmake. [Alexandre Dulaunoy] cmake * Add date to version output. [William Robinet] * Add comment for MacOS. [William Robinet] * Make it work on OpenBSD and FreeBSD. [William Robinet] * Add install target for man page. [William Robinet] * Set binary install target, update doc. [William Robinet] * Update README & fix version. [William Robinet] * Update gh workflows. [William Robinet] * Print meaningful error messages. [William Robinet] * Lower cmake version requirement (Ubuntu Focal) [William Robinet] * Add FindJSONC.cmake module + fix CMakeLists.txt. [William Robinet] * Remove autotools files. [William Robinet] * Initial cmake setup. [William Robinet] * Merge pull request #80 from wllm-rbnt/ts. [Alexandre Dulaunoy] Add -z option for printing timestamps in front of TCP headers * Add -z option for printing timestamps in front of TCP headers. [William Robinet] * Merge pull request #79 from robert-scheck/dependabot. [Alexandre Dulaunoy] Add dependabot configuration * Add dependabot configuration. [Robert Scheck] * Merge pull request #77 from robert-scheck/macos. [Alexandre Dulaunoy] Add macOS to CI builds * Add macOS to CI builds. [Robert Scheck] * Merge pull request #76 from robert-scheck/workflow-compiler. [Alexandre Dulaunoy] Switch to gcc-12 (default: gcc-11), clang-14 is newest in ubuntu-latest * Switch to gcc-12 (default: gcc-11), clang-14 is newest in ubuntu-latest. [Robert Scheck] ## v1.7 (2023-04-09) ### Changes * [doc] updated man page. [Alexandre Dulaunoy] * [CREDITS] new contributor added. [Alexandre Dulaunoy] * [doc] Add distribution including this version of ssldump. [Alexandre Dulaunoy] * [doc] v1.6 released. [Alexandre Dulaunoy] * [CREDITS] updated for version 1.6. [Alexandre Dulaunoy] * [doc] v1.6 release included. [Alexandre Dulaunoy] ### Other * Merge branch 'lord8266-tls1.3' [Alexandre Dulaunoy] * Fix comment. [Vishwa Pravin] * Remove irrelevant log entries, fix session ticket for tls1.2. [Vishwa Pravin] * Adding tls1.3 decryption support. [Vishwa Pravin] * Merge pull request #73 from robert-scheck/fedora. [Alexandre Dulaunoy] Update Fedora link, mention RHEL/derivatives * Update Fedora link, mention RHEL/derivatives. [Robert Scheck] * Merge pull request #74 from robert-scheck/centos. [Alexandre Dulaunoy] Fix typo, mention RHEL derivative * Fix typo, mention RHEL derivative. [Robert Scheck] * Merge pull request #69 from robert-scheck/ci-openssl. [Alexandre Dulaunoy] * CI: libtls-dev -> libssl-dev. [Robert Scheck] * Merge pull request #67 from robert-scheck/codeql-analysis. [Alexandre Dulaunoy] Add CodeQL analysis * Add CodeQL analysis. [Robert Scheck] * Merge pull request #68 from robert-scheck/wrong-type. [Alexandre Dulaunoy] For Y2K38 on 32 bit systems `time_t tv_sec` can be `long long` * For Y2K38 on 32 bit systems `time_t tv_sec` can be `long long` [Robert Scheck] * Merge pull request #66 from robert-scheck/ci-matrix. [Alexandre Dulaunoy] Improve CI builds using matrix strategy * Improve CI builds using matrix strategy. [Robert Scheck] ## v1.6 (2023-02-03) ### Changes * [doc] v1.5 released. [Alexandre Dulaunoy] * [doc] ChangeLog updated with release v1.5. [Alexandre Dulaunoy] ### Other * Merge pull request #63 from wllm-rbnt/dev. [Alexandre Dulaunoy] Fix missing port # in pcap files * Fix missing port # in pcap files. [William Robinet] * Merge pull request #61 from lord8266/aead. [Alexandre Dulaunoy] Print MAC keys only for non AEAD ciphers * Print MAC keys only for non AEAD ciphers. [Vishwa Pravin] ## v1.5 (2022-05-26) ### Changes * [doc] An example use-case of JA3. [Alexandre Dulaunoy] * [doc] Changelog updated. [Alexandre Dulaunoy] ### Other * Merge pull request #60 from lord8266/max. [Alexandre Dulaunoy] Add parentheses around MAX and MIN * Add parentheses around MAX and MIN. [Vishwa Pravin] * Merge pull request #58 from wllm-rbnt/dev. [Alexandre Dulaunoy] Add support for pcap output to FIFO * Add support for pcap output to FIFO. [William Robinet] ## v1.4 (2021-04-13) ### Changes * [doc] v1.4 released. [Alexandre Dulaunoy] * [doc] v1.4 released. [Alexandre Dulaunoy] * [doc] cleanup README. [Alexandre Dulaunoy] * [doc] v1.3 released. [Alexandre Dulaunoy] ### Other * Merge pull request #54 from wllm-rbnt/dev. [Alexandre Dulaunoy] Fix release version * Fix release version. [William Robinet] * Merge pull request #53 from wllm-rbnt/dev. [Alexandre Dulaunoy] Add support for IPv6 traffic dump * Add support for IPv6 traffic dump. [William Robinet] * Merge pull request #51 from wllm-rbnt/dev. [Alexandre Dulaunoy] dev 1.4 beta * Fix ja3(s) length of strings used in MD5 computation + update MD5 functions. [William Robinet] * Extract traffic mirroring commands from docker run scripts. [William Robinet] * Add support for ja3 & ja3s. [William Robinet] * Fix snprintf warning. [William Robinet] * Fix file ownership in Dockerfiles. [William Robinet] * Docker files initial import. [William Robinet] * Bump version to 1.4b. [William Robinet] ## v1.3 (2021-02-02) ### Changes * [doc] prepare for release v1.3. [Alexandre Dulaunoy] * [copyright] added additional copyright for all new contribution. [Alexandre Dulaunoy] ssldump is collectively owned by all the contributors. There is no change to the original license. * [doc] man page fixed for copyright notice + README updated. [Alexandre Dulaunoy] * [doc] William has a real name. [Alexandre Dulaunoy] * [credits] updated. [Alexandre Dulaunoy] * [doc] v1.2 released. [Alexandre Dulaunoy] * [doc] v1.2 released. [Alexandre Dulaunoy] ### Other * Merge pull request #49 from wllm-rbnt/leaks. [Alexandre Dulaunoy] Adjust copyright info * Adjust copyright info. [William Robinet] * Merge branch 'wllm-rbnt-leaks' [Alexandre Dulaunoy] * Fix bug introduced in 64effa3bb93c3a219fb0afd868c5bc2609093ced. [William Robinet] * Merge remote-tracking branch 'upstream/master' into leaks. [William Robinet] * Merge pull request #46 from wllm-rbnt/leaks. [Alexandre Dulaunoy] Leaks * Avoid leak in TCP segment reassembly code. [William Robinet] * Clean remaining json object in case of error. [William Robinet] * Abort properly on decode error. [William Robinet] * Avoid client session_id related leak. [William Robinet] * Avoid server_random related leak. [William Robinet] * Avoid client_random related leak. [William Robinet] * Check ssl_decode_enum() return code correctly. [William Robinet] * Exit process_tcp_packet() in case TCP header is incomplete. [William Robinet] * Check timestamp_diff return code correctly. [William Robinet] * Cleanup before exit on error. [William Robinet] * Fix for crash if length of captured frame is less than Ethernet header size. [William Robinet] * Check packet size before looking at IP header. [William Robinet] * Check return code after string extraction. [William Robinet] * Limit length during server name decoding. [William Robinet] * Bump version to 1.3 in configure.ac. [William Robinet] * Decode ClientHello v2 properly. [William Robinet] * Output error to stderr. [William Robinet] * Add proper return value. [William Robinet] * Avoid leak by freeing SSL decoding context properly. [William Robinet] * Close everything properly in case of SIGINT. [William Robinet] * Fix leak in associative array implementation. [William Robinet] * Merge branch 'wllm-rbnt-json' [Alexandre Dulaunoy] * Avoid some memory leaks. [William Robinet] * Fix time struct related warning (2) [William Robinet] * Fix time struct related warning. [William Robinet] * Add checks for libjson-c to configure.ac. [William Robinet] * Update CI workflow descriptions (2) [William Robinet] * Update CI workflow descriptions. [William Robinet] * First import of the JSON output code (https://github.com/adulau/ssldump/issues/41) [William Robinet] * Do not print information message when no connection is cleaned at shutdown. [William Robinet] * Fix memory leak in ssl_process_server_session_id() [William Robinet] * Close global pcap struct properly in case of SIGINT. [William Robinet] * Change binary installation directory to /usr/sbin. [William Robinet] * Move unused files away. [William Robinet] * Fix README.md - wrong package name for rpm based distros. [William Robinet] * Merge pull request #42 from wllm-rbnt/extensions. [Alexandre Dulaunoy] Add missing extension names * Add missing extension names. [William Robinet] * Merge pull request #39 from wllm-rbnt/save2pcap. [Alexandre Dulaunoy] Rework of https://github.com/adulau/ssldump/pull/26 after build system changes * Mention https://github.com/droe/sslsplit in README.md, fix man page. [William Robinet] * Add libnet1-dev deps to CI and README.md. [William Robinet] * Merge remote-tracking branch 'upstream/master' into save2pcap. [William Robinet] * Merge pull request #38 from wllm-rbnt/warnings. [Alexandre Dulaunoy] Code cleanup * Add missing Makefile.am. [William Robinet] * Rework https://github.com/adulau/ssldump/pull/26 after build system changes. [William Robinet] * Add save decrypted datato pcap. first alpha version. [Aleksey Ryabkov] * Fix for use of deprecated OpenSSL HMAC functions. [William Robinet] * Fix for type casting related warnings. [William Robinet] * Add missing function prototype. [William Robinet] * Fix for "warning: operator << has lower precedence than -" [William Robinet] * Remove definitions of unused variables. [William Robinet] * Fix for "warning: promoted type int of K&R function parameter is not compatible with the parameter type ..." [William Robinet] * Fix for "warning: using the result of an assignment as a condition without parentheses" [William Robinet] * Merge pull request #37 from wllm-rbnt/fixes. [Alexandre Dulaunoy] Fixes * Link README to README.md. [William Robinet] * Fix for uninitialized variables and possible overflow. [William Robinet] * Remove unused RCSSTRING variable globally. [William Robinet] * Reorganize README files. [William Robinet] * Add line return after "certificate_types" in output, see the problem in https://github.com/adulau/ssldump/issues/36#issuecomment-702586335. [William Robinet] ## v1.2 (2020-09-22) ### Changes * [cleanup] file cleanup (tab/ws mixed) [Alexandre Dulaunoy] * [doc] workflow badge added. [Alexandre Dulaunoy] * [workflow] config updated. [Alexandre Dulaunoy] * [workflow] pcap. [Alexandre Dulaunoy] * [workflow] add required packages. [Alexandre Dulaunoy] * [doc] clarification about ssldump repository + release v1.1. [Alexandre Dulaunoy] * [doc] release v1.1 - ChangeLog updated. [Alexandre Dulaunoy] ### Other * Merge pull request #34 from wllm-rbnt/build-sys. [Alexandre Dulaunoy] Build system updates * Fix long line in README.md. [William Robinet] * Update README.md with ./configure examples. [William Robinet] * Update README.md with ./configure options. [William Robinet] * Clean debug functions, remove duplicates. [William Robinet] * Define DEBUG when using --enable-debug. [William Robinet] * Add optional features to ./configure (ASAN, debug, optimization) [William Robinet] * Reenable OpenSSL code compilation. [William Robinet] * Update .gitignore, rearrange CI workflows variable definition. [William Robinet] * Remove -g from default CFLAGS and check for Clang explicitly. [William Robinet] * Remove deprecated define. [William Robinet] * Reorder checks in configure.ac. [William Robinet] * Prepare ASAN build. [William Robinet] * Force use of GCC in GCC CI. [William Robinet] * Add Clang CI. [William Robinet] * Merge pull request #35 from mattslot/master. [Alexandre Dulaunoy] Add renegotiation_info extension * Add renegotiation_info extension. [Matt Slot] * Merge pull request #33 from wllm-rbnt/oob-reads. [Alexandre Dulaunoy] Fix multiple segfaults on out-of-bounds read access * Fix multiple segfault by OOB read because of wrong format string specifier. [William Robinet] * Fix segfault by OOB read on malformed packets (2) [William Robinet] * Fix segfault by OOB read on malformed packets. [William Robinet] * Merge pull request #31 from wllm-rbnt/autoconf2020. [Alexandre Dulaunoy] Autoconf2020 * Fix deprecation warning from libcap 1.9.1. [William Robinet] * Make FreeBSD (12.1) happy. [William Robinet] * Update CI workflow. [William Robinet] * Apply Replace-direct-struct-access-patterns-with-OpenSSL-1.1-ge.patch from Debian pkg. [William Robinet] * Update readme. [William Robinet] * Fix readme. [William Robinet] * Improve lib detection and .gitignore. [William Robinet] * Remove generated file. [William Robinet] * Add man page to Makefile.am. [William Robinet] * Fix warning about type of arguments of pcap_handler. [William Robinet] * Fix warning about signal() arguments type. [William Robinet] * Fix build warnings for missing prototypes. [William Robinet] * Add build deps to readme. [William Robinet] * Fix readme. [William Robinet] * Autoconf setup rewritten. [William Robinet] * Set theme jekyll-theme-minimal. [Alexandre Dulaunoy] * Merge pull request #27 from microolap-technologies/resumed_sessions. [Alexandre Dulaunoy] add support to decrypt resumed sessions * Add support to decrypt resumed sessions. [Aleksey Ryabkov] * First test workflow. [Alexandre Dulaunoy] * Merge pull request #25 from microolap-technologies/sni_2_srv_name. [Alexandre Dulaunoy] use sni in server_name * Use sni in server_name. [Aleksey Ryabkov] ## v1.1 (2019-12-28) ### Changes * [doc] Changelog reflecting v1.0 release. [Alexandre Dulaunoy] ### Other * Merge pull request #24 from mattslot/master. [Alexandre Dulaunoy] Explicit parameter types for static prototypes * Explicit parameter types for static prototypes. [Matt Slot] * Merge pull request #22 from EaseTheWorld/handshake. [Alexandre Dulaunoy] Handle weird 3-way handshake(syn&ack -> syn -> ack) * Handle weird 3-way handshake(syn&ack -> syn -> ack) I have pcaps from Cisco2960 span port and found some tcp handshake has weird order 3-way handshake. It seems first packet order between sessions is not guaranted for cisco span. maybe. Current state transition is INIT -- syn --> SYN1 -- syn&ack --> SYN2 -- ack --> ESTABLISHED New state transition starts with SYN1 or SYN2 and adds(revive actually) STATE_ACK to handle both cases. case1 : INIT -- syn --> SYN1 -- syn&ack -->ACK -- ack --> ESTABLISHED (normal) case2 : INIT -- syn&ack --> SYN2 -- syn -->ACK -- ack --> ESTABLISHED (weird) [EaseTheWorld] ## v1.0 (2019-05-26) ### Changes * [build] v1.0 released. [Alexandre Dulaunoy] * [changelog] v1.0 released. [Alexandre Dulaunoy] * [build] gitchangelogrc configuration added. [Alexandre Dulaunoy] ### Other * Merge pull request #21 from qha/repair-make-targets. [Alexandre Dulaunoy] Repair make targets and ssl/ssldecode.c, bump version * Rerun autoconf. [Ulrik Haugen] * Bump version. [Ulrik Haugen] * Repair ssl_key_log_file handling. [Ulrik Haugen] Set ssl_key_log_file to null in ssl_decode_ctx_create if no file name was supplied. Only seek ssl_key_log_file in ssl_read_key_log_file if it is non null. Repair order of fseek parameters. * Take project name and version from configure define. [Ulrik Haugen] ... in print_version. * Enable compiling without std c99 when OPENSSL is defined. [Ulrik Haugen] * Repair spelling in comments. [Ulrik Haugen] * Remove presumably extraneous files. [Ulrik Haugen] * Remove extraneous files. [Ulrik Haugen] * Add .gitignore. [Ulrik Haugen] * Make install target install doc files. [Ulrik Haugen] * Repair installdir variable names. [Ulrik Haugen] * Repair dist target. [Ulrik Haugen] Mark phony targets as such. Cease use of unobtainable version-check.pl. Take version from configure substituted variable. Adjust dist archive location. Prune more backup files. * Whitespace. [Ulrik Haugen] * Set package name in configure.in, move version there. [Ulrik Haugen] * Merge pull request #19 from 1div0/master. [Alexandre Dulaunoy] GREASE * GREASE. [Peter Kovář] * Merge pull request #18 from mathewmarcus/dh_aes_gcm_support. [Alexandre Dulaunoy] Dh aes gcm support * Use macro to check if cipher is AEAD. [mathewmarcus] * Update man page with -l sslkeylogfile option. [mathewmarcus] * Updated relevant ciphersuites with GCM enc. [mathewmarcus] * Added fix for AES256 GCM decryption. [mathewmarcus] * Added case insensitive string comparison macro. [mathewmarcus] * Added support for AES GCM decryption. [mathewmarcus] * Use sslkeylogfile to get MS if possible. [mathewmarcus] * Added function to extract MS from sslkeylogfile. [mathewmarcus] * Added GCM specific ciphersuite info. [mathewmarcus] * Added sslkeylogfile pointer to decode ctx. [mathewmarcus] * Fix decoding and printing of DiffieHellman Client params. [mathewmarcus] * Add l option for SSLKEYLOGFILE. [mathewmarcus] * Merge pull request #17 from mathewmarcus/fix_extension_bug. [Alexandre Dulaunoy] correctly handle case where server hello does not request extension s… * Improve syntax. [mathewmarcus] * Correctly handle case where server hello does not request extension specified by client. [mathewmarcus] * Merge pull request #16 from mathewmarcus/tls_extensions. [Alexandre Dulaunoy] Tls extensions * Code cleanup. [mathewmarcus] * Added support for SNI. [mathewmarcus] * Added support for encrypt-then-mac. [mathewmarcus] * Finished support for extended master secret. [mathewmarcus] * Calculate session hash. [mathewmarcus] * Added struct to store extensions. [mathewmarcus] * Added struct to store extensions. [mathewmarcus] * Revert "moved struct ssl_decoder_ definition into header file because we need it in ssl.enums.c" [Mathew Marcus] This reverts commit 193c6001086920c0623593aba373f948aa275f8d. * Moved struct ssl_decoder_ definition into header file because we need it in ssl.enums.c. [mathewmarcus] * Added handler for extended master secret extension. [mathewmarcus] * Rename functions. [mathewmarcus] * Record handshake messages for session hash. [Mathew Marcus] * Include extensions in output. [mathewmarcus] * Merge pull request #15 from Whissi/update-ciphers. [Alexandre Dulaunoy] Update ciphers * Adjust cipher suite formation. [Thomas Deutschmann] * Add TLS 1.3 cipher suites. [Thomas Deutschmann] * Add fallback signaling cipher suite. [Thomas Deutschmann] * Add CHACHA20_POLY1305 cipher suite. [Thomas Deutschmann] * Merge pull request #14 from davidkretch/fix-typo. [Alexandre Dulaunoy] Fix a typo in the man page * Fix a typo in the man page. [David Kretch] Delete the extra "to" in "To decrypt traffic to to host" under the examples section. * Merge pull request #13 from alperakcan/master. [Alexandre Dulaunoy] fix ssl record queue data read * - fix mis calculation of read_left if queue already has some data, which might not be bigger than ssl_header_size - update q->ptr only if q->data is changed. [Alper Akcan] * Merge pull request #1 from adulau/master. [Alper Akcan] Merge pull request #12 from alperakcan/master * Merge pull request #12 from alperakcan/master. [Alexandre Dulaunoy] Fix packet length calculation if IP length is 0, due to TSO * Fix packet length calculation if IP length is 0, due to TSO. [Alper Akcan] * Typo fixed. [Alexandre Dulaunoy] * Explanation added in a new README. [Alexandre Dulaunoy] * Merge pull request #9 from PequalsNP-team/master. [Alexandre Dulaunoy] updated configure for new libpcap location on most linux distro * Updated configure for new libpcap location on most linux distro. [thez3ro] * Merge pull request #7 from knowtoto/master. [Alexandre Dulaunoy] Fix a null pointer dereference bug * Fix a null pointer dereference bug of tls12_prf be caused by invalid extern declaration for digests variable. [hyunkyu.oh] * Merge pull request #5 from wllm-rbnt/master. [Alexandre Dulaunoy] More code cleaning * Include string.h (remove warnings about memcpy) [William Robinet] * Fix order of arguments in calls to calloc. [William Robinet] * "Each invocation of va_start() must be matched by a corresponding invocation of va_end()" [William Robinet] * Remove dead code. [William Robinet] * Do not use uninitialized variable. [William Robinet] * Make valgrind/memcheck happy. [William Robinet] * Add missing comma (introduced by 2d067c26503ace1466d132e7efd9f0ff7885295a) [William Robinet] * Merge pull request #4 from wllm-rbnt/master. [Alexandre Dulaunoy] Fix cleanup loop * Avoid auto-vivisection during connection clean-up ... [William Robinet] * Fix inactive connection removal. [William Robinet] * Merge pull request #3 from wllm-rbnt/master. [Alexandre Dulaunoy] [bugfix] Initialize initial reference timeval * Initialize initial reference timeval Avoids wrong cleaning of first connection(s) [William Robinet] * Merge pull request #2 from wllm-rbnt/master. [Alexandre Dulaunoy] Fixes for 2 memory leaks and in flight structure cleaning * Fix memory leak if SSL session id is not present. [William Robinet] * In flight connection pool cleaning. [William Robinet] * Fix memory leak at connection closing. [William Robinet] * Merge pull request #1 from wllm-rbnt/csloop. [Alexandre Dulaunoy] Fix for infinite loop in Ciphers Suite decoding * Fix for infinite loop in Ciphers Suite decoding. [William Robinet] * Dtable bug fixed: list overrun (from NetBSD tree) [Alexandre Dulaunoy] * Memory leak per TLS session removed. Call cleanup after each finalization. [Alexandre Dulaunoy] * Free also the packet structure. [Alexandre Dulaunoy] * Snaplen increased to the default jumbo frame size. [Alexandre Dulaunoy] If the snaplen is lower than the total frame length announced, ssldump won't be able to reassemble the payload. "Length mismatch" error. Tested on Ethernet uplinks supporting jumbo frame. * Continue even if no IP address is assigned on the interface. [Alexandre Dulaunoy] ssldump in a production environment can be used on a capture interface where no IP addresses are assigned. Print a warning instead of exiting. * Modern config.guess/sub from Ubuntu ssldump package. [Alexandre Dulaunoy] * Ssldump-0.9-ciphersuites.patch. [Alexandre Dulaunoy] * Ssldump-0.9-ssl-enums.patch. [Alexandre Dulaunoy] * Ssldump-0.9-tlsv12.patch. [Alexandre Dulaunoy] * Ssldump-0.9-pcap-vlan.patch. [Alexandre Dulaunoy] * Ssldump-0.9-link_layer.patch. [Alexandre Dulaunoy] * Ssldump-0.9-table-stops.patch. [Alexandre Dulaunoy] * Sldump-0.9-cvs-20060619.patch. [Alexandre Dulaunoy] * Sldump-0.9-aes.patch. [Alexandre Dulaunoy] * Sldump-0.9-libpcap.patch. [Alexandre Dulaunoy] * Ssldump-0.9-openssl.patch. [Alexandre Dulaunoy] * Ssldump_0.9b3.orig.tar.gz Import. [Alexandre Dulaunoy] ssldump-1.9/INSTALL000066400000000000000000000027701470411077700141210ustar00rootroot00000000000000$Id: INSTALL,v 1.5 2001/09/14 22:29:13 ekr Exp $ If you don't have libpcap, you'll need to get it and install it. You can obtain it from: http://www.tcpdump.org/ If you want to be able to decrypt SSL traffic or view certificates, get OpenSSL if you don't have it: http://www.openssl.org/ Once you've built and installed libpcap and OpenSSL, you're ready to build ssldump. ssldump uses a GNU autoconf-based configuration to automatically configure the build. In the simplest form you can simply do: ./configure If the configure script can't find libpcap, it will abort. If you've installed it in unobvious place, you may need to give configure a hint using the '--with-pcap' or '--with-pcap-{lib,inc}' switches. If the configure script can't find OpenSSL, it will continue without it. If your OpenSSL is in a nonstandard location, you may need to give configure a hint with the '--with-openssl' or '--with-openssl-{lib,include}' switches. Once you've done the configure, you can simply run 'make'. Note that on some platforms (HP/UX) you will have to use GNU make (gmake). If the make succeeds, run a 'make install' (you will probably need to be root to do this.) TESTED PLATFORMS FreeBSD 2.2.8, 3.4 HP/UX 10.20 Linux (Red Hat, Debian) Solaris 2.x If you get ssldump to work on a platform not listed above, please send mail to ssldump@rtfm.com with the platform and any fixes you had to make. INSTALLING ON WINDOWS Read the file INSTALL.W32 in this directory for instructions on installing on Windows. ssldump-1.9/INSTALL.W32000066400000000000000000000106401470411077700144660ustar00rootroot00000000000000 Notes First, make sure you've read the README file. Build Environment ----------------- The build environment is assumed to be Microsoft Visual C++ 6.0 SP4 (VC6), although earlier or later versions may work. In particular, the make-like utility used to build this port of ssldump is NMAKE version 6.00.x from Microsoft. The basis for this port is ssldump version 0.9b3. The win32 directory contains the win32-specific stuff, including the NMAKE makefile vcwin32.mak. You need to have your environment variables and PATH correctly setup to properly use the command-line VC6 tools. In the VC6\bin directory is a batch file, VCVARS32.bat, which should set things up correctly. You should run this batch file prior to attempting a build. What you need (besides the ssldump source) ------------------------------------------ You must have downloaded and installed the following from the WinPcap/Windump project: 1. The Winpcap developer's pack, version 2.3, from http://winpcap.polito.it/install/bin/WPdpack_2_3.zip contains the pcap.h and net/bpf.h files, and the pcap import library. Place these in the win32 directory. 2. The Winpcap source code distribution, version 2.3, from http://winpcap.polito.it/install/bin/WPcapSrc_2_3.zip. It contains some .h files commonly found on UNIX systems that ssldump expects. Place these in the win32 directory. 3. The Winpcap auto-installer, version 2.3, from http://winpcap.polito.it/install/bin/WinPcap_2_3_nogui.exe. This is only needed to run ssldump, not needed to build it. It is needed on *any* windows system on which ssldump is run. It installs a device driver and the pcap library DLL. 4. Possibly the Windump utility from http://windump.polito.it/install/bin/WinDump.exe. This is essentially a Windows port of tcpdump, with an extra -D option. This option enumerates the interface names so that you at least have a clue to what to supply the -i option (see below). The win32 directory should look like the following after these files are downloaded and extracted: winpcap WPdpack Ssldump.html vcwin32.mak OpenSSL Support --------------- By default, the OpenSSL libraries are not linked into ssldump. If you want to link in the OpenSSL libraries, you'll need to customize the makefile. First, look for the macro OPENSSL and change its value to "yes". Next, look for the macro OPENSSL_DIR and make sure it points to the openssl distribution on your machine. You must build a version(s) of SSL that links to the static C run-time library; these are distinguished by the use of the compiler flag /MT for release versions, and /MTd for debug versions. Then you must set the OPENSSL_RELEASE and OPENSSL_DEBUG macros to point to the directories that contain the libraries for these versions. If you only intend to build one of either the debug or release versions, you only need to define the corresponding OPENSSL_ macro. Building ssldump ---------------- To build, run (from the ssldump root directory): nmake /f win32\vcwin32.mak all this creates a directory, out32, which contains the object files and the ssldump.exe executable. The build produces a simple command-line ssldump.exe which must be run from a console window (i.e. a DOS box). It builds the release version by default. Set the macro CFG="debug" to build a debug version, e.g. nmake /f vcwin32.mak all CFG="debug". win32\ssldump.html contains an HTML version of the ssldump.1 manpage. You should read this to learn the options. What are the names of the Interfaces? ------------------------------------- One tricky aspect is choosing the correct interface name for the -i option of ssldump. AFAIK, there is no standard windows utility that will give you the correct names for the interfaces. For example, on my system they are named PPPMAC (for the PPP adapter) and CBEN5 (for my Ethernet Adapter). I did find these names in the registry under HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Class\Net\nnnn\NDIS\LogDriverName, but this may be different on other Windows OSes. The Windump utility from the WinPcap folks has an option, -D, to enumerate these interface names. Use the Windump utility or hunt through the registry to find the names of your interfaces. If you don't specify the interface explicitly with the -i option, ssldump will select the 'first' interface and this may be exactly what you want. ssldump-1.9/NEWS000077700000000000000000000000001470411077700153262ChangeLogustar00rootroot00000000000000ssldump-1.9/README000077700000000000000000000000001470411077700152142README.mdustar00rootroot00000000000000ssldump-1.9/README.md000066400000000000000000000104651470411077700143470ustar00rootroot00000000000000# ssldump - (de-facto repository gathering patches around the cyberspace) [![Build CI](https://github.com/adulau/ssldump/actions/workflows/build.yml/badge.svg)](https://github.com/adulau/ssldump/actions/workflows/build.yml) [![CodeQL analysis](https://github.com/adulau/ssldump/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/adulau/ssldump/actions/workflows/codeql-analysis.yml) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/adulau/ssldump/badge)](https://securityscorecards.dev/viewer/?uri=github.com/adulau/ssldump) # Release and tagging - Current version of ssldump is [v1.8](https://github.com/adulau/ssldump/releases/tag/v1.8) (released: 2023-08-14) - [ChangeLog](https://raw.githubusercontent.com/adulau/ssldump/master/ChangeLog) # What about the original ssldump? This repository is composed of the original SSLDUMP 0.9b3 + a myriad of patches (from Debian and other distributions) + contributions via PR ssldump is an SSLv3/TLS network protocol analyzer. It identifies TCP connections on the chosen network interface and attempts to interpret them as SSLv3/TLS traffic. When it identifies SSLv3/TLS traffic, it decodes the records and displays them in a textual form to stdout. If provided with the appropriate keying material, it will also decrypt the connections and display the application data traffic. It also includes a JSON output option, supports [JA3](https://github.com/salesforce/ja3) and IPv6. # How to do I run ssldump? `./ssldump -j -ANH -n -i any | jq` will run ssldump on all interfaces and output the result in JSON format including ja3 hashes. For more details, check the man page. ## How can I lookup ja3 hashes? This example will query ja3er.com service to display the known ja3 hashes from the TLS handshaked in the pcap. `./ssldump -r yourcapture.pcap -j | jq -r 'select(.ja3_fp != null) | .ja3_fp' | parallel 'curl -s -X GET 'https://ja3er.com/search/{}' | jq .'` # Why do you maintain this repository? Because it's a mess. The software maintenance process for old free (unmaintained) software like ssldump is a complete chaotic process. I do this to ease my pain and this could help other too (but this is just a collateral damage). # Where ssldump is used? - I used it for a relatively small project called Passive SSL. For more information, [Passive SSL Passive Detection and Reconnaissance Techniques, to Find, Track, and Attribute Vulnerable ”Devices”](https://www.first.org/resources/papers/conf2015/first_2015_-_leverett_-_dulaunoy_-_passive_detection_20150604.pdf). Additional back-end code available is in the [crl-monitor ](https://github.com/adulau/crl-monitor/tree/master/bin/x509) repository. - ssldump is used in the [D4-Project](https://github.com/D4-project/). # Where ssldump is available? - Alpine Linux [ssldump](https://pkgs.alpinelinux.org/packages?name=ssldump&branch=edge&repo=&arch=&maintainer=) - Arch Linux [ssldump](https://aur.archlinux.org/packages/ssldump) - CentOS, RHEL, Rocky (via [EPEL](https://docs.fedoraproject.org/en-US/epel/)) [ssldump](https://packages.fedoraproject.org/pkgs/ssldump/ssldump/) - Fedora [ssldump](https://packages.fedoraproject.org/pkgs/ssldump/ssldump/) - Kali Linux [ssldump](https://www.kali.org/tools/ssldump/) - Ubuntu Linux [ssldump](http://changelogs.ubuntu.com/changelogs/pool/universe/s/ssldump/) # Build instructions Install dependencies on Debian & Ubuntu (as root): ``` apt install build-essential git cmake ninja-build libssl-dev libpcap-dev libnet1-dev libjson-c-dev ``` On Fedora, CentOS, RHEL & Rocky (as root): ``` dnf install git cmake ninja-build gcc openssl-devel libpcap-devel libnet-devel json-c-devel ``` On OpenBSD (as root): ``` pkg_add git cmake ninja json-c libnet ``` On FreeBSD (as root): ``` pkg install git cmake ninja json-c libnet ``` On MacOS (as root): ``` brew install cmake ninja openssl@3 libpcap libnet json-c ``` Compile & install: ``` git clone https://github.com/adulau/ssldump.git cd ssldump cmake -G Ninja -B build ninja -C build ./build/ssldump -v (optional, as root) ninja -C build install ``` # Notes The "save to pcap" (-w) option by @ryabkov, is heavily based on the work of @droe on https://github.com/droe/sslsplit . # Contributing The contributing policy is simple. If you have a patch to propose, make a pull-request via the interface. If the patch works for me, it's merged. ssldump-1.9/README.old000066400000000000000000000055621470411077700145270ustar00rootroot00000000000000 # Old original README file from SSLDUMP 0.9b3 and probably outdated $Id: README,v 1.9 2002/08/17 01:33:15 ekr Exp $ SSLDUMP 0.9b3 ssldump is an SSLv3/TLS network protocol analyzer. It identifies TCP connections on the chosen network interface and attempts to interpret them as SSLv3/TLS traffic. When it identifies SSLv3/TLS traffic, it decodes the records and displays them in a textual form to stdout. If provided with the appropriate keying material, it will also decrypt the connections and display the application data traffic. ssldump depends on the libpcap packet capture library. Some systems (e.g. FreeBSD) now have libpcap as part of their standard install. On other systems, you will need to install it. You can obtain the distribution from: http://www.tcpdump.org/ If linked with OpenSSL, ssldump can display certificates in decoded form and decrypt traffic (provided that it has the appropriate keying material). Again, OpenSSL may be installed on your system. Otherwise you can obtain it from: http://www.openssl.org/ See the file INSTALL for instructions on building and installing ssldump. STABILITY This is a beta release of ssldump. The UNIX portions have received extensive testing and are believed to be quite solid. The Windows port is substantially less stable. CHANGES SINCE 0.9b2 Security fix: some potential over and underflows Added support for VLANs. Added -P flag to disable promiscuous mode. Fixed bugs in the TCP reassembly code. A lot of bug fixes. See the ChangeLog for a more complete list of changes. MAILING LIST For support questions and general discussion on ssldump, please subscribe to the ssldump-users mailing list. Subscription is by majordomo. To subscribe, send a message with no subject and a body consisting of the single line: subscribe ssldump-users to majordomo@rtfm.com. Note, you cannot send messages to the list unless you are subscribed. BUG REPORTS Please send bug reports either to the ssldump-users mailing list or to ssldump@rtfm.com. INTEROPERABILITY NOTE Previous versions of ssldump automatically looked for the keyfile in 'server.pem' and used the password 'password'. This version removes those defaults. For decryption to work you MUST specify the keyfile (and password if the keyfile is encrypted.) NEW VERSIONS Newer versions of ssldump can be found at: http://www.rtfm.com/ssldump/ SSL REFERENCES The SSLv3 specification can be found at: http://home.netscape.com/eng/ssl3/draft302.txt The TLS specification is in RFC 2246 and can be found at: http://www.ietf.org/rfc/rfc2246.txt SHAMELESS PLUG Extremely detailed coverage of SSL/TLS can be found in _SSL_and_TLS:_Designing_and_Building_Secure_Systems_ Eric Rescorla Addison-Wesley, 2001 ISBN 0-201-61598-3 _SSL_and_TLS_ makes extensive use of ssldump to demonstrate real-life SSL behavior. If you like ssldump and want to learn about SSL, you might consider buying my book. ssldump-1.9/_config.yml000066400000000000000000000000331470411077700152050ustar00rootroot00000000000000theme: jekyll-theme-minimalssldump-1.9/base/000077500000000000000000000000001470411077700137745ustar00rootroot00000000000000ssldump-1.9/base/network.c000066400000000000000000000204441470411077700156350ustar00rootroot00000000000000/** network.c Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: network.c,v 1.10 2002/09/09 21:02:58 ekr Exp $ ekr@rtfm.com Tue Dec 29 09:52:54 1998 */ #include #include #include "network.h" #ifndef _WIN32 #include #include #include #include #endif #include "tcppack.h" #ifdef STDC_HEADERS #include #endif UINT4 NET_print_flags; struct network_handler_ { proto_mod *mod; proto_ctx *ctx; }; int network_handler_create(proto_mod *mod, n_handler **handlerp) { int r, _status; n_handler *handler = 0; if(!(handler = (n_handler *)malloc(sizeof(n_handler)))) ABORT(R_NO_MEMORY); if(mod->vtbl->create_ctx) { if((r = mod->vtbl->create_ctx(mod->handle, &handler->ctx))) ABORT(r); } handler->mod = mod; *handlerp = handler; _status = 0; abort: if(_status) { network_handler_destroy(mod, &handler); } return _status; } int network_handler_destroy(proto_mod *mod, n_handler **handlerp) { n_handler *handler = 0; if(!handlerp || !*handlerp) return 0; handler = *handlerp; mod->vtbl->destroy_ctx(mod->handle, &handler->ctx); free(*handlerp); *handlerp = 0; return 0; } int network_process_packet(n_handler *handler, struct timeval *timestamp, UCHAR *data, int length, int af) { int r; int hlen; packet p; u_short off; int proto; /*We can pretty much ignore all the options*/ memcpy(&p.ts, timestamp, sizeof(struct timeval)); p.base = data; p._len = length; p.data = data; p.len = length; p.af = af; if(p.len < 20) { if(!(NET_print_flags & NET_PRINT_JSON)) printf( "Malformed packet, packet too small to contain IP header, skipping " "...\n"); return 0; } memset(&p.i_addr.so_st, 0x0, sizeof(struct sockaddr_storage)); memset(&p.r_addr.so_st, 0x0, sizeof(struct sockaddr_storage)); if(af == AF_INET) { p.l3_hdr.ip = (struct ip *)data; memcpy(&p.i_addr.so_in.sin_addr, &p.l3_hdr.ip->ip_src, sizeof(struct in_addr)); p.i_addr.so_in.sin_family = AF_INET; memcpy(&p.r_addr.so_in.sin_addr, &p.l3_hdr.ip->ip_dst, sizeof(struct in_addr)); p.r_addr.so_in.sin_family = AF_INET; /*Handle, or rather mishandle, fragmentation*/ off = ntohs(p.l3_hdr.ip->ip_off); if((off & 0x1fff) || /*Later fragment*/ (off & 0x2000)) { /*More fragments*/ /* fprintf(stderr,"Fragmented packet! rejecting\n"); */ return 0; } hlen = p.l3_hdr.ip->ip_hl * 4; p.data += hlen; p.len = ntohs(p.l3_hdr.ip->ip_len); if(p.len > length) { if(!(NET_print_flags & NET_PRINT_JSON)) printf( "Malformed packet, size from IP header is larger than size " "reported by libpcap, skipping ...\n"); return 0; } if(p.len == 0) { DBG((0, "ip length reported as 0, presumed to be because of 'TCP " "segmentation offload' (TSO)\n")); p.len = p._len; } p.len -= hlen; proto = p.l3_hdr.ip->ip_p; } else { p.l3_hdr.ip6 = (struct ip6_hdr *)data; memcpy(&p.i_addr.so_in6.sin6_addr, &p.l3_hdr.ip6->ip6_src, sizeof(struct in6_addr)); p.i_addr.so_in6.sin6_family = AF_INET6; memcpy(&p.r_addr.so_in6.sin6_addr, &p.l3_hdr.ip6->ip6_dst, sizeof(struct in6_addr)); p.r_addr.so_in6.sin6_family = AF_INET6; // Skip packets with header extensions if(p.l3_hdr.ip6->ip6_ctlun.ip6_un1.ip6_un1_nxt != IPPROTO_TCP) { return 0; } hlen = 40; // Fixed header size with no extension p.data += hlen; p.len = ntohs(p.l3_hdr.ip6->ip6_ctlun.ip6_un1.ip6_un1_plen); if(p.len > length) { if(!(NET_print_flags & NET_PRINT_JSON)) printf( "Malformed packet, size from IP header is larger than size " "reported by libpcap, skipping ...\n"); return 0; } if(p.len == 0) { DBG((0, "ip length reported as 0, presumed to be because of 'TCP " "segmentation offload' (TSO)\n")); p.len = p._len; } proto = p.l3_hdr.ip6->ip6_ctlun.ip6_un1.ip6_un1_nxt; } switch(proto) { case IPPROTO_TCP: if((r = process_tcp_packet(handler->mod, handler->ctx, &p))) ERETURN(r); break; } return 0; } int packet_copy(packet *in, packet **out) { int _status; packet *p = 0; if(!(p = (packet *)calloc(1, sizeof(packet)))) ABORT(R_NO_MEMORY); memcpy(&p->ts, &in->ts, sizeof(struct timeval)); if(!(p->base = (UCHAR *)malloc(in->_len))) ABORT(R_NO_MEMORY); memcpy(p->base, in->base, p->_len = in->_len); p->data = p->base + (in->data - in->base); p->len = in->len; p->ip = (struct ip *)(p->base + ((UCHAR *)in->ip - in->base)); p->tcp = (struct tcphdr *)(p->base + ((UCHAR *)in->tcp - in->base)); *out = p; _status = 0; abort: if(_status) { packet_destroy(p); } return _status; } int packet_destroy(packet *p) { if(!p) return 0; FREE(p->base); FREE(p); return 0; } int timestamp_diff(struct timeval *t1, struct timeval *t0, struct timeval *diff) { long d; if(t0->tv_sec > t1->tv_sec) ERETURN(R_BAD_ARGS); /*Easy case*/ if(t0->tv_usec <= t1->tv_usec) { diff->tv_sec = t1->tv_sec - t0->tv_sec; diff->tv_usec = t1->tv_usec - t0->tv_usec; return 0; } /*Hard case*/ d = t0->tv_usec - t1->tv_usec; if(t1->tv_sec < (t0->tv_sec + 1)) ERETURN(R_BAD_ARGS); diff->tv_sec = t1->tv_sec - (t0->tv_sec + 1); diff->tv_usec = 1000000 - d; return 0; } int lookuphostname(struct sockaddr_storage *so_st, char **namep) { int r = 1; *namep = calloc(1, NI_MAXHOST); void *addr = NULL; if(!(NET_print_flags & NET_PRINT_NO_RESOLVE)) { r = getnameinfo((struct sockaddr *)so_st, sizeof(struct sockaddr_storage), *namep, NI_MAXHOST, NULL, 0, 0); } if(r) { if(so_st->ss_family == AF_INET) { addr = &((struct sockaddr_in *)so_st)->sin_addr; } else { addr = &((struct sockaddr_in6 *)so_st)->sin6_addr; } inet_ntop(so_st->ss_family, addr, *namep, INET6_ADDRSTRLEN); } return 0; } int addrtotext(struct sockaddr_storage *so_st, char **namep) { *namep = calloc(1, NI_MAXHOST); void *addr = NULL; if(so_st->ss_family == AF_INET) { addr = &((struct sockaddr_in *)so_st)->sin_addr; } else { addr = &((struct sockaddr_in6 *)so_st)->sin6_addr; } inet_ntop(so_st->ss_family, addr, *namep, INET6_ADDRSTRLEN); return 0; } ssldump-1.9/base/network.h000066400000000000000000000104271470411077700156420ustar00rootroot00000000000000/** network.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: network.h,v 1.3 2001/09/14 22:29:14 ekr Exp $ ekr@rtfm.com Tue Dec 29 09:53:50 1998 */ #ifndef _network_h #define _network_h #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #ifndef _WIN32 #include #include #else #include #endif #include #include #include #include #include #include typedef struct network_handler_ n_handler; typedef struct proto_mod_ proto_mod; typedef struct proto_handler_ proto_handler; typedef struct packet_ packet; int network_handler_create PROTO_LIST((proto_mod * mod, n_handler **handlerp)); int network_handler_destroy PROTO_LIST((proto_mod * mod, n_handler **handlerp)); int network_process_packet PROTO_LIST((n_handler * handler, struct timeval *timestamp, UCHAR *data, int length, int af)); int packet_copy PROTO_LIST((packet * in, packet **out)); int packet_destroy PROTO_LIST((packet * p)); int timestamp_diff PROTO_LIST((struct timeval * t1, struct timeval *t0, struct timeval *diff)); int lookuphostname PROTO_LIST((struct sockaddr_storage * addr, char **name)); int addrtotext PROTO_LIST((struct sockaddr_storage * addr, char **name)); struct packet_ { struct timeval ts; UCHAR *base; /*The base of the packet*/ int _len; UCHAR *data; /*The data ptr appropriate to this layer*/ int len; /*The length of the data segment*/ /*These just save us the effort of doing casts to the data segments*/ struct ip *ip; /*The IP header*/ int af; union { struct ip *ip; /*The IP header*/ struct ip6_hdr *ip6; /*The IP header*/ } l3_hdr; struct tcphdr *tcp; /*The TCP header*/ union { struct sockaddr_storage so_st; struct sockaddr_in so_in; struct sockaddr_in6 so_in6; } i_addr; union { struct sockaddr_storage so_st; struct sockaddr_in so_in; struct sockaddr_in6 so_in6; } r_addr; }; #include "tcpconn.h" #include "proto_mod.h" extern UINT4 NET_print_flags; #define NET_PRINT_TCP_HDR 1 #define NET_PRINT_TYPESET 2 #define NET_PRINT_ACKS 4 #define NET_PRINT_NO_RESOLVE 8 #define NET_PRINT_JSON 16 #define NET_PRINT_TS 32 #endif ssldump-1.9/base/pcap-snoop.c.in000066400000000000000000000370251470411077700166330ustar00rootroot00000000000000/** pcap-snoop.c Copyright (C) 1999-2001 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: pcap-snoop.c,v 1.14 2002/09/09 21:02:58 ekr Exp $ ekr@rtfm.com Tue Dec 29 10:17:41 1998 */ #include #include #ifndef __OpenBSD__ #include #endif #ifndef _WIN32 #include #endif #include #ifndef _WIN32 #include #include #else #include #include #endif #include #include #include #include "network.h" #include #include #include "null_analyze.h" #include "ssl_analyze.h" #ifdef ENABLE_RECORD #include "record_analyze.h" #endif #include "pcap_logger.h" #include "tcpconn.h" #ifndef ETHERTYPE_8021Q #define ETHERTYPE_8021Q 0x8100 #endif char *collapse_args PROTO_LIST((int argc, char **argv)); static int pcap_if_type = DLT_NULL; int err_exit PROTO_LIST((char *str, int num)); int usage PROTO_LIST((void)); int print_version PROTO_LIST((void)); void sig_handler_quit PROTO_LIST((int sig)); void sig_handler_usr PROTO_LIST((int sig)); void pcap_cb PROTO_LIST((u_char * ptr, const struct pcap_pkthdr *hdr, const u_char *data)); int main PROTO_LIST((int argc, char **argv)); int packet_cnt = 0; // Packet counter used for connection pool cleaning int conn_freq = 100; // Number of packets after which a connection pool // cleaning is performed int conn_ttl = 100; // TTL of inactive connections in connection pool struct timeval last_packet_seen_time = // Timestamp of the last packet of the (struct timeval){0}; // last block of conn_freq packets seen logger_mod *logger = NULL; int err_exit(char *str, int num) { fprintf(stderr, "ERROR: %s\n", str); sig_handler_quit(SIGQUIT); exit(num); } int usage(void) { fprintf(stderr, "Usage: ssldump [-r dumpfile] [-i interface] [-l sslkeylogfile] [-w " "outpcapfile]\n"); fprintf(stderr, " [-k keyfile] [-p password] [-vtaTznsAxVNde]\n"); fprintf(stderr, " [filter]\n"); exit(0); } int print_version(void) { printf("Version: @ssldump_VERSION@ (@ssldump_DESCRIPTION@)\n"); printf( "Maintained by a bunch of volunteers, see " "https://github.com/adulau/ssldump/blob/master/CREDITS\n"); printf("Copyright (C) 2015-2023 the aforementioned volunteers\n"); printf("Copyright (C) 1998-2001 RTFM, Inc.\n"); printf("All rights reserved.\n"); #ifdef OPENSSL printf("Compiled with OpenSSL: decryption enabled\n"); #endif exit(0); } pcap_t *p; proto_mod *mod = &ssl_mod; n_handler *n; char *interface_name = 0; char *file = 0; char *filter = 0; void sig_handler_quit(int sig) { int freed_conn = 0; fflush(stdout); if(logger) logger->vtbl->deinit(); freed_conn = destroy_all_conn(); if(freed_conn && !(NET_print_flags & NET_PRINT_JSON)) fprintf(stderr, "Cleaned %d remaining connection(s) from connection pool\n", freed_conn); network_handler_destroy(mod, &n); if(p) pcap_close(p); if(interface_name) free(interface_name); if(filter) free(filter); if(file) free(file); exit(sig); } void sig_handler_usr(int sig) { int freed_conn = 0; if(sig == SIGUSR1) { if(!first_conn) { fprintf(stderr, "Received SIGUSR1, connection pool empty, nothing to list.\n"); } else { fprintf( stderr, "Received SIGUSR1, listing currently tracked connection(s) ...\n"); list_all_conn(); } } else if(sig == SIGUSR2) { if(!first_conn) { fprintf(stderr, "Received SIGUSR2, connection pool empty, nothing to purge.\n"); } else { fprintf(stderr, "Received SIGUSR2, purging connection pool ...\n"); freed_conn = destroy_all_conn(); if(freed_conn && !(NET_print_flags & NET_PRINT_JSON)) fprintf(stderr, "Purged %d connection(s) from connection pool\n", freed_conn); } } } void pcap_cb(u_char *ptr, const struct pcap_pkthdr *hdr, const u_char *data) { n_handler *n; int len; struct ether_header *e_hdr = (struct ether_header *)data; int type = ETHERTYPE_IP; int cleaned_conn; n = (n_handler *)ptr; if(hdr->caplen != hdr->len) err_exit("Length mismatch", -1); len = hdr->len; switch(pcap_if_type) { case DLT_RAW: switch(((u_int8_t)*data) >> 4) { case 4: type = ETHERTYPE_IP; break; case 6: type = ETHERTYPE_IPV6; break; default: fprintf(stderr, "Unknown packet type, skipping ...\n"); return; } break; #ifdef DLT_LOOP case DLT_LOOP: #endif case DLT_NULL: data += 4; len -= 4; break; case DLT_EN10MB: if(len < sizeof(struct ether_header)) { if(!(NET_print_flags & NET_PRINT_JSON)) fprintf(stderr, "Frame size too small to contain Ethernet header, skipping " "...\n"); return; } type = ntohs(e_hdr->ether_type); data += sizeof(struct ether_header); len -= sizeof(struct ether_header); /* if vlans, push past VLAN header (4 bytes) */ if(type == ETHERTYPE_8021Q) { type = ntohs(*(u_int16_t *)(data + 2)); data += 4; len += 4; } if(type != ETHERTYPE_IP && type != ETHERTYPE_IPV6) return; break; case DLT_IEEE802: data += 22; len -= 22; break; case DLT_FDDI: data += 21; len -= 21; break; #ifdef __amigaos__ case DLT_MIAMI: data += 16; len -= 16; break; #endif case DLT_SLIP: #ifdef DLT_SLIP_BSDOS case DLT_SLIP_BSDOS: #endif #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \ defined(__bsdi__) || defined(__APPLE__) data += 16; len -= 16; #else data += 24; len -= 24; #endif break; case DLT_PPP: #ifdef DLT_PPP_BSDOS case DLT_PPP_BSDOS: #endif #ifdef DLT_PPP_SERIAL case DLT_PPP_SERIAL: #endif #ifdef DLT_PPP_ETHER case DLT_PPP_ETHER: #endif #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \ defined(__bsdi__) || defined(__APPLE__) data += 4; len -= 4; #else #if defined(sun) || defined(__sun) data += 8; len -= 8; #else data += 24; len -= 24; #endif #endif break; #ifdef DLT_ENC case DLT_ENC: data += 12; len -= 12; break; #endif #ifdef DLT_LINUX_SLL case DLT_LINUX_SLL: data += 16; len -= 16; break; #endif #ifdef DLT_IPNET case DLT_IPNET: data += 24; len -= 24; break; #endif } if(type == ETHERTYPE_IPV6) network_process_packet(n, (struct timeval *)&hdr->ts, (u_char *)data, len, AF_INET6); else network_process_packet(n, (struct timeval *)&hdr->ts, (u_char *)data, len, AF_INET); if(packet_cnt == conn_freq) { packet_cnt = 0; memcpy(&last_packet_seen_time, &hdr->ts, sizeof(struct timeval)); if((cleaned_conn = clean_old_conn()) && !(NET_print_flags & NET_PRINT_JSON)) fprintf(stderr, "%d inactive connection(s) cleaned from connection pool\n", cleaned_conn); } else { packet_cnt++; } } typedef struct module_def_ { char *name; proto_mod *mod; } module_def; static module_def modules[] = {{"SSL", &ssl_mod}, {"NULL", &null_mod}, #ifdef ENABLE_RECORD {"RECORD", &record_mod}, #endif {0, 0}}; int parse_ssl_flag PROTO_LIST((int c)); int main(int argc, char **argv) { int r; #ifdef _WIN32 __declspec(dllimport) char *optarg; __declspec(dllimport) int optind; #else extern char *optarg; extern int optind; #endif pcap_if_t *interfaces; bpf_u_int32 localnet, netmask; int c; module_def *m = 0; int no_promiscuous = 0; int freed_conn = 0; char errbuf[PCAP_ERRBUF_SIZE]; signal(SIGINT, sig_handler_quit); signal(SIGUSR1, sig_handler_usr); signal(SIGUSR2, sig_handler_usr); while((c = getopt(argc, argv, "vr:F:f:S:jyTt:ai:k:l:w:p:znsAxXhHVNdqem:P")) != EOF) { switch(c) { case 'v': print_version(); break; case 'f': fprintf(stderr, "-f option replaced by -r. Use that in the future\n"); case 'r': file = strdup(optarg); break; case 'S': ssl_mod.vtbl->parse_flags(optarg); break; case 'y': NET_print_flags |= NET_PRINT_TYPESET; /*Kludge*/ SSL_print_flags |= SSL_PRINT_NROFF; break; case 'j': NET_print_flags |= NET_PRINT_JSON; SSL_print_flags |= SSL_PRINT_JSON; break; case 'z': NET_print_flags |= NET_PRINT_TS; break; case 'a': NET_print_flags |= NET_PRINT_ACKS; break; case 'A': SSL_print_flags |= SSL_PRINT_ALL_FIELDS; break; case 'T': NET_print_flags |= NET_PRINT_TCP_HDR; break; case 'i': interface_name = strdup(optarg); break; case 'k': SSL_keyfile = strdup(optarg); break; case 'l': SSL_keylogfile = strdup(optarg); break; case 'w': logger = &pcap_mod; if(logger->vtbl->init(optarg) != 0) { fprintf(stderr, "Can not open/create out pcap %s\n", optarg); exit(1); } break; case 'p': SSL_password = strdup(optarg); break; case 'P': ++no_promiscuous; break; case 'n': NET_print_flags |= NET_PRINT_NO_RESOLVE; break; case 't': conn_ttl = atoi(optarg); break; case 'F': conn_freq = atoi(optarg); break; case 'm': for(m = modules; m->name != 0; m++) { if(!strcmp(m->name, optarg)) { mod = m->mod; break; } } if(!m->name) { fprintf(stderr, "Request analysis module %s not found\n", optarg); exit(1); } break; case 'h': usage(); printf("Do 'man ssldump' for documentation\n"); exit(1); case '?': usage(); exit(1); /* must be an SSL flag. This is kind of a gross special case */ default: parse_ssl_flag(c); break; } } argv += optind; argc -= optind; if(!file) { if(!interface_name) { if(pcap_findalldevs(&interfaces, errbuf) == -1) { fprintf(stderr, "PCAP: %s\n", errbuf); err_exit("Aborting", -1); } interface_name = interfaces->name; if(!interface_name) { fprintf(stderr, "PCAP: %s\n", errbuf); err_exit("Aborting", -1); } } fprintf(stderr, "ssldump: listening on %s\n", interface_name); if(!(p = pcap_open_live(interface_name, 65535, !no_promiscuous, 1000, errbuf))) { fprintf(stderr, "PCAP: %s\n", errbuf); err_exit("Aborting", -1); } if(pcap_lookupnet(interface_name, &localnet, &netmask, errbuf) < 0) fprintf(stderr, "PCAP: %s\n", errbuf); } else { if(!(p = pcap_open_offline(file, errbuf))) { fprintf(stderr, "PCAP: %s\n", errbuf); err_exit("Aborting", -1); } netmask = 0; localnet = 0; } if(argc != 0) filter = collapse_args(argc, argv); if(filter) { struct bpf_program fp; /* (F5 patch) * reformat filter to include traffic with or without the 802.1q * vlan header. for example, "port 80" becomes: * "( port 80 ) or ( vlan and port 80 )". * note that if the filter includes the literals vlan, tagged, or * untagged, then it is assumed that the user knows what she is * doing, and the filter is not reformatted. */ if((pcap_datalink(p) == DLT_EN10MB) && (filter != NULL) && (strstr(filter, "vlan") == NULL)) { char *tmp_filter; char *fmt = "( (not ether proto 0x8100) and (%s) ) or ( vlan and (%s) )"; tmp_filter = (char *)malloc((strlen(filter) * 2) + strlen(fmt) + 1); if(tmp_filter == NULL) { fprintf(stderr, "PCAP: malloc failed\n"); err_exit("Aborting", -1); } sprintf(tmp_filter, fmt, filter, filter); free(filter); filter = tmp_filter; } if(pcap_compile(p, &fp, filter, 0, netmask) < 0) verr_exit("PCAP: %s\n", pcap_geterr(p)); if(pcap_setfilter(p, &fp) < 0) verr_exit("PCAP: %s\n", pcap_geterr(p)); } pcap_if_type = pcap_datalink(p); if(!(NET_print_flags & NET_PRINT_JSON)) if(NET_print_flags & NET_PRINT_TYPESET) printf("\n.nf\n.ps -2\n"); if((r = network_handler_create(mod, &n))) err_exit("Couldn't create network handler", r); pcap_loop(p, -1, pcap_cb, (u_char *)n); if(!(NET_print_flags & NET_PRINT_JSON)) if(NET_print_flags & NET_PRINT_TYPESET) printf("\n.ps\n.fi\n"); freed_conn = destroy_all_conn(); if(freed_conn && !(NET_print_flags & NET_PRINT_JSON)) fprintf(stderr, "Cleaned %d remaining connection(s) from connection pool\n", freed_conn); network_handler_destroy(mod, &n); pcap_close(p); free(n); if(filter) free(filter); if(file) free(file); if(interface_name) free(interface_name); if(SSL_keyfile) free(SSL_keyfile); if(SSL_keylogfile) free(SSL_keylogfile); if(SSL_password) free(SSL_password); if(logger) { logger->vtbl->deinit(); } exit(0); } char *collapse_args(int argc, char **argv) { int i, len = 0; char *ret; if(!argc) return 0; for(i = 0; i < argc; i++) { len += strlen(argv[i]) + 1; } if(!(ret = (char *)malloc(len))) err_exit("Out of memory", 1); len = 0; for(i = 0; i < argc; i++) { strcpy(ret + len, argv[i]); len += strlen(argv[i]); if(i != (argc - 1)) ret[len++] = ' '; } return ret; } ssldump-1.9/base/print_utils.c000066400000000000000000000050711470411077700165170ustar00rootroot00000000000000/** print_utils.c Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: print_utils.c,v 1.2 2000/10/17 16:09:58 ekr Exp $ ekr@rtfm.com Mon Feb 15 17:23:36 1999 */ int explain(char *format, ...) { va_list ap; va_start(ap, format); INDENT; vprintf(format, ap); va_end(ap); return 0; } int exdump(name, data) char *name; Data *data; { int i, j; char prefix[100]; INDENT; if(name) { sprintf(prefix, "%s[%d]=\n", name, data->len); printf("%s", prefix); INDENT_INCR; } for(i = 0; i < data->len; i++) { if(!i && (data->len > 8)) INDENT; if((data->len > 8) && i && !(i % 12)) { LF; INDENT; } printf("%.2x ", data->data[i] & 255); } if(name) INDENT_POP; if(data->len > 8 && i % 12) LF; return 0; } ssldump-1.9/base/print_utils.h000066400000000000000000000041441470411077700165240ustar00rootroot00000000000000/** print_utils.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: print_utils.h,v 1.2 2000/10/17 16:09:58 ekr Exp $ ekr@rtfm.com Mon Feb 15 17:23:56 1999 */ #ifndef _print_utils_h #define _print_utils_h int explain PROTO_LIST((char *format, ...)); int exdump PROTO_LIST((char *name, Data *data)); #endif ssldump-1.9/base/proto_mod.c000066400000000000000000000056111470411077700161450ustar00rootroot00000000000000/** proto_mod.c Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: proto_mod.c,v 1.3 2001/07/20 23:33:14 ekr Exp $ ekr@rtfm.com Thu Jan 7 22:35:23 1999 */ #include "network.h" int create_proto_handler(proto_mod *mod, proto_ctx *ctx, proto_handler **handlerp, tcp_conn *conn, struct timeval *first_packet) { int r, _status; proto_handler *handler = 0; if(!(handler = (proto_handler *)calloc(1, sizeof(proto_handler)))) ABORT(R_NO_MEMORY); handler->vtbl = mod->vtbl; if((r = mod->vtbl->create(mod->handle, ctx, conn, &handler->obj, &conn->i_addr, conn->i_port, &conn->r_addr, conn->r_port, first_packet))) ABORT(r); *handlerp = handler; _status = 0; abort: if(_status) { destroy_proto_handler(&handler); } return _status; } int destroy_proto_handler(proto_handler **handlerp) { if(!handlerp || !*handlerp) return 0; (*handlerp)->vtbl->destroy(&(*handlerp)->obj); free(*handlerp); *handlerp = 0; return 0; } ssldump-1.9/base/proto_mod.h000066400000000000000000000104701470411077700161510ustar00rootroot00000000000000/** proto_mod.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: proto_mod.h,v 1.4 2001/11/26 22:28:16 ekr Exp $ ekr@rtfm.com Thu Dec 24 21:10:05 1998 */ #ifndef _proto_mod_h #define _proto_mod_h typedef struct proto_obj_ proto_obj; typedef struct proto_ctx_ proto_ctx; #define DIR_I2R 1 #define DIR_R2I 2 struct proto_mod_vtbl_ { int(*parse_flags) PROTO_LIST((char *str)); int(*parse_flag) PROTO_LIST((int flag)); int(*create_ctx) PROTO_LIST((void *handle, proto_ctx **ctxp)); int(*create) PROTO_LIST((void *handle, proto_ctx *ctx, tcp_conn *conn, proto_obj **objp, struct sockaddr_storage *i_addr, u_short i_port, struct sockaddr_storage *r_addr, u_short r_port, struct timeval *time_base)); int(*destroy_ctx) PROTO_LIST((void *handle, proto_ctx **ctxp)); int(*destroy) PROTO_LIST((proto_obj * *objp)); int(*data) PROTO_LIST((proto_obj * obj, segment *data, int direction)); int(*close) PROTO_LIST((proto_obj * obj, packet *p, int direction)); }; struct proto_mod_ { void *handle; struct proto_mod_vtbl_ *vtbl; }; struct proto_handler_ { proto_obj *obj; struct proto_mod_vtbl_ *vtbl; }; int create_proto_handler PROTO_LIST((proto_mod * mod, proto_ctx *ctx, proto_handler **handlerp, tcp_conn *conn, struct timeval *first_packet)); int destroy_proto_handler PROTO_LIST((proto_handler * *handlerp)); // add logger struct logger_mod_vtbl_ { int(*init) PROTO_LIST((void *data)); // deinit must be async signal safe(!!!) int(*deinit) PROTO_LIST(()); int(*create) PROTO_LIST((proto_obj * *objp, struct sockaddr_storage *i_addr, u_short i_port, struct sockaddr_storage *r_addr, u_short r_port, struct timeval *time_base)); int(*destroy) PROTO_LIST((proto_obj * *objp)); int(*data) PROTO_LIST( (proto_obj * obj, unsigned char *data, unsigned int len, int direction)); int(*close) PROTO_LIST( (proto_obj * obj, unsigned char *data, unsigned int len, int direction)); }; struct logger_mod_ { char *name; struct logger_mod_vtbl_ *vtbl; }; typedef struct logger_mod_ logger_mod; extern logger_mod *logger; #endif ssldump-1.9/base/tcpconn.c000066400000000000000000000151611470411077700156100ustar00rootroot00000000000000/** tcpconn.c Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: tcpconn.c,v 1.7 2002/08/17 01:33:16 ekr Exp $ ekr@rtfm.com Tue Dec 29 15:13:03 1998 */ #include "network.h" #include "tcpconn.h" int conn_number = 1; conn_struct *first_conn = 0; char *state_map[] = { "UNKNOWN", "TCP_STATE_SYN1", "TCP_STATE_SYN2", "TCP_STATE_ACK", "TCP_STATE_ESTABLISHED", "TCP_STATE_FIN1", "TCP_STATE_CLOSED"}; extern struct timeval last_packet_seen_time; extern int conn_ttl; static int zero_conn PROTO_LIST((tcp_conn * conn)); static int zero_conn(tcp_conn *conn) { memset(conn, 0, sizeof(tcp_conn)); return 0; } int tcp_find_conn(tcp_conn **connp, int *directionp, struct sockaddr_storage *saddr, u_short sport, struct sockaddr_storage *daddr, u_short dport) { conn_struct *conn; for(conn = first_conn; conn; conn = conn->next) { if(sport == conn->conn.i_port && dport == conn->conn.r_port) { if(!memcmp(saddr, &conn->conn.i_addr, sizeof(struct sockaddr_storage)) && !memcmp(daddr, &conn->conn.r_addr, sizeof(struct sockaddr_storage))) { *directionp = DIR_I2R; *connp = &(conn->conn); return 0; } } if(dport == conn->conn.i_port && sport == conn->conn.r_port) { if(!memcmp(saddr, &conn->conn.r_addr, sizeof(struct sockaddr_storage)) && !memcmp(daddr, &conn->conn.i_addr, sizeof(struct sockaddr_storage))) { *directionp = DIR_R2I; *connp = &(conn->conn); return 0; } } } return R_NOT_FOUND; } int tcp_create_conn(tcp_conn **connp, struct sockaddr_storage *i_addr, u_short i_port, struct sockaddr_storage *r_addr, u_short r_port) { conn_struct *conn = 0; if(!(conn = (conn_struct *)malloc(sizeof(conn_struct)))) return R_NO_MEMORY; conn->prev = 0; zero_conn(&conn->conn); conn->conn.backptr = conn; conn->conn.conn_number = conn_number++; memcpy(&conn->conn.i_addr, i_addr, sizeof(struct sockaddr_storage)); conn->conn.i_port = i_port; memcpy(&conn->conn.r_addr, r_addr, sizeof(struct sockaddr_storage)); conn->conn.r_port = r_port; *connp = &(conn->conn); /* Insert at the head of the list */ conn->next = first_conn; if(first_conn) first_conn->prev = conn; first_conn = conn; return 0; } int tcp_destroy_conn(tcp_conn *conn) { conn_struct *c = conn->backptr; /* Detach from the list */ if(c->next) { c->next->prev = c->prev; } if(c->prev) { c->prev->next = c->next; } else { first_conn = c->next; } destroy_proto_handler(&conn->analyzer); free_tcp_segment_queue(conn->i2r.oo_queue); free_tcp_segment_queue(conn->r2i.oo_queue); free(conn->i_name); free(conn->r_name); free(conn->i_num); free(conn->r_num); zero_conn(conn); free(conn->backptr); free(conn); return 0; } int clean_old_conn(void) { conn_struct *conn; tcp_conn *tcpconn; struct timeval dt; int i = 0; if(!last_packet_seen_time.tv_sec) return 0; // Still processing first block of packets conn = first_conn; while(conn) { tcpconn = &conn->conn; conn = conn->next; if(timestamp_diff(&last_packet_seen_time, &tcpconn->last_seen_time, &dt)) continue; if(dt.tv_sec > conn_ttl) { i++; tcp_destroy_conn(tcpconn); } } return i; } void list_all_conn(void) { conn_struct *conn; tcp_conn *tcpconn; struct timeval dt; long freshness; fprintf(stderr, " -> " "\n"); conn = first_conn; while(conn) { tcpconn = &conn->conn; conn = conn->next; freshness = (timestamp_diff(&last_packet_seen_time, &tcpconn->last_seen_time, &dt)) ? 0 : dt.tv_sec; fprintf(stderr, "Connection #%d %s:%d -> %s:%d %s %ld\n", tcpconn->conn_number, tcpconn->i_name, tcpconn->i_port, tcpconn->r_name, tcpconn->r_port, state_map[tcpconn->state], freshness); } } int destroy_all_conn(void) { int i = 0; while(first_conn) { i++; tcp_destroy_conn(&first_conn->conn); } return i; } int free_tcp_segment_queue(segment *seg) { segment *tmp; while(seg) { tmp = seg->next; packet_destroy(seg->p); free(seg); seg = tmp; } return 0; } int copy_tcp_segment_queue(segment **out, segment *in) { int r, _status; segment *base = 0; for(; in; in = in->next) { if(!(*out = (segment *)calloc(1, sizeof(segment)))) ABORT(R_NO_MEMORY); if(!base) base = *out; if((r = packet_copy(in->p, &(*out)->p))) ABORT(r); out = &(*out)->next; /* Move the pointer we're assigning to */ } _status = 0; abort: if(_status) { free_tcp_segment_queue(base); } return _status; } ssldump-1.9/base/tcpconn.h000066400000000000000000000100271470411077700156110ustar00rootroot00000000000000/** tcpconn.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: tcpconn.h,v 1.4 2001/07/20 23:33:15 ekr Exp $ ekr@rtfm.com Tue Dec 29 13:00:52 1998 */ #ifndef _tcpconn_h #define _tcpconn_h typedef struct segment_ { u_char *data; u_int len; tcp_seq s_seq; packet *p; struct segment_ *next; } segment; typedef struct stream_data_ { tcp_seq seq; tcp_seq ack; short close; segment *oo_queue; } stream_data; extern char *state_map[]; typedef struct tcp_conn_ { int conn_number; int state; #define TCP_STATE_SYN1 1 #define TCP_STATE_SYN2 2 #define TCP_STATE_ACK 3 #define TCP_STATE_ESTABLISHED 4 #define TCP_STATE_FIN1 5 #define TCP_STATE_CLOSED 6 /*The address which sent the first SYN*/ struct sockaddr_storage i_addr; u_short i_port; char *i_name; char *i_num; /*The address which sent the second SYN*/ struct sockaddr_storage r_addr; u_short r_port; char *r_name; char *r_num; stream_data i2r; /*The stream from initiator to responder*/ stream_data r2i; /*The stream from responder to initiator*/ struct timeval start_time; struct timeval last_seen_time; proto_handler *analyzer; /*The analyzer to call with new data*/ struct conn_struct_ *backptr; } tcp_conn; typedef struct conn_struct_ { tcp_conn conn; struct conn_struct_ *next; struct conn_struct_ *prev; } conn_struct; int tcp_find_conn PROTO_LIST((tcp_conn * *connp, int *directionp, struct sockaddr_storage *src_addr, u_short src_port, struct sockaddr_storage *dst_addr, u_short dst_port)); int tcp_create_conn PROTO_LIST((tcp_conn * *connp, struct sockaddr_storage *initiator_addr, u_short initiator_port, struct sockaddr_storage *responder_addr, u_short responder_port)); int tcp_destroy_conn PROTO_LIST((tcp_conn * conn)); int free_tcp_segment_queue PROTO_LIST((segment * seg)); int copy_tcp_segment_queue PROTO_LIST((segment * *out, segment *in)); int clean_old_conn(void); void list_all_conn(void); int destroy_all_conn(void); extern conn_struct *first_conn; #endif ssldump-1.9/base/tcppack.c000066400000000000000000000326721470411077700155770ustar00rootroot00000000000000/** tcppack.c Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: tcppack.c,v 1.11 2002/09/09 21:02:58 ekr Exp $ ekr@rtfm.com Tue Dec 29 12:43:39 1998 */ #include "network.h" #ifndef _WIN32 #include #include #ifndef LINUX #include #else #define SEQ_LT(x, y) ((int)((x) - (y)) < 0) #endif #else #include #define SEQ_LT(x, y) ((int)((x) - (y)) < 0) #endif #include #include "debug.h" #include "tcpconn.h" #include "tcppack.h" static int process_data_segment PROTO_LIST((tcp_conn * conn, proto_mod *handler, packet *p, stream_data *stream, int direction)); static int new_connection PROTO_LIST( (proto_mod * handler, proto_ctx *ctx, packet *p, tcp_conn **connp)); static int print_tcp_packet PROTO_LIST((packet * p)); int STRIM PROTO_LIST((UINT4 _seq, segment *s)); int process_tcp_packet(proto_mod *handler, proto_ctx *ctx, packet *p) { int r, _status; int direction; stream_data *stream; tcp_conn *conn; if(p->len < 20) ABORT(1); p->tcp = (struct tcphdr *)p->data; print_tcp_packet(p); if((r = tcp_find_conn(&conn, &direction, &p->i_addr.so_st, ntohs(p->tcp->th_sport), &p->r_addr.so_st, ntohs(p->tcp->th_dport)))) { if(r != R_NOT_FOUND) ABORT(r); if((p->tcp->th_flags & TH_SYN) != TH_SYN) { DBG((0, "TCP: rejecting packet from unknown connection, seq: %u\n", ntohl(p->tcp->th_seq))); return 0; } if((r = new_connection(handler, ctx, p, &conn))) ABORT(r); return 0; } stream = direction == DIR_R2I ? &conn->r2i : &conn->i2r; memcpy(&conn->last_seen_time, &p->ts, sizeof(struct timeval)); switch(conn->state) { case TCP_STATE_SYN1: if(direction == DIR_R2I && (p->tcp->th_flags & TH_SYN)) { DBG((0, "SYN2 seq: %u", ntohl(p->tcp->th_seq))); conn->r2i.seq = ntohl(p->tcp->th_seq) + 1; conn->r2i.ack = ntohl(p->tcp->th_ack) + 1; conn->state = TCP_STATE_ACK; } break; case TCP_STATE_SYN2: if(direction == DIR_I2R && (p->tcp->th_flags & TH_SYN)) { DBG((0, "SYN1 seq: %u", ntohl(p->tcp->th_seq))); conn->i2r.seq = ntohl(p->tcp->th_seq) + 1; conn->i2r.ack = ntohl(p->tcp->th_ack) + 1; conn->state = TCP_STATE_ACK; } break; case TCP_STATE_ACK: { if(direction != DIR_I2R) break; DBG((0, "ACK seq: %u", ntohl(p->tcp->th_seq))); conn->i2r.ack = ntohl(p->tcp->th_ack) + 1; if(!(NET_print_flags & NET_PRINT_JSON)) { if(NET_print_flags & NET_PRINT_TYPESET) printf("\\fC"); printf("New TCP connection #%d: %s(%d) <-> %s(%d)\n", conn->conn_number, conn->i_name, conn->i_port, conn->r_name, conn->r_port); if(NET_print_flags & NET_PRINT_TYPESET) printf("\\fR"); } conn->state = TCP_STATE_ESTABLISHED; } case TCP_STATE_ESTABLISHED: case TCP_STATE_FIN1: { if(p->tcp->th_flags & TH_SYN) break; if((r = process_data_segment(conn, handler, p, stream, direction))) ABORT(r); } break; default: break; } if(conn->state == TCP_STATE_CLOSED) tcp_destroy_conn(conn); _status = 0; abort: return _status; } static int new_connection(proto_mod *handler, proto_ctx *ctx, packet *p, tcp_conn **connp) { int r, _status; tcp_conn *conn = 0; if((p->tcp->th_flags & (TH_SYN | TH_ACK)) == TH_SYN) { if((r = tcp_create_conn(&conn, &p->i_addr.so_st, ntohs(p->tcp->th_sport), &p->r_addr.so_st, ntohs(p->tcp->th_dport)))) ABORT(r); DBG((0, "SYN1 seq: %u", ntohl(p->tcp->th_seq))); conn->i2r.seq = ntohl(p->tcp->th_seq) + 1; conn->i2r.ack = ntohl(p->tcp->th_ack) + 1; conn->state = TCP_STATE_SYN1; } else { // SYN&ACK comes first somehow if((r = tcp_create_conn(&conn, &p->r_addr.so_st, ntohs(p->tcp->th_dport), &p->i_addr.so_st, ntohs(p->tcp->th_sport)))) ABORT(r); DBG((0, "SYN2 seq: %u", ntohl(p->tcp->th_seq))); conn->r2i.seq = ntohl(p->tcp->th_seq) + 1; conn->r2i.ack = ntohl(p->tcp->th_ack) + 1; conn->state = TCP_STATE_SYN2; } memcpy(&conn->start_time, &p->ts, sizeof(struct timeval)); memcpy(&conn->last_seen_time, &p->ts, sizeof(struct timeval)); lookuphostname(&conn->i_addr, &conn->i_name); lookuphostname(&conn->r_addr, &conn->r_name); addrtotext(&conn->i_addr, &conn->i_num); addrtotext(&conn->r_addr, &conn->r_num); if((r = create_proto_handler(handler, ctx, &conn->analyzer, conn, &p->ts))) ABORT(r); *connp = conn; _status = 0; abort: return _status; } /*#define STRIM(_seq,s) { \ int l;\ int off;\ l=(s)->s_seq - _seq; \ off=(s)->p->tcp->th_off*4; \ if(l>((s)->p->len-off)) ERETURN(R_BAD_DATA);\ (s)->data=(s)->p->data + off + (l) ; \ (s)->len=(s)->p->len - off + (l); \ (s)->s_seq += (l); \ if((s)->next) { \ if((s)->s_seq >= (s)->next->s_seq) {\ l=(s)->next->s_seq - (s)->s_seq; \ if((s)->len){\ (s)->len-=(l+1); \ (s)->s_seq-=(l+1);\ }\ }\ }\ } */ static int process_data_segment(tcp_conn *conn, proto_mod *handler, packet *p, stream_data *stream, int direction) { int r, _status; tcp_seq seq, right_edge; segment _seg; segment *seg, *nseg = 0; long l; l = p->len - p->tcp->th_off * 4; if(l < 0) { fprintf(stderr, "Malformed packet, computed TCP segment size is negative, skipping " "...\n"); return 0; } if(stream->close) { DBG((0, "Rejecting packet received after FIN: %u:%u(%u)", ntohl(p->tcp->th_seq), ntohl(p->tcp->th_seq + l), l)); return 0; } /*The idea here is to pass all available segments to the analyzer at once. Since we want to preserve the segment packet data, we pass the data as a linked list of segments*/ seq = ntohl(p->tcp->th_seq); /*Add ACK processing logic here */ if(p->tcp->th_flags & TH_ACK) { long acknum, acked; acknum = ntohl(p->tcp->th_ack); acked = acknum - stream->ack; if(acked && !l) { /* if((r=timestamp_diff(&p->ts,&conn->start_time,&dt))) ERETURN(r); printf("%d%c%4.4d ",dt.tv_sec,'.',dt.tv_usec/100); if(direction == DIR_R2I) printf("S>C "); else printf("C>S "); printf("ACK (%d)\n",acked); */ } stream->ack = acknum; } DBG((0, "Stream Seq %u ", stream->seq)); /* Check to see if this packet has been processed already */ right_edge = seq + (p->len - (p->tcp->th_off) * 4); if(!(p->tcp->th_flags & (TH_RST)) && SEQ_LT(right_edge, stream->seq)) return 0; if(SEQ_LT(stream->seq, seq)) { /* Out of order segment */ tcp_seq left_edge; for(seg = 0; seg; seg = seg ? seg->next : stream->oo_queue) { if(seg->next->s_seq > seq) break; } if(!(nseg = (segment *)calloc(1, sizeof(segment)))) ABORT(R_NO_MEMORY); if((r = packet_copy(p, &nseg->p))) ABORT(r); nseg->s_seq = seq; /*Insert this segment into the reassembly queue*/ if(seg) { nseg->next = seg->next; seg->next = nseg; } else { nseg->next = stream->oo_queue; stream->oo_queue = nseg; } left_edge = seg ? seg->s_seq : stream->seq; STRIM(left_edge, nseg); } else { /*First segment -- just thread the unallocated data on the list so we can pass to the analyzer*/ _seg.next = 0; _seg.p = p; _seg.s_seq = seq; /*Now split the queue. Assemble as many packets as possible and pass them to the analyzer. But process anything with a RST in it immediately and ignore any data that might be in it */ if(_seg.p->tcp->th_flags & (TH_RST)) { stream->close = _seg.p->tcp->th_flags & (TH_RST); seg = &_seg; conn->state = TCP_STATE_CLOSED; } else { STRIM(stream->seq, &_seg); if(_seg.p->tcp->th_flags & (TH_FIN)) { stream->close = _seg.p->tcp->th_flags & (TH_FIN); seg = &_seg; } else { for(seg = &_seg; seg->next; seg = seg->next) { if(seg->p->tcp->th_flags & (TH_FIN)) { stream->close = _seg.p->tcp->th_flags & (TH_FIN); break; } if(seg->len + seg->s_seq != seg->next->s_seq) break; } } /*Note that this logic is broken because it doesn't do the CLOSE_WAIT/FIN_WAIT stuff, but it's probably close enough, since this is a higher level protocol analyzer, not a TCP analyzer*/ if(seg->p->tcp->th_flags & (TH_FIN)) { if(conn->state == TCP_STATE_ESTABLISHED) conn->state = TCP_STATE_FIN1; else conn->state = TCP_STATE_CLOSED; } free_tcp_segment_queue(stream->oo_queue); stream->oo_queue = seg->next; seg->next = 0; stream->seq = seg->s_seq + seg->len; DBG((0, "Analyzing segment: %u:%u(%u)", seg->s_seq, seg->s_seq + seg->len, seg->len)); if((r = conn->analyzer->vtbl->data(conn->analyzer->obj, &_seg, direction))) { DBG((0, "ABORT due to segment: %u:%u(%u)", seg->s_seq, seg->s_seq + seg->len, seg->len)); ABORT(r); } } if(stream->close) { DBG((0, "Closing with segment: %u:%u(%u)", seg->s_seq, stream->seq, seg->len)); if((r = conn->analyzer->vtbl->close(conn->analyzer->obj, p, direction))) { DBG((0, "ABORT due to segment: %u:%u(%u)", seg->s_seq, stream->seq, seg->len)); ABORT(r); } } free_tcp_segment_queue(_seg.next); } _status = 0; abort: return _status; } static int print_tcp_packet(packet *p) { char *src = 0, *dst = 0; struct timeval *ts = &p->ts; if(!(NET_print_flags & NET_PRINT_TCP_HDR)) return 0; lookuphostname(&p->i_addr.so_st, &src); lookuphostname(&p->r_addr.so_st, &dst); if(!(NET_print_flags & NET_PRINT_JSON)) { if(NET_print_flags & NET_PRINT_TS) { printf("%lld%c%4.4lld ", (long long)ts->tv_sec, '.', (long long)ts->tv_usec / 100); } printf("TCP: %s(%d) -> %s(%d) ", src, ntohs(p->tcp->th_sport), dst, ntohs(p->tcp->th_dport)); printf("Seq %u.(%d) ", ntohl(p->tcp->th_seq), p->len - p->tcp->th_off * 4); if(p->tcp->th_flags & TH_ACK) printf("ACK %u ", ntohl(p->tcp->th_ack)); if(p->tcp->th_flags & TH_FIN) printf("FIN "); if(p->tcp->th_flags & TH_SYN) printf("SYN "); if(p->tcp->th_flags & TH_RST) printf("RST "); if(p->tcp->th_flags & TH_PUSH) printf("PUSH "); if(p->tcp->th_flags & TH_URG) printf("URG "); printf("\n"); } free(src); free(dst); return 0; } int STRIM(UINT4 _seq, segment *s) { int l; int off; /* Test: this shouldn't damage things at all s->p->data-=4; s->p->len+=4; s->s_seq-=4; */ l = _seq - (s)->s_seq; /* number of bytes to trim from the left of s */ off = (s)->p->tcp->th_off * 4; if(l > ((s)->p->len - off)) ERETURN(R_BAD_DATA); /* Now remove the leading l bytes */ (s)->data = (s)->p->data + off + (l); (s)->len = (s)->p->len - (off + l); (s)->s_seq += (l); /* Now trim to the right if necessary */ if((s)->next) { if((s)->s_seq >= (s)->next->s_seq) { l = (s)->s_seq - (s)->next->s_seq; if((s)->len) { (s)->len -= (l + 1); } } } return 0; } ssldump-1.9/base/tcppack.h000066400000000000000000000041071470411077700155740ustar00rootroot00000000000000/** tcppack.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: tcppack.h,v 1.3 2001/07/20 23:33:15 ekr Exp $ ekr@rtfm.com Wed Jan 6 15:08:30 1999 */ #ifndef _tcppack_h #define _tcppack_h int process_tcp_packet PROTO_LIST((proto_mod * mod, proto_ctx *ctx, packet *p)); #endif ssldump-1.9/build.sh000077500000000000000000000001051470411077700145140ustar00rootroot00000000000000#!/bin/sh rm -Rf build && cmake -B build -G Ninja && ninja -C build ssldump-1.9/cmake/000077500000000000000000000000001470411077700141425ustar00rootroot00000000000000ssldump-1.9/cmake/modules/000077500000000000000000000000001470411077700156125ustar00rootroot00000000000000ssldump-1.9/cmake/modules/FindJSONC.cmake000066400000000000000000000027071470411077700202770ustar00rootroot00000000000000# From https://github.com/fastogt/cmake/blob/master/FindJSON-C.cmake # Copyright (c) 2018, FastoGT # License: BSD 3-Clause # Modified by: Micah Snyder # JSONC_FOUND - true if library and headers were found # JSONC_INCLUDE_DIRS - include directories # JSONC_LIBRARIES - library directories if(JSONC_USE_STATIC) add_library(jsonc STATIC IMPORTED GLOBAL) else() add_library(jsonc SHARED IMPORTED GLOBAL) endif(JSONC_USE_STATIC) find_package(PkgConfig QUIET) PKG_CHECK_MODULES(PC_JSONC QUIET json-c) find_path(JSONC_INCLUDE_DIR json.h HINTS ${PC_JSONC_INCLUDEDIR} ${PC_JSONC_INCLUDE_DIRS} PATH_SUFFIXES json-c json) if(JSONC_USE_STATIC) find_library(JSONC_LIBRARY NAMES libjson-c.a libjson-c-static.a HINTS ${PC_JSONC_LIBDIR} ${PC_JSONC_LIBRARY_DIRS}) else() find_library(JSONC_LIBRARY NAMES json-c libjson-c HINTS ${PC_JSONC_LIBDIR} ${PC_JSONC_LIBRARY_DIRS}) endif(JSONC_USE_STATIC) set(JSONC_LIBRARIES ${JSONC_LIBRARY}) set(JSONC_INCLUDE_DIRS ${JSONC_INCLUDE_DIR}) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(JSONC DEFAULT_MSG JSONC_LIBRARIES JSONC_INCLUDE_DIRS) if(JSONC_FOUND AND NOT TARGET JSONC::jsonc) add_library(JSONC::jsonc UNKNOWN IMPORTED) set_target_properties(JSONC::jsonc PROPERTIES IMPORTED_LOCATION "${JSONC_LIBRARY}" INTERFACE_COMPILE_OPTIONS "${PC_JSONC_CFLAGS_OTHER}" INTERFACE_INCLUDE_DIRECTORIES "${JSONC_INCLUDE_DIRS}" ) endif() mark_as_advanced( JSONC_INCLUDE_DIR JSONC_LIBRARY ) ssldump-1.9/cmake/modules/FindLIBNET.cmake000066400000000000000000000074761470411077700204100ustar00rootroot00000000000000# Copyright 2013 Ettercap Development Team. # # Distributed under GPL license. # # Look for the header file find_path(LIBNET_INCLUDE_DIR NAMES libnet.h PATH_SUFFIXES libnet11 libnet-1.1) mark_as_advanced(LIBNET_INCLUDE_DIR) #Look for the library find_library(LIBNET_LIBRARY NAMES net libnet PATH_SUFFIXES libnet11 libnet-1.1) mark_as_advanced(LIBNET_LIBRARY) # Make sure we've got an include dir. if(NOT LIBNET_INCLUDE_DIR) if(LIBNET_FIND_REQUIRED AND NOT LIBNET_FIND_QUIETLY) message(FATAL_ERROR "Could not find LIBNET include directory.") endif() return() endif() if(NOT LIBNET_LIBRARY) if(LIBNET_FIND_REQUIRED AND NOT LIBNET_FIND_QUIETLY) message(FATAL_ERROR "Could not find LIBNET library.") endif() return() endif() #============================================================= # _LIBNET_GET_VERSION # Internal function to parse the version number in libnet.h # _OUT_version = The full version number # _OUT_version_major = The major version number only # _OUT_version_minor = The minor version number only # _libnet_hdr = Header file to parse #============================================================= function(_LIBNET_GET_VERSION _OUT_version _OUT_version_major _OUT_version_minor _libnet_hdr) file(READ ${_libnet_hdr} _contents) if(_contents) string(REGEX REPLACE ".*#define LIBNET_VERSION[ \t]+\"([0-9.a-zA-Z-]+)\".*" "\\1" ${_OUT_version} "${_contents}") if(NOT ${_OUT_version} MATCHES "[0-9.a-zA-Z-]+") message(FATAL_ERROR "Version parsing failed for LIBNET_VERSION!") endif() set(${_OUT_version} ${${_OUT_version}} PARENT_SCOPE) string(REGEX REPLACE "^([0-9]+)\\.[0-9]+.*" "\\1" ${_OUT_version_major} "${${_OUT_version}}") string(REGEX REPLACE "^[0-9]+\\.([0-9]+).*" "\\1" ${_OUT_version_minor} "${${_OUT_version}}") if(NOT ${_OUT_version_major} MATCHES "[0-9]+" OR NOT ${_OUT_version_minor} MATCHES "[0-9]+") message(FATAL_ERROR "Version parsing failed for detailed LIBNET_VERSION!: '${_OUT_version}' '${_OUT_version_major}' '${_OUT_version_minor}'") endif() set(${_OUT_version_major} ${${_OUT_version_major}} PARENT_SCOPE) set(${_OUT_version_minor} ${${_OUT_version_minor}} PARENT_SCOPE) else() message(FATAL_ERROR "Include file ${_libnet_hdr} does not exist") endif() endfunction() if(LIBNET_FIND_VERSION) set(LIBNET_FAILED_VERSION_CHECK true) _libnet_get_version(LIBNET_VERSION LIBNET_VERSION_MAJOR LIBNET_VERSION_MINOR ${LIBNET_INCLUDE_DIR}/libnet.h) if(LIBNET_FIND_VERSION_EXACT) if(LIBNET_VERSION VERSION_EQUAL LIBNET_FIND_VERSION) set(LIBNET_FAILED_VERSION_CHECK false) endif() else() if(LIBNET_VERSION VERSION_EQUAL LIBNET_FIND_VERSION OR LIBNET_VERSION VERSION_GREATER LIBNET_FIND_VERSION) set(LIBNET_FAILED_VERSION_CHECK false) endif() endif() if(LIBNET_FAILED_VERSION_CHECK) if(LIBNET_FIND_REQUIRED AND NOT LIBNET_FIND_QUIETLY) if(LIBNET_FIND_VERSION_EXACT) message(FATAL_ERROR "LIBNET version check failed. Version ${LIBNET_VERSION} was found, version ${LIBNET_FIND_VERSION} is needed exactly.") else() message(FATAL_ERROR "LIBNET version check failed. Version ${LIBNET_VERSION} was found, at least version ${LIBNET_FIND_VERSION} is required") endif() endif() # If the version check fails, exit out of the module here return() endif() endif() #handle the QUIETLY and REQUIRED arguments and set LIBNET_FOUND to TRUE if # all listed variables are TRUE include(FindPackageHandleStandardArgs) find_package_handle_standard_args(LIBNET DEFAULT_MSG LIBNET_LIBRARY LIBNET_INCLUDE_DIR) if(LIBNET_FOUND) set(LIBNET_LIBRARY ${LIBNET_LIBRARY}) set(LIBNET_INCLUDE_DIR ${LIBNET_INCLUDE_DIR}) set(LIBNET_VERSION ${LIBNET_VERSION}) set(LIBNET_VERSION_MAJOR ${LIBNET_VERSION_MAJOR}) set(LIBNET_VERSION_MINOR ${LIBNET_VERSION_MINOR}) endif() ssldump-1.9/cmake/modules/FindPCAP.cmake000066400000000000000000000052631470411077700201460ustar00rootroot00000000000000# - Try to find libpcap include dirs and libraries # # Usage of this module as follows: # # find_package(PCAP) # # Variables used by this module, they can change the default behaviour and need # to be set before calling find_package: # # PCAP_ROOT_DIR Set this variable to the root installation of # libpcap if the module has problems finding the # proper installation path. # # Variables defined by this module: # # PCAP_FOUND System has libpcap, include and library dirs found # PCAP_INCLUDE_DIR The libpcap include directories. # PCAP_LIBRARY The libpcap library (possibly includes a thread # library e.g. required by pf_ring's libpcap) # HAVE_PF_RING If a found version of libpcap supports PF_RING find_path(PCAP_ROOT_DIR NAMES include/pcap.h Include/pcap.h ) find_path(PCAP_INCLUDE_DIR NAMES pcap.h HINTS ${PCAP_ROOT_DIR}/include ) if ( MSVC AND COMPILER_ARCHITECTURE STREQUAL "x86_64" ) set(_pcap_lib_hint_path ${PCAP_ROOT_DIR}/lib/x64) else() set(_pcap_lib_hint_path ${PCAP_ROOT_DIR}/lib) endif() find_library(PCAP_LIBRARY NAMES pcap wpcap HINTS ${_pcap_lib_hint_path} ) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(PCAP DEFAULT_MSG PCAP_LIBRARY PCAP_INCLUDE_DIR ) include(CheckCSourceCompiles) set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARY}) check_c_source_compiles("int main() { return 0; }" PCAP_LINKS_SOLO) set(CMAKE_REQUIRED_LIBRARIES) # check if linking against libpcap also needs to link against a thread library if (NOT PCAP_LINKS_SOLO) find_package(Threads) if (THREADS_FOUND) set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) check_c_source_compiles("int main() { return 0; }" PCAP_NEEDS_THREADS) set(CMAKE_REQUIRED_LIBRARIES) endif () if (THREADS_FOUND AND PCAP_NEEDS_THREADS) set(_tmp ${PCAP_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) list(REMOVE_DUPLICATES _tmp) set(PCAP_LIBRARY ${_tmp} CACHE STRING "Libraries needed to link against libpcap" FORCE) else () message(FATAL_ERROR "Couldn't determine how to link against libpcap") endif () endif () string(FIND "${PCAP_LIBRARY}" "wpcap" _pcap_lib_is_wpcap) if ( _pcap_lib_is_wpcap GREATER_EQUAL 0 ) set(HAVE_WPCAP TRUE) endif() include(CheckFunctionExists) set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARY}) check_function_exists(pcap_get_pfring_id HAVE_PF_RING) check_function_exists(pcap_dump_open_append HAVE_PCAP_DUMP_OPEN_APPEND) set(CMAKE_REQUIRED_LIBRARIES) mark_as_advanced( PCAP_ROOT_DIR PCAP_INCLUDE_DIR PCAP_LIBRARY ) ssldump-1.9/common/000077500000000000000000000000001470411077700143525ustar00rootroot00000000000000ssldump-1.9/common/include/000077500000000000000000000000001470411077700157755ustar00rootroot00000000000000ssldump-1.9/common/include/r_assoc.h000066400000000000000000000064121470411077700176020ustar00rootroot00000000000000/** r_assoc.h Associative array code. This code has the advantage that different elements can have different create and destroy operators. Unfortunately, this can waste space. Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: r_assoc.h,v 1.3 2001/12/24 06:06:26 ekr Exp $ ekr@rtfm.com Sun Jan 17 17:57:18 1999 */ #ifndef _r_assoc_h #define _r_assoc_h typedef struct r_assoc_ r_assoc; int r_assoc_create PROTO_LIST((r_assoc * *assocp)); int r_assoc_insert PROTO_LIST((r_assoc * assoc, char *key, int len, void *value, int (*copy)(void **new, void *old), int (*destroy)(void *ptr), int how)); #define R_ASSOC_REPLACE 0x1 #define R_ASSOC_NEW 0x2 int r_assoc_fetch PROTO_LIST((r_assoc * assoc, char *key, int len, void **value)); int r_assoc_copy PROTO_LIST((r_assoc * *new, r_assoc *old)); int r_assoc_destroy PROTO_LIST((r_assoc * *assocp)); /*We need iterators, but I haven't written them yet*/ typedef struct r_assoc_iterator_ { r_assoc *assoc; int prev_chain; struct r_assoc_el_ *prev; int next_chain; struct r_assoc_el_ *next; } r_assoc_iterator; int r_assoc_init_iter PROTO_LIST((r_assoc * assoc, r_assoc_iterator *)); int r_assoc_iter PROTO_LIST((r_assoc_iterator * iter, void **key, int *keyl, void **val)); int r_assoc_iter_delete PROTO_LIST((r_assoc_iterator *)); #endif ssldump-1.9/common/include/r_bitfield.h000066400000000000000000000007701470411077700202550ustar00rootroot00000000000000/** r_bitfield.h Copyright (C) 2001 RTFM, Inc. All Rights Reserved. ekr@rtfm.com Wed Oct 3 10:43:50 2001 */ #ifndef _r_bitfield_h #define _r_bitfield_h typedef struct r_bitfield_ { UINT4 *data; UINT4 len; UINT4 base; } r_bitfield; int r_bitfield_set PROTO_LIST((r_bitfield *, int bit)); int r_bitfield_isset PROTO_LIST((r_bitfield *, int bit)); int r_bitfield_create PROTO_LIST((r_bitfield * *setp, UINT4 size)); int r_bitfield_destroy PROTO_LIST((r_bitfield * *setp)); #endif ssldump-1.9/common/include/r_common.h000066400000000000000000000045431470411077700177650ustar00rootroot00000000000000/** r_common.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: r_common.h,v 1.2 2000/10/17 16:09:59 ekr Exp $ ekr@rtfm.com Tue Dec 22 10:40:07 1998 */ #ifndef _r_common_h #define _r_common_h #ifdef HAVE_CONFIG_H #include #endif #include "r_defaults.h" #include "r_includes.h" #include "r_types.h" #include "r_macros.h" #include "r_errors.h" #include "r_data.h" /*AAH*/ int xdump PROTO_LIST((char *label, UCHAR *data, int len)); /* defines for possibly replaced functions */ #ifndef HAVE_STRDUP char *strdup PROTO_LIST((char *in)); #endif #endif ssldump-1.9/common/include/r_data.h000066400000000000000000000051511470411077700174020ustar00rootroot00000000000000/** r_data.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: r_data.h,v 1.2 2000/10/17 16:09:59 ekr Exp $ ekr@rtfm.com Wed Feb 10 14:18:19 1999 */ #ifndef _r_data_h #define _r_data_h typedef struct Data_ { UCHAR *data; int len; } Data; int r_data_create PROTO_LIST((Data * *dp, UCHAR *d, int l)); int r_data_alloc PROTO_LIST((Data * *dp, int l)); int r_data_make PROTO_LIST((Data * dp, UCHAR *d, int l)); int r_data_destroy PROTO_LIST((Data * *dp)); int r_data_copy PROTO_LIST((Data * dst, Data *src)); int r_data_zfree PROTO_LIST((Data * d)); int r_data_compare PROTO_LIST((Data * d1, Data *d2)); #define INIT_DATA(a, b, c) \ (a).data = b; \ (a).len = c #define ATTACH_DATA(a, b) \ (a).data = b; \ (a).len = sizeof(b) #define ZERO_DATA(a) \ (a).data = 0; \ (a).len = 0 #endif ssldump-1.9/common/include/r_defaults.h000066400000000000000000000041771470411077700203070ustar00rootroot00000000000000/** r_defaults.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: r_defaults.h,v 1.2 2000/10/17 16:09:59 ekr Exp $ ekr@rtfm.com Tue Dec 22 10:39:14 1998 */ #ifndef _r_defaults_h #define _r_defaults_h #ifndef R_USE_PROTOTYPES #define R_USE_PROTOTYPES 1 #endif /*The needs defines don't belong here*/ #define R_NEEDS_STDLIB_H #endif ssldump-1.9/common/include/r_errors.h000066400000000000000000000046051470411077700200100ustar00rootroot00000000000000/** r_errors.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: r_errors.h,v 1.3 2002/01/21 17:36:51 ekr Exp $ ekr@rtfm.com Tue Dec 22 10:59:49 1998 */ #ifndef _r_errors_h #define _r_errors_h #define R_NO_MEMORY 1 /*out of memory*/ #define R_NOT_FOUND 2 /*Item not found*/ #define R_INTERNAL 3 /*Unspecified internal error*/ #define R_ALREADY 4 /*Action already done*/ #define R_EOD 5 /*end of data*/ #define R_BAD_ARGS 6 /*Bad arguments*/ #define R_BAD_DATA 7 /*Bad data*/ #define R_WOULDBLOCK 8 /*Operation would block */ int verr_exit PROTO_LIST((char *fmt, ...)); #endif ssldump-1.9/common/include/r_includes.h000066400000000000000000000042211470411077700202740ustar00rootroot00000000000000/** r_includes.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: r_includes.h,v 1.2 2000/10/17 16:09:59 ekr Exp $ ekr@rtfm.com Tue Dec 22 11:38:50 1998 */ #ifndef _r_includes_h #define _r_includes_h #ifdef R_NEEDS_STDLIB_H #include #endif #ifdef R_NEEDS_MEMORY_H #include #endif #include #include #endif ssldump-1.9/common/include/r_list.h000066400000000000000000000055051470411077700174470ustar00rootroot00000000000000/** r_list.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: r_list.h,v 1.2 2000/10/17 16:09:59 ekr Exp $ ekr@rtfm.com Tue Jan 19 08:36:48 1999 */ #ifndef _r_list_h #define _r_list_h typedef struct r_list_ r_list; typedef struct r_list_iterator_ { r_list *list; struct r_list_el_ *ptr; } r_list_iterator; int r_list_create PROTO_LIST((r_list * *listp)); int r_list_destroy PROTO_LIST((r_list * *listp)); int r_list_copy PROTO_LIST((r_list * *out, r_list *in)); int r_list_insert PROTO_LIST((r_list * list, void *value, int (*copy)(void **new, void *old), int (*destroy)(void **ptr))); int r_list_append PROTO_LIST((r_list * list, void *value, int (*copy)(void **new, void *old), int (*destroy)(void **ptr))); int r_list_init_iter PROTO_LIST((r_list * list, r_list_iterator *iter)); int r_list_iter PROTO_LIST((r_list_iterator * iter, void **val)); #endif ssldump-1.9/common/include/r_macros.h000066400000000000000000000077341470411077700177660ustar00rootroot00000000000000/** r_macros.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: r_macros.h,v 1.4 2001/11/20 17:45:18 ekr Exp $ ekr@rtfm.com Tue Dec 22 10:37:32 1998 */ #ifndef _r_macros_h #define _r_macros_h #if(R_USE_PROTOTYPES == 1) #define PROTO_LIST(a) a #else #define PROTO_LIST(a) () #endif #ifndef __GNUC__ #define __FUNCTION__ "unknown" #endif #ifdef R_TRACE_ERRORS #define REPORT_ERROR_(caller, a) \ fprintf(stderr, "%s: error %d at %s:%d (function %s)\n", caller, a, \ __FILE__, __LINE__, __FUNCTION__) #else #define REPORT_ERROR_(caller, a) #endif #ifndef ERETURN #define ERETURN(a) \ do { \ int _r = a; \ if(!_r) \ _r = -1; \ REPORT_ERROR_("ERETURN", _r); \ return _r; \ } while(0) #endif #ifndef ABORT #define ABORT(a) \ do { \ int _r = a; \ if(!_r) \ _r = -1; \ REPORT_ERROR_("ABORT", _r); \ _status = _r; \ goto abort; \ } while(0) #endif #ifndef FREE #define FREE(a) \ if(a) \ free(a) #endif #ifndef MIN #define MIN(a, b) (((a) > (b)) ? (b) : (a)) #endif #ifndef MAX #define MAX(a, b) (((b) > (a)) ? (b) : (a)) #endif #ifdef DEBUG #define DBG(a) debug a int debug(int class, char *format, ...); #else #define DBG(a) #endif #ifndef RMALLOC #define RMALLOC(a) malloc(a) #endif #ifndef RCALLOC #define RCALLOC(a) calloc(1, a) #endif #ifndef RFREE #define RFREE(a) \ if(a) \ free(a) #endif #ifndef RREALLOC #define RREALLOC(a, b) realloc(a, b) #endif #define UNIMPLEMENTED \ do { \ fprintf(stderr, "Function %s unimplemented\n", __FUNCTION__); \ abort(); \ } while(0) #ifdef STDC_HEADERS #include #endif #ifndef STRNICMP #ifdef _WIN32 #define STRNICMP(a, b, n) strnicmp(a, b, n) #else #define STRNICMP(a, b, n) strncasecmp(a, b, n) #endif #endif #endif ssldump-1.9/common/include/r_thread.h000066400000000000000000000050311470411077700177350ustar00rootroot00000000000000/** r_thread.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: r_thread.h,v 1.2 2000/10/17 16:09:59 ekr Exp $ ekr@rtfm.com Tue Feb 23 14:58:36 1999 */ #ifndef _r_thread_h #define _r_thread_h typedef void *r_thread; typedef void *r_rwlock; int r_thread_fork PROTO_LIST((void (*func)(void *), void *arg, r_thread *tid)); int r_thread_destroy PROTO_LIST((r_thread tid)); int r_thread_yield PROTO_LIST((void)); int r_thread_exit PROTO_LIST((void)); int r_thread_wait_last PROTO_LIST((void)); int r_rwlock_create PROTO_LIST((r_rwlock * *lockp)); int r_rwlock_destroy PROTO_LIST((r_rwlock * *lock)); int r_rwlock_lock PROTO_LIST((r_rwlock * lock, int action)); #define R_RWLOCK_UNLOCK 0 #define R_RWLOCK_RLOCK 1 #define R_RWLOCK_WLOCK 2 #endif ssldump-1.9/common/include/r_time.h000066400000000000000000000052451470411077700174330ustar00rootroot00000000000000/** r_time.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: r_time.h,v 1.4 2001/12/24 06:06:26 ekr Exp $ ekr@rtfm.com Thu Mar 4 08:45:41 1999 */ #ifndef _r_time_h #define _r_time_h #ifdef HAVE_CONFIG_H #include #endif #ifdef _WIN32 #include #else /* Cribbed from the autoconf doc */ #if TIME_WITH_SYS_TIME #include #include #else #if HAVE_SYS_TIME_H #include #else #include #endif #endif #endif int r_timeval_diff PROTO_LIST((struct timeval * t1, struct timeval *t0, struct timeval *diff)); int r_timeval_add PROTO_LIST((struct timeval * t1, struct timeval *t2, struct timeval *sum)); UINT8 r_timeval2int PROTO_LIST((struct timeval * tv)); UINT8 r_gettimeint PROTO_LIST((void)); #endif ssldump-1.9/common/include/r_types.h000066400000000000000000000055761470411077700176500ustar00rootroot00000000000000/** r_types.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: r_types.h,v 1.3 2002/09/09 21:02:58 ekr Exp $ ekr@rtfm.com Tue Dec 22 10:36:02 1998 */ #ifndef _r_types_h #define _r_types_h #ifdef HAVE_CONFIG_H #include #endif #ifndef R_DEFINED_UINT4 #ifndef SIZEOF_UNSIGNED_INT typedef unsigned int UINT4; #else #if(SIZEOF_UNSIGNED_INT == 4) typedef unsigned int UINT4; #elif(SIZEOF_UNSIGNED_SHORT == 4) typedef unsigned short UINT4; #elif(SIZEOF_UNSIGNED_LONG == 4) typedef unsigned long UINT4; #else #error no type for UINT4 #endif #endif #endif #ifndef R_DEFINED_UINT8 #ifndef SIZEOF_UNSIGNED_LONG typedef unsigned long UINT8; #else #if(SIZEOF_UNSIGNED_INT == 8) typedef unsigned int UINT8; #elif(SIZEOF_UNSIGNED_SHORT == 8) typedef unsigned short UINT8; #elif(SIZEOF_UNSIGNED_LONG == 8) typedef unsigned long UINT8; #elif(SIZEOF_UNSIGNED_LONG_LONG == 8) typedef unsigned long long UINT8; #elif defined(_WIN32) && defined(_MSC_VER) typedef unsigned __int64 UINT8; #else #error no type for UINT8 #endif #endif #endif #ifndef R_DEFINED_UCHAR typedef unsigned char UCHAR; #endif #endif ssldump-1.9/common/lib/000077500000000000000000000000001470411077700151205ustar00rootroot00000000000000ssldump-1.9/common/lib/assoc.h000066400000000000000000000040131470411077700163770ustar00rootroot00000000000000/** assoc.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: assoc.h,v 1.2 2000/10/17 16:10:00 ekr Exp $ ekr@rtfm.com Sun Jan 17 17:56:35 1999 */ #ifndef _assoc_h #define _assoc_h typedef struct assoc_ assoc; #endif ssldump-1.9/common/lib/debug.c000066400000000000000000000047321470411077700163600ustar00rootroot00000000000000/** debug.c Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: debug.c,v 1.3 2001/12/24 06:06:26 ekr Exp $ ekr@rtfm.com Wed Jan 6 17:08:58 1999 */ #include #include #include "r_common.h" #include "debug.h" int debug(int class, char *format, ...) { va_list ap; va_start(ap, format); vfprintf(stderr, format, ap); fprintf(stderr, "\n"); va_end(ap); return 0; } int xdump(char *name, UCHAR *data, int len) { int i; if(name) { printf("%s[%d]=\n", name, len); } for(i = 0; i < len; i++) { if((len > 8) && i && !(i % 12)) { printf("\n"); } printf("%.2x ", data[i] & 255); } if(i % 12) printf("\n"); return 0; } ssldump-1.9/common/lib/debug.h000066400000000000000000000042221470411077700163570ustar00rootroot00000000000000/** debug.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: debug.h,v 1.3 2001/12/24 06:06:26 ekr Exp $ ekr@rtfm.com Wed Jan 6 17:13:00 1999 */ #ifndef _debug_h #define _debug_h #ifdef DEBUG #define DBG(a) debug a #else #define DBG(a) #endif int debug(int class, char *format, ...); int xdump PROTO_LIST((char *name, UCHAR *data, int len)); #endif ssldump-1.9/common/lib/r_assoc.c000066400000000000000000000224241470411077700167210ustar00rootroot00000000000000/** r_assoc.c This is an associative array implementation, using an open-chained hash bucket technique. Note that this implementation permits each data entry to have separate copy constructors and destructors. This currently wastes space, but could be implemented while saving space by using the high order bit of the length value or somesuch. The major problem with this code is it's not resizable, though it could be made so. Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: r_assoc.c,v 1.4 2001/12/24 06:06:26 ekr Exp $ ekr@rtfm.com Sun Jan 17 17:57:15 1999 */ #include #include "r_assoc.h" typedef struct r_assoc_el_ { char *key; int key_len; void *data; struct r_assoc_el_ *prev; struct r_assoc_el_ *next; int(*copy) PROTO_LIST((void **new, void *old)); int(*destroy) PROTO_LIST((void *ptr)); } r_assoc_el; struct r_assoc_ { int size; int bits; r_assoc_el **chains; }; #define DEFAULT_TABLE_BITS 5 static int destroy_assoc_chain PROTO_LIST((r_assoc_el * chain)); static int r_assoc_fetch_bucket PROTO_LIST((r_assoc * assoc, char *key, int len, r_assoc_el **bucketp)); UINT4 hash_compute PROTO_LIST((char *key, int len, int size)); static int copy_assoc_chain PROTO_LIST((r_assoc_el * *newp, r_assoc_el *old)); int r_assoc_create(r_assoc **assocp) { r_assoc *assoc = 0; int _status; if(!(assoc = (r_assoc *)calloc(sizeof(r_assoc), 1))) ABORT(R_NO_MEMORY); assoc->size = (1 << DEFAULT_TABLE_BITS); assoc->bits = DEFAULT_TABLE_BITS; if(!(assoc->chains = (r_assoc_el **)calloc(sizeof(r_assoc_el *), assoc->size))) ABORT(R_NO_MEMORY); *assocp = assoc; _status = 0; abort: if(_status) { r_assoc_destroy(&assoc); } return _status; } int r_assoc_destroy(r_assoc **assocp) { r_assoc *assoc; int i; if(!assocp || !*assocp) return 0; assoc = *assocp; for(i = 0; i < assoc->size; i++) destroy_assoc_chain(assoc->chains[i]); free(assoc->chains); free(assoc); return 0; } static int destroy_assoc_chain(r_assoc_el *chain) { r_assoc_el *nxt; while(chain) { nxt = chain->next; if(chain->destroy) chain->destroy(chain->data); free(chain->key); free(chain); chain = nxt; } return 0; } static int copy_assoc_chain(r_assoc_el **newp, r_assoc_el *old) { r_assoc_el *new = 0, *ptr, *tmp; int r, _status; if(!old) { *newp = 0; return 0; } for(; old; old = old->next) { if(!(tmp = (r_assoc_el *)calloc(sizeof(r_assoc_el), 1))) ABORT(R_NO_MEMORY); if(!new) { new = tmp; ptr = new; } else { ptr->next = tmp; tmp->prev = ptr; ptr = tmp; } ptr->destroy = old->destroy; ptr->copy = old->copy; if(old->copy) { if((r = old->copy(&ptr->data, old->data))) ABORT(r); } else ptr->data = old->data; if(!(ptr->key = (char *)malloc(old->key_len))) ABORT(R_NO_MEMORY); memcpy(ptr->key, old->key, ptr->key_len = old->key_len); } *newp = new; _status = 0; abort: if(_status) { destroy_assoc_chain(new); } return _status; } static int r_assoc_fetch_bucket(r_assoc *assoc, char *key, int len, r_assoc_el **bucketp) { UINT4 hash_value; r_assoc_el *bucket; hash_value = hash_compute(key, len, assoc->bits); for(bucket = assoc->chains[hash_value]; bucket; bucket = bucket->next) { if(bucket->key_len == len && !memcmp(bucket->key, key, len)) { *bucketp = bucket; return 0; } } return R_NOT_FOUND; } int r_assoc_fetch(r_assoc *assoc, char *key, int len, void **datap) { r_assoc_el *bucket; int r; if((r = r_assoc_fetch_bucket(assoc, key, len, &bucket))) { if(r != R_NOT_FOUND) ERETURN(r); return r; } *datap = bucket->data; return 0; } int r_assoc_insert(r_assoc *assoc, char *key, int len, void *data, int(*copy) PROTO_LIST((void **new, void *old)), int(*destroy) PROTO_LIST((void *ptr)), int how) { r_assoc_el *bucket, *new_bucket = 0; int r, _status; if((r = r_assoc_fetch_bucket(assoc, key, len, &bucket))) { /*Note that we compute the hash value twice*/ UINT4 hash_value; if(r != R_NOT_FOUND) ABORT(r); hash_value = hash_compute(key, len, assoc->bits); if(!(new_bucket = (r_assoc_el *)calloc(sizeof(r_assoc_el), 1))) ABORT(R_NO_MEMORY); if(!(new_bucket->key = (char *)malloc(len))) ABORT(R_NO_MEMORY); memcpy(new_bucket->key, key, len); new_bucket->key_len = len; /*Insert at the list head. Is FIFO a good algorithm?*/ if(assoc->chains[hash_value]) assoc->chains[hash_value]->prev = new_bucket; new_bucket->next = assoc->chains[hash_value]; assoc->chains[hash_value] = new_bucket; bucket = new_bucket; } else { if(!(how & R_ASSOC_REPLACE)) ABORT(R_ALREADY); if(bucket->destroy) bucket->destroy(bucket->data); } bucket->data = data; bucket->copy = copy; bucket->destroy = destroy; _status = 0; abort: if(_status && new_bucket) { free(new_bucket->key); free(new_bucket); } return _status; } int r_assoc_copy(r_assoc **newp, r_assoc *old) { int r, _status, i; r_assoc *new; if(!(new = (r_assoc *)calloc(sizeof(r_assoc), 1))) ABORT(R_NO_MEMORY); new->size = old->size; new->bits = old->bits; if(!(new->chains = (r_assoc_el **)calloc(sizeof(r_assoc_el), old->size))) ABORT(R_NO_MEMORY); for(i = 0; i < new->size; i++) { if((r = copy_assoc_chain(new->chains + i, old->chains[i]))) ABORT(R_NO_MEMORY); } *newp = new; _status = 0; abort: if(_status) { r_assoc_destroy(&new); } return _status; } int r_assoc_init_iter(r_assoc *assoc, r_assoc_iterator *iter) { int i; iter->assoc = assoc; iter->prev_chain = -1; iter->prev = 0; iter->next_chain = assoc->size; iter->next = 0; for(i = 0; i < assoc->size; i++) { if(assoc->chains[i] != 0) { iter->next_chain = i; iter->next = assoc->chains[i]; break; } } return 0; } int r_assoc_iter(r_assoc_iterator *iter, void **key, int *keyl, void **val) { int i; r_assoc_el *ret; if(!iter->next) return R_EOD; ret = iter->next; *key = ret->key; *keyl = ret->key_len; *val = ret->data; /* Now increment */ iter->prev_chain = iter->next_chain; iter->prev = iter->next; /* More on this chain */ if(iter->next->next) { iter->next = iter->next->next; } else { iter->next = 0; /* FInd the next occupied chain*/ for(i = iter->next_chain; i < iter->assoc->size; i++) { if(iter->assoc->chains[i]) { iter->next_chain = i; iter->next = iter->assoc->chains[i]; break; } } } return 0; } /* Delete the last returned value*/ int r_assoc_iter_delete(r_assoc_iterator *iter) { /* First unhook it from the list*/ if(!iter->prev->prev) { /* First element*/ iter->assoc->chains[iter->prev_chain] = iter->prev->next; } else { iter->prev->prev->next = iter->prev->next; } if(iter->prev->next) { iter->prev->next->prev = iter->prev->prev; } iter->prev->destroy(iter->prev->data); free(iter->prev->data); free(iter->prev); return 0; } /*This is a hack from AMS. Supposedly, it's pretty good for strings, even though it doesn't take into account all the data*/ UINT4 hash_compute(char *key, int len, int bits) { UINT4 h = 0; h = key[0] + (key[len - 1] * len); h &= (1 << bits) - 1; return h; } ssldump-1.9/common/lib/r_assoc_test.c000066400000000000000000000066431470411077700177650ustar00rootroot00000000000000/** r_assoc_test.c Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: r_assoc_test.c,v 1.2 2000/10/17 16:10:00 ekr Exp $ ekr@rtfm.com Sun Jan 17 21:09:22 1999 */ #include #include int main(void) { char test_vector[1024], *v; int rnd, ct, r; r_assoc *assoc, *new_assoc; if(r = r_assoc_create(&assoc)) { fprintf(stderr, "Couldn't create\n"); exit(1); } srand(getpid()); v = test_vector; for(ct = 0; ct < 256; ct++) { v[0] = ct & 255; v[1] = (ct >> 8) & 255; v[2] = (ct >> 16) & 255; v[3] = (ct >> 24) & 255; if(r = r_assoc_insert(assoc, v, 4, v, 0, 0, R_ASSOC_REPLACE)) { fprintf(stderr, "Couldn't insert %d\n", ct); exit(1); } v += 4; } fetch_test(assoc); if(r = r_assoc_copy(&new_assoc, assoc)) { fprintf(stderr, "Couldn't copy\n"); exit(1); } r_assoc_destroy(&assoc); fetch_test(new_assoc); r_assoc_destroy(&new_assoc); printf("Tests pass\n"); exit(0); } int fetch_test(r_assoc *assoc) { int ct; char vec[4], *v; int r, _status, rnd; for(ct = 0; ct < 65537; ct++) { rnd = rand(); rnd &= 0x3ff; vec[0] = rnd & 255; vec[1] = (rnd >> 8) & 255; vec[2] = (rnd >> 16) & 255; vec[3] = (rnd >> 24) & 255; if(r = r_assoc_fetch(assoc, vec, 4, (void **)&v)) { if(rnd < 256) { fprintf(stderr, "Couldn't fetch\n"); exit(1); } else continue; } else { if(rnd > 255) { fprintf(stderr, "Spurious fetch\n"); exit(1); } } if(memcmp(vec, v, 4)) { fprintf(stderr, "Fetch error\n"); exit(1); } } return 0; } ssldump-1.9/common/lib/r_bitfield.c000066400000000000000000000032151470411077700173700ustar00rootroot00000000000000/** r_bitfield.c Copyright (C) 2001 RTFM, Inc. All Rights Reserved. ekr@rtfm.com Wed Oct 3 11:15:23 2001 */ #include #include "r_bitfield.h" int r_bitfield_create(r_bitfield **setp, UINT4 size) { r_bitfield *set = 0; int _status; int num_words = size / 32 + !!(size % 32); if(!(set = (r_bitfield *)RMALLOC(sizeof(r_bitfield)))) ABORT(R_NO_MEMORY); if(!(set->data = (UINT4 *)RMALLOC(num_words * 4))) ABORT(R_NO_MEMORY); memset(set->data, 0, 4 * num_words); set->base = 0; set->len = num_words; *setp = set; _status = 0; abort: if(_status) { r_bitfield_destroy(&set); } return _status; } int r_bitfield_destroy(r_bitfield **setp) { r_bitfield *set; if(!setp || !*setp) return 0; set = *setp; RFREE(set->data); RFREE(set); *setp = 0; return 0; } int r_bitfield_set(r_bitfield *set, int bit) { int word = (bit - set->base) / 32; int bbit = (bit - set->base) % 32; int _status; /* Resize? */ if(word > set->len) { UINT4 newlen = set->len; UINT4 *tmp; while(newlen < word) newlen *= 2; if(!(tmp = (UINT4 *)RMALLOC(newlen))) ABORT(R_NO_MEMORY); memcpy(tmp, set->data, set->len * 4); memset(tmp + set->len * 4, 0, (newlen - set->len) * 4); RFREE(set->data); set->data = tmp; } set->data[word] |= 1 << bbit; _status = 0; abort: return _status; } int r_bitfield_isset(r_bitfield *set, int bit) { int word = (bit - set->base) / 32; int bbit = (bit - set->base) % 32; int _status; if(bit < set->base) return 0; /* Resize? */ if(word > set->len) return 0; return set->data[word] & (1 << bbit); } ssldump-1.9/common/lib/r_data.c000066400000000000000000000066621470411077700165300ustar00rootroot00000000000000/** r_data.c Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: r_data.c,v 1.3 2001/07/20 23:33:15 ekr Exp $ ekr@rtfm.com Tue Aug 17 15:39:50 1999 */ #include #include int r_data_create(Data **dp, UCHAR *d, int l) { Data *d_ = 0; int _status; if(!(d_ = (Data *)calloc(sizeof(Data), 1))) ABORT(R_NO_MEMORY); if(!(d_->data = (UCHAR *)malloc(l))) ABORT(R_NO_MEMORY); memcpy(d_->data, d, l); d_->len = l; *dp = d_; _status = 0; abort: if(_status) r_data_destroy(&d_); return _status; } int r_data_alloc(Data **dp, int l) { Data *d_ = 0; int _status; if(!(d_ = (Data *)calloc(sizeof(Data), 1))) ABORT(R_NO_MEMORY); if(!(d_->data = (UCHAR *)calloc(l, 1))) ABORT(R_NO_MEMORY); d_->len = l; *dp = d_; _status = 0; abort: if(_status) r_data_destroy(&d_); return _status; } int r_data_make(Data *dp, UCHAR *d, int l) { if(!(dp->data = (UCHAR *)malloc(l))) ERETURN(R_NO_MEMORY); memcpy(dp->data, d, l); dp->len = l; return 0; } int r_data_destroy(Data **dp) { if(!dp || !*dp) return 0; if((*dp)->data) free((*dp)->data); free(*dp); *dp = 0; return 0; } int r_data_copy(Data *dst, Data *src) { if(!(dst->data = (UCHAR *)malloc(src->len))) ERETURN(R_NO_MEMORY); memcpy(dst->data, src->data, dst->len = src->len); return 0; } int r_data_zfree(Data *d) { if(!d) return 0; if(!d->data) return 0; memset(d->data, 0, d->len); free(d->data); return 0; } int r_data_compare(Data *d1, Data *d2) { if(d1->len < d2->len) return -1; if(d2->len < d1->len) return -1; return memcmp(d1->data, d2->data, d1->len); } ssldump-1.9/common/lib/r_data.h000066400000000000000000000037611470411077700165320ustar00rootroot00000000000000/** r_data.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: r_data.h,v 1.2 2000/10/17 16:10:00 ekr Exp $ ekr@rtfm.com Fri Feb 4 08:58:48 2000 */ #ifndef _r_data_h #define _r_data_h #endif ssldump-1.9/common/lib/r_errors.c000066400000000000000000000042131470411077700171210ustar00rootroot00000000000000/** r_errors.c Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: r_errors.c,v 1.3 2001/12/24 06:06:27 ekr Exp $ ekr@rtfm.com Tue Feb 16 16:37:05 1999 */ #include #include #include "r_common.h" #include "r_errors.h" int verr_exit(char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); exit(1); } ssldump-1.9/common/lib/r_list.c000066400000000000000000000114371470411077700165660ustar00rootroot00000000000000/** r_list.c Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: r_list.c,v 1.4 2001/12/24 06:06:27 ekr Exp $ ekr@rtfm.com Tue Jan 19 08:36:39 1999 */ #include #include "r_list.h" typedef struct r_list_el_ { void *data; struct r_list_el_ *next; struct r_list_el_ *prev; int(*copy) PROTO_LIST((void **new, void *old)); int(*destroy) PROTO_LIST((void **ptr)); } r_list_el; struct r_list_ { struct r_list_el_ *first; struct r_list_el_ *last; }; int r_list_create(r_list **listp) { r_list *list = 0; int _status; if(!(list = (r_list *)calloc(sizeof(r_list), 1))) ABORT(R_NO_MEMORY); list->first = 0; list->last = 0; *listp = list; _status = 0; abort: return _status; } int r_list_destroy(r_list **listp) { r_list *list; r_list_el *el; if(!listp || !*listp) return 0; list = *listp; el = list->first; while(el) { r_list_el *el_t; if(el->destroy && el->data) el->destroy(&el->data); el_t = el; el = el->next; free(el_t); } free(list); *listp = 0; return 0; } int r_list_copy(r_list **outp, r_list *in) { r_list *out = 0; r_list_el *el, *el2, *last = 0; int r, _status; if(r = r_list_create(&out)) ABORT(r); for(el = in->first; in; el = el->next) { if(!(el2 = (r_list_el *)calloc(sizeof(r_list_el), 1))) ABORT(R_NO_MEMORY); if(el->copy && el->data) { if(r = el->copy(&el2->data, el->data)) ABORT(r); } el2->copy = el->copy; el2->destroy = el->destroy; if(!(out->first)) out->first = el2; el2->prev = last; last->next = el2; last = el2; } out->last = last; *outp = out; _status = 0; abort: if(_status) r_list_destroy(&out); return _status; } int r_list_insert(list, value, copy, destroy) r_list *list; void *value; int(*copy) PROTO_LIST((void **out, void *in)); int(*destroy) PROTO_LIST((void **val)); { r_list_el *el = 0; int _status; if(!(el = (r_list_el *)calloc(sizeof(r_list_el), 1))) ABORT(R_NO_MEMORY); el->data = value; el->copy = copy; el->destroy = destroy; el->prev = 0; el->next = list->first; if(list->first) { list->first->prev = el; } list->first = el; _status = 0; abort: return _status; } int r_list_append(list, value, copy, destroy) r_list *list; void *value; int(*copy) PROTO_LIST((void **out, void *in)); int(*destroy) PROTO_LIST((void **val)); { r_list_el *el = 0; int _status; if(!(el = (r_list_el *)calloc(sizeof(r_list_el), 1))) ABORT(R_NO_MEMORY); el->data = value; el->copy = copy; el->destroy = destroy; el->prev = list->last; el->next = 0; if(list->last) list->last->next = el; else list->first = el; list->last = el; _status = 0; abort: return _status; } int r_list_init_iter(r_list *list, r_list_iterator *iter) { iter->list = list; iter->ptr = list->first; return 0; } int r_list_iter(r_list_iterator *iter, void **val) { if(!iter->ptr) return R_EOD; *val = iter->ptr->data; iter->ptr = iter->ptr->next; return 0; } ssldump-1.9/common/lib/r_replace.c000066400000000000000000000042331470411077700172220ustar00rootroot00000000000000/** r_replace.c Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: r_replace.c,v 1.2 2000/10/17 16:10:00 ekr Exp $ ekr@rtfm.com Sun Oct 1 11:18:49 2000 */ #include "r_common.h" #ifndef HAVE_STRDUP char *strdup(char *str) { int len = strlen(str); char *n; if(!(n = (char *)malloc(len + 1))) return 0; memcpy(n, str, len + 1); return n; } #endif ssldump-1.9/common/lib/r_time.c000066400000000000000000000105401470411077700165430ustar00rootroot00000000000000/** r_time.c Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: r_time.c,v 1.6 2002/09/09 21:02:58 ekr Exp $ ekr@rtfm.com Thu Mar 4 08:43:46 1999 */ #include #include #ifdef _WIN32 #include int gettimeofday(struct timeval *tv, struct timezone *tzp) { /* JAN1_1970_OFFSET is the number of 100-nanoseconds ticks between midnight jan 1, 1970 and jan 1, 1601. */ const ULARGE_INTEGER JAN1_1970_OFFSET = {0xd53e8000, 0x019db1de}; ULARGE_INTEGER currentTimeSinceJan_1_1970; FILETIME currentTime; GetSystemTimeAsFileTime(¤tTime); currentTimeSinceJan_1_1970.LowPart = currentTime.dwLowDateTime; currentTimeSinceJan_1_1970.HighPart = currentTime.dwHighDateTime; currentTimeSinceJan_1_1970.QuadPart -= JAN1_1970_OFFSET.QuadPart; /* At this point, currentTimeSinceJan_1_1970 contains the number of 100-nanosecond 'ticks' since midnight, Jan. 1, 1970. This is equivalent to 10 * the number of microseconds elapsed since this time. The BSD man pages for gettimeofday() suggest that we should return the whole number of seconds in the tv_sec field, and the fractional number of seconds in units of microseconds in the tv_usec field. sec = time / 10000000, usec = (time % 10000000) / 10; */ tv->tv_sec = currentTimeSinceJan_1_1970.QuadPart / 10000000; tv->tv_usec = (currentTimeSinceJan_1_1970.QuadPart % 10000000) / 10; return 0; } #endif /*Note that t1 must be > t0 */ int r_timeval_diff(struct timeval *t1, struct timeval *t0, struct timeval *diff) { long d; if(t0->tv_sec > t1->tv_sec) ERETURN(R_BAD_ARGS); /*Easy case*/ if(t0->tv_usec <= t1->tv_usec) { diff->tv_sec = t1->tv_sec - t0->tv_sec; diff->tv_usec = t1->tv_usec - t0->tv_usec; return 0; } /*Hard case*/ d = t0->tv_usec - t1->tv_usec; if(t1->tv_sec < (t0->tv_sec + 1)) ERETURN(R_BAD_ARGS); diff->tv_sec = t1->tv_sec - (t0->tv_sec + 1); diff->tv_usec = 1000000 - d; return 0; } int r_timeval_add(struct timeval *t1, struct timeval *t2, struct timeval *sum) { long tv_sec, tv_usec, d; tv_sec = t1->tv_sec + t2->tv_sec; d = t1->tv_usec + t2->tv_usec; if(d > 1000000) { tv_sec++; tv_usec = d - 1000000; } else { tv_usec = d; } sum->tv_sec = tv_sec; sum->tv_usec = tv_usec; return 0; } UINT8 r_timeval2int(struct timeval *tv) { UINT8 r = 0; r = (tv->tv_sec); r *= 1000000; r += tv->tv_usec; return r; } UINT8 r_gettimeint(void) { struct timeval tv; gettimeofday(&tv, 0); return r_timeval2int(&tv); } ssldump-1.9/common/lib/threads/000077500000000000000000000000001470411077700165525ustar00rootroot00000000000000ssldump-1.9/common/lib/threads/pthreads/000077500000000000000000000000001470411077700203645ustar00rootroot00000000000000ssldump-1.9/common/lib/threads/pthreads/pthread.c000066400000000000000000000042361470411077700221640ustar00rootroot00000000000000/** pthread.c Copyright (C) 1999, RTFM, Inc. All Rights Reserved. ekr@rtfm.com Tue Feb 23 15:08:03 1999 */ #include #include #include static int thread_count = 0; typedef struct { void(*func) PROTO_LIST((void *)); void *arg; } helper; static void *r_thread_real_create PROTO_LIST((void *arg)); static void *r_thread_real_create(void *arg) { helper *h; h = (helper *)arg; thread_count++; h->func(h->arg); thread_count--; free(h); return 0; } int r_thread_fork(func, arg, id) void(*func) PROTO_LIST((void *)); void *arg; r_thread *id; { pthread_t thread; helper *h; int r, _status; h = (helper *)malloc(sizeof(helper)); h->func = func; h->arg = arg; if(r = pthread_create(&thread, 0, r_thread_real_create, (void *)h)) ABORT(R_INTERNAL); _status = 0; abort: return _status; } int r_thread_yield(void) { pthread_yield(); } int r_thread_exit(void) { thread_count--; pthread_exit(0); return 0; } int r_thread_wait_last(void) { do { pthread_yield(); usleep(10000); DBG((0, "%d threads left", thread_count)); } while(thread_count); return 0; } int r_rwlock_create(r_rwlock **lockp) { pthread_rwlock_t *lock; int r; if(!(lock = (pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t)))) ERETURN(R_NO_MEMORY); if(r = pthread_rwlock_init(lock, 0)) ERETURN(R_INTERNAL); *lockp = (void *)lock; return 0; } int r_rwlock_destroy(r_rwlock **lock) { pthread_rwlock_t *plock; if(!lock || !*lock) return 0; plock = (pthread_rwlock_t *)(*lock); pthread_rwlock_destroy(plock); return 0; } int r_rwlock_lock(r_rwlock *lock, int action) { pthread_rwlock_t *plock; int r, _status; plock = (pthread_rwlock_t *)lock; switch(action) { case R_RWLOCK_UNLOCK: if(r = pthread_rwlock_unlock(plock)) ABORT(R_INTERNAL); break; case R_RWLOCK_RLOCK: if(r = pthread_rwlock_rdlock(plock)) ABORT(R_INTERNAL); break; case R_RWLOCK_WLOCK: if(r = pthread_rwlock_wrlock(plock)) ABORT(R_INTERNAL); break; default: ABORT(R_BAD_ARGS); } _status = 0; abort: return _status; } ssldump-1.9/docker/000077500000000000000000000000001470411077700143315ustar00rootroot00000000000000ssldump-1.9/docker/README.md000066400000000000000000000012241470411077700156070ustar00rootroot00000000000000# Docker instructions *Note: Dockerfiles are only provided for Debian-like distributions so far.* ## Configure image building: Uncomment the distribution reference you want to use, in top section in `debian-distros/Dockerfile`. ## Build the image: `cd debian-distros` `./docker_build.sh` ## Run the container, and start ssldump inside the container: `./docker_run.sh` `(in container) sudo ssldump -n -i eth0 -j -AH` ## Mirror traffic to container Outside of the container, adjust local interface name and container IP address in `mirror_traffic_to_container.sh`. Then mirror local traffic to ssldump container: `./mirror_traffic_to_container.sh` ssldump-1.9/docker/debian-distros/000077500000000000000000000000001470411077700172405ustar00rootroot00000000000000ssldump-1.9/docker/debian-distros/Dockerfile000066400000000000000000000014541470411077700212360ustar00rootroot00000000000000#FROM debian:bookworm-slim #FROM debian:bullseye-slim #FROM debian:buster-slim FROM ubuntu:jammy #FROM ubuntu:focal ENV LANG C ENV DEBIAN_FRONTEND noninteractive RUN apt-get update && \ apt-get dist-upgrade -y && \ apt-get install -y --no-install-recommends ca-certificates sudo git build-essential cmake ninja-build clang libssl-dev libpcap-dev libnet1-dev libjson-c-dev iproute2 && \ apt-get clean RUN useradd -ms /bin/bash ssldump RUN passwd -d ssldump RUN printf 'ssldump ALL=(ALL) ALL\n' | tee -a /etc/sudoers USER ssldump RUN cd /home/ssldump && \ git clone https://github.com/adulau/ssldump.git ssldump-build RUN cd /home/ssldump/ssldump-build && \ cmake -G Ninja -B build && \ ninja -C build && \ sudo ninja -C build install WORKDIR "/home/ssldump" CMD ["/bin/bash"] ssldump-1.9/docker/debian-distros/docker_build.sh000077500000000000000000000003261470411077700222260ustar00rootroot00000000000000#!/bin/bash ssldump_version=$(awk '/\s+VERSION/ {print $2}' ../../CMakeLists.txt) distribution=$(awk '/^FROM/ {gsub(":","-"); print $2}' Dockerfile) docker build -t "ssldump-${distribution}:${ssldump_version}" . ssldump-1.9/docker/debian-distros/docker_run.sh000077500000000000000000000003221470411077700217270ustar00rootroot00000000000000#!/bin/bash ssldump_version=$(awk '/\s+VERSION/ {print $2}' ../../CMakeLists.txt) distribution=$(awk '/^FROM/ {gsub(":","-"); print $2}' Dockerfile) docker run -it ssldump-${distribution}:${ssldump_version} ssldump-1.9/docker/mirror_traffic_to_container.sh000077500000000000000000000003461470411077700224470ustar00rootroot00000000000000#!/bin/bash local_if=eth0 container_ip=172.17.0.2 sudo iptables -t mangle -I PREROUTING 1 -i ${local_if} -j TEE --gateway ${container_ip} sudo iptables -t mangle -I POSTROUTING 1 -o ${local_if} -j TEE --gateway ${container_ip} ssldump-1.9/null/000077500000000000000000000000001470411077700140345ustar00rootroot00000000000000ssldump-1.9/null/null_analyze.c000066400000000000000000000112121470411077700166720ustar00rootroot00000000000000/** null_analyze.c Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: null_analyze.c,v 1.6 2001/11/26 22:28:16 ekr Exp $ ekr@rtfm.com Thu Jan 7 22:58:27 1999 */ #include #include "network.h" #include "proto_mod.h" #include "debug.h" typedef struct null_analyzer_ { int num; } null_analyzer; static int create_null_analyzer PROTO_LIST((void *handle, proto_ctx *ctx, tcp_conn *conn, proto_obj **objp, struct sockaddr_storage *i_addr, u_short i_port, struct sockaddr_storage *r_addr, u_short r_port, struct timeval *base_time)); static int create_null_analyzer(void *handle, proto_ctx *ctx, tcp_conn *conn, proto_obj **objp, struct sockaddr_storage *i_addr, u_short i_port, struct sockaddr_storage *r_addr, u_short r_port, struct timeval *base_time) { null_analyzer *obj = 0; static int ctr; if(!(obj = (null_analyzer *)calloc(1, sizeof(null_analyzer)))) ERETURN(R_NO_MEMORY); obj->num = ctr++; DBG((0, "Creating analyzer for connection %d\n", obj->num)); *objp = (proto_obj *)obj; return 0; } int destroy_null_analyzer(proto_obj **objp) { #ifdef DEBUG null_analyzer *obj; #endif if(!objp || !*objp) return 0; #ifdef DEBUG obj = (null_analyzer *)*objp; #endif DBG((0, "Destroying analyzer for connection %d\n", obj->num)); free(*objp); *objp = 0; return 0; } int data_null_analyzer(proto_obj *_obj, segment *seg, int direction) { #ifdef DEBUG null_analyzer *obj = (null_analyzer *)_obj; #endif DBG((0, "Processing data for connection %d dir %d\n", obj->num, direction)); for(; seg; seg = seg->next) { int i; for(i = 0; i < MIN(seg->len, 20); i++) { if(!isascii(seg->data[i])) break; } if(i < 20) xdump("NSEGMENT", seg->data, seg->len); else { printf("NSEGMENT: "); fwrite(seg->data, 1, seg->len, stdout); } printf("====\n"); } return 0; } int fin_null_analyzer(proto_obj *_obj, packet *p, int direction) { #ifdef DEBUG null_analyzer *obj = (null_analyzer *)_obj; #endif DBG((0, "Received FIN on connection %d\n", obj->num)); return 0; } static struct proto_mod_vtbl_ null_vtbl = { 0, 0, 0, create_null_analyzer, 0, destroy_null_analyzer, data_null_analyzer, fin_null_analyzer, }; struct proto_mod_ null_mod = {0, &null_vtbl}; ssldump-1.9/null/null_analyze.h000066400000000000000000000040451470411077700167050ustar00rootroot00000000000000/** null_analyze.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: null_analyze.h,v 1.2 2000/10/17 16:10:01 ekr Exp $ ekr@rtfm.com Fri Jan 8 11:23:10 1999 */ #ifndef _null_analyze_h #define _null_analyze_h extern proto_mod null_mod; #endif ssldump-1.9/pcap/000077500000000000000000000000001470411077700140055ustar00rootroot00000000000000ssldump-1.9/pcap/attrib.h000066400000000000000000000052011470411077700154410ustar00rootroot00000000000000/*- * SSLsplit - transparent SSL/TLS interception * https://www.roe.ch/SSLsplit * * Copyright (c) 2009-2019, Daniel Roethlisberger . * 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 COPYRIGHT HOLDER 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 COPYRIGHT HOLDER 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. */ #ifndef ATTRIB_H #define ATTRIB_H /* * GCC attributes and built-ins for improved compile-time error checking * and performance optimization. * * All of these are fully optional and are automatically disabled on non-GCC * and non-LLVM/clang compilers. */ /* * Attributes. * These serve to improve the compiler warnings or optimizations. */ #if !defined(__GNUC__) && !defined(__clang__) #define __attribute__(x) #endif #define UNUSED __attribute__((unused)) #define NORET __attribute__((noreturn)) #define PRINTF(f, a) __attribute__((format(printf, (f), (a)))) #define SCANF(f, a) __attribute__((format(scanf, (f), (a)))) #define WUNRES __attribute__((warn_unused_result)) #define MALLOC __attribute__((malloc)) WUNRES #define NONNULL(...) __attribute__((nonnull(__VA_ARGS__))) #define PURE __attribute__((pure)) /* * Branch prediction macros. * These serve to tell the compiler which of the branches is more likely. */ #if !defined(__GNUC__) && !defined(__clang__) #define likely(expr) (expr) #define unlikely(expr) (expr) #else #define likely(expr) __builtin_expect((expr), 1) #define unlikely(expr) __builtin_expect((expr), 0) #endif #endif /* !ATTRIB_H */ /* vim: set noet ft=c: */ ssldump-1.9/pcap/logpkt.c000066400000000000000000000640661470411077700154650ustar00rootroot00000000000000/*- * SSLsplit - transparent SSL/TLS interception * https://www.roe.ch/SSLsplit * * Copyright (c) 2009-2019, Daniel Roethlisberger . * 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 COPYRIGHT HOLDER 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 COPYRIGHT HOLDER 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. */ #include "logpkt.h" #include "sys.h" #include #include #include #include #include #include #include #include #include #include #ifndef WITHOUT_MIRROR #include #endif /* !WITHOUT_MIRROR */ typedef struct __attribute__((packed)) { uint32_t magic_number; /* magic number */ uint16_t version_major; /* major version number */ uint16_t version_minor; /* minor version number */ uint32_t thiszone; /* GMT to local correction */ uint32_t sigfigs; /* accuracy of timestamps */ uint32_t snaplen; /* max length of captured packets, in octets */ uint32_t network; /* data link type */ } pcap_file_hdr_t; typedef struct __attribute__((packed)) { uint32_t ts_sec; /* timestamp seconds */ uint32_t ts_usec; /* timestamp microseconds */ uint32_t incl_len; /* number of octets of packet saved in file */ uint32_t orig_len; /* actual length of packet */ } pcap_rec_hdr_t; #define PCAP_MAGIC 0xa1b2c3d4 typedef struct __attribute__((packed)) { uint8_t dst_mac[ETHER_ADDR_LEN]; uint8_t src_mac[ETHER_ADDR_LEN]; uint16_t ethertype; } ether_hdr_t; #ifndef ETHERTYPE_IP #define ETHERTYPE_IP 0x0800 #endif #ifndef ETHERTYPE_IPV6 #define ETHERTYPE_IPV6 0x86dd #endif typedef struct __attribute__((packed)) { uint8_t version_ihl; uint8_t dscp_ecn; uint16_t len; uint16_t id; uint16_t frag; uint8_t ttl; uint8_t proto; uint16_t chksum; uint32_t src_addr; uint32_t dst_addr; } ip4_hdr_t; typedef struct __attribute__((packed)) { uint32_t flags; uint16_t len; uint8_t next_hdr; uint8_t hop_limit; uint8_t src_addr[16]; uint8_t dst_addr[16]; } ip6_hdr_t; typedef struct __attribute__((packed)) { uint16_t src_port; uint16_t dst_port; uint32_t seq; uint32_t ack; uint16_t flags; uint16_t win; uint16_t chksum; uint16_t urgp; } tcp_hdr_t; #ifndef TH_FIN #define TH_FIN 0x01 #endif #ifndef TH_SYN #define TH_SYN 0x02 #endif #ifndef TH_RST #define TH_RST 0x04 #endif #ifndef TH_PUSH #define TH_PUSH 0x08 #endif #ifndef TH_ACK #define TH_ACK 0x10 #endif /* * *MTU* is the size of the largest layer 3 packet, including IP header. * * *MAX_PKTSZ* is the buffer size needed to construct a layer 2 frame * containing the largest possible layer 3 packet allowed by MTU. * * *MSS_IP4* and *MSS_IP6* are the maximum TCP segment sizes that fit into a * single IPv4 and IPv6 packet, respectively. * * The calculations assume no IPv4 options and no IPv6 option headers. * * These constants are only used for PCAP writing, not for mirroring. */ //#define MTU 1500 #define MTU 65535 // we add support for jumboframes and offload #define MAX_PKTSZ (MTU + sizeof(ether_hdr_t)) #define MSS_IP4 (MTU - sizeof(ip4_hdr_t) - sizeof(tcp_hdr_t)) #define MSS_IP6 (MTU - sizeof(ip6_hdr_t) - sizeof(tcp_hdr_t)) /* * IP/TCP checksumming operating on uint32_t intermediate state variable C. */ #define CHKSUM_INIT(C) \ { (C) = 0; } #define CHKSUM_ADD_RANGE(C, B, S) \ { \ uint16_t *p = (uint16_t *)(B); \ size_t words = (S) >> 1; \ while(words--) { \ (C) += *p++; \ } \ if((S)&1) { \ (C) += htons(*((char *)p) << 8); \ } \ } #define CHKSUM_ADD_UINT32(C, U) \ { (C) += ((U) >> 16) + ((U)&0xFFFF); } #define CHKSUM_ADD_UINT16(C, U) \ { (C) += (U); } #define CHKSUM_FINALIZE(C) \ { \ (C) = ((C) >> 16) + ((C)&0xffff); \ (C) += ((C) >> 16); \ (C) = ~(C); \ } /* Socket address typecasting shorthand notations. */ #define CSA(X) ((const struct sockaddr *)(X)) #define CSIN(X) ((const struct sockaddr_in *)(X)) #define CSIN6(X) ((const struct sockaddr_in6 *)(X)) /* * Write the PCAP file-level header to file descriptor *fd* open for writing, * positioned at the beginning of an empty file. * * Returns 0 on success and -1 on failure. */ static int logpkt_write_global_pcap_hdr(int fd) { pcap_file_hdr_t hdr; memset(&hdr, 0x0, sizeof(hdr)); hdr.magic_number = PCAP_MAGIC; hdr.version_major = 2; hdr.version_minor = 4; hdr.snaplen = MAX_PKTSZ; hdr.network = 1; return write(fd, &hdr, sizeof(hdr)) != sizeof(hdr) ? -1 : 0; } /* * Called on a file descriptor open for reading and writing. * If the fd points to an empty file, a pcap header is added and 0 is returned. * If the fd points to a file with PCAP magic bytes, the file position is moved * to the end of the file and 0 is returned. * If the fd points to a file without PCAP magic bytes, the file is truncated * to zero bytes and a new PCAP header is written. * On a return value of 0, the caller can continue to write PCAP records to the * file descriptor. On error, -1 is returned and the file descriptor is in an * undefined but still open state. */ int logpkt_pcap_open_fd(int fd) { pcap_file_hdr_t hdr; off_t sz; ssize_t n; struct stat st; if(fstat(fd, &st)) return -1; if(!S_ISFIFO(st.st_mode)) { sz = lseek(fd, 0, SEEK_END); if(sz == -1) return -1; if(sz > 0) { if(lseek(fd, 0, SEEK_SET) == -1) return -1; n = read(fd, &hdr, sizeof(pcap_file_hdr_t)); if(n != sizeof(pcap_file_hdr_t)) return -1; if(hdr.magic_number == PCAP_MAGIC) return lseek(fd, 0, SEEK_END) == -1 ? -1 : 0; if(lseek(fd, 0, SEEK_SET) == -1) return -1; if(ftruncate(fd, 0) == -1) return -1; } } return logpkt_write_global_pcap_hdr(fd); } /* * Initialize the per-connection packet crafting context. For mirroring, * *libnet* must be an initialized libnet instance and *mtu* must be the * target interface MTU greater than 0. For PCAP writing, *libnet* must be * NULL and *mtu* must be 0. The ether and sockaddr addresses are used as the * layer 2 and layer 3 addresses respectively. For mirroring, the ethers must * match the actual link layer addresses to be used when sending traffic, not * some emulated addresses. */ void logpkt_ctx_init(logpkt_ctx_t *ctx, libnet_t *libnet, size_t mtu, const uint8_t *src_ether, const uint8_t *dst_ether, const struct sockaddr *src_addr, socklen_t src_addr_len, const struct sockaddr *dst_addr, socklen_t dst_addr_len, const uint32_t *timestamp_sec, const uint32_t *timestamp_usec) { ctx->libnet = libnet; memcpy(ctx->src_ether, src_ether, ETHER_ADDR_LEN); memcpy(ctx->dst_ether, dst_ether, ETHER_ADDR_LEN); memcpy(&ctx->src_addr, src_addr, src_addr_len); memcpy(&ctx->dst_addr, dst_addr, dst_addr_len); memcpy(&ctx->timestamp_sec, timestamp_sec, sizeof(timestamp_sec)); memcpy(&ctx->timestamp_usec, timestamp_usec, sizeof(timestamp_usec)); ctx->src_seq = 0; ctx->dst_seq = 0; if(mtu) { ctx->mss = mtu - sizeof(tcp_hdr_t) - (dst_addr->sa_family == AF_INET ? sizeof(ip4_hdr_t) : sizeof(ip6_hdr_t)); } else { ctx->mss = dst_addr->sa_family == AF_INET ? MSS_IP4 : MSS_IP6; } } /* * Write the layer 2 frame contained in *pkt* to file descriptor *fd* already * open for writing. First writes a PCAP record header, then the actual frame. */ static int logpkt_pcap_write(const uint8_t *pkt, size_t pktsz, int fd, uint32_t timestamp_sec, uint32_t timestamp_usec) { pcap_rec_hdr_t rec_hdr; struct timeval tv; if (timestamp_sec != 0 || timestamp_usec != 0) { rec_hdr.ts_sec = timestamp_sec; rec_hdr.ts_usec = timestamp_usec; } else { gettimeofday(&tv, NULL); rec_hdr.ts_sec = tv.tv_sec; rec_hdr.ts_usec = tv.tv_usec; } rec_hdr.orig_len = rec_hdr.incl_len = pktsz; if(write(fd, &rec_hdr, sizeof(rec_hdr)) != sizeof(rec_hdr)) { printf("Error writing pcap record hdr: %s\n", strerror(errno)); return -1; } if(write(fd, pkt, pktsz) != (ssize_t)pktsz) { printf("Error writing pcap record: %s\n", strerror(errno)); return -1; } return 0; } /* * Build a frame from the given layer 2, layer 3 and layer 4 parameters plus * payload, write the resulting bytes into buffer pointed to by *pkt*, and fix * the checksums on all layers. The receiving buffer must be at least * MAX_PKTSZ bytes large and payload must be a maximum of MSS_IP4 or MSS_IP6 * respectively. Layer 2 is Ethernet II, layer 3 is IPv4 or IPv6 depending on * the address family of *dst_addr*, and layer 4 is TCP. * * This function is stateless. For header fields that cannot be directly * derived from the arguments, default values will be used. */ static size_t logpkt_pcap_build(uint8_t *pkt, uint8_t *src_ether, uint8_t *dst_ether, const struct sockaddr *src_addr, const struct sockaddr *dst_addr, char flags, uint32_t seq, uint32_t ack, const uint8_t *payload, size_t payloadlen) { ether_hdr_t *ether_hdr; ip4_hdr_t *ip4_hdr; ip6_hdr_t *ip6_hdr; tcp_hdr_t *tcp_hdr; size_t sz; uint32_t sum; ether_hdr = (ether_hdr_t *)pkt; memcpy(ether_hdr->src_mac, src_ether, sizeof(ether_hdr->src_mac)); memcpy(ether_hdr->dst_mac, dst_ether, sizeof(ether_hdr->dst_mac)); sz = sizeof(ether_hdr_t); if(dst_addr->sa_family == AF_INET) { ether_hdr->ethertype = htons(ETHERTYPE_IP); ip4_hdr = (ip4_hdr_t *)(((uint8_t *)ether_hdr) + sizeof(ether_hdr_t)); ip4_hdr->version_ihl = 0x45; /* version 4, ihl 5 words */ ip4_hdr->dscp_ecn = 0; ip4_hdr->len = htons(sizeof(ip4_hdr_t) + sizeof(tcp_hdr_t) + payloadlen); ip4_hdr->id = sys_rand16(), ip4_hdr->frag = 0; ip4_hdr->ttl = 64; ip4_hdr->proto = IPPROTO_TCP; ip4_hdr->src_addr = CSIN(src_addr)->sin_addr.s_addr; ip4_hdr->dst_addr = CSIN(dst_addr)->sin_addr.s_addr; ip4_hdr->chksum = 0; CHKSUM_INIT(sum); CHKSUM_ADD_RANGE(sum, ip4_hdr, sizeof(ip4_hdr_t)); CHKSUM_FINALIZE(sum); ip4_hdr->chksum = sum; sz += sizeof(ip4_hdr_t); tcp_hdr = (tcp_hdr_t *)(((uint8_t *)ip4_hdr) + sizeof(ip4_hdr_t)); tcp_hdr->src_port = CSIN(src_addr)->sin_port; tcp_hdr->dst_port = CSIN(dst_addr)->sin_port; /* pseudo header */ CHKSUM_INIT(sum); CHKSUM_ADD_UINT32(sum, ip4_hdr->src_addr); CHKSUM_ADD_UINT32(sum, ip4_hdr->dst_addr); CHKSUM_ADD_UINT16(sum, htons(ip4_hdr->proto)); CHKSUM_ADD_UINT16(sum, htons(sizeof(tcp_hdr_t) + payloadlen)); } else { ether_hdr->ethertype = htons(ETHERTYPE_IPV6); ip6_hdr = (ip6_hdr_t *)(((uint8_t *)ether_hdr) + sizeof(ether_hdr_t)); ip6_hdr->flags = htonl(0x60000000UL); /* version 6 */ ip6_hdr->len = htons(sizeof(tcp_hdr_t) + payloadlen); ip6_hdr->next_hdr = IPPROTO_TCP; ip6_hdr->hop_limit = 255; memcpy(ip6_hdr->src_addr, CSIN6(src_addr)->sin6_addr.s6_addr, sizeof(ip6_hdr->src_addr)); memcpy(ip6_hdr->dst_addr, CSIN6(dst_addr)->sin6_addr.s6_addr, sizeof(ip6_hdr->dst_addr)); sz += sizeof(ip6_hdr_t); tcp_hdr = (tcp_hdr_t *)(((uint8_t *)ip6_hdr) + sizeof(ip6_hdr_t)); tcp_hdr->src_port = CSIN6(src_addr)->sin6_port; tcp_hdr->dst_port = CSIN6(dst_addr)->sin6_port; /* pseudo header */ CHKSUM_INIT(sum); CHKSUM_ADD_RANGE(sum, ip6_hdr->src_addr, sizeof(ip6_hdr->src_addr)); CHKSUM_ADD_RANGE(sum, ip6_hdr->dst_addr, sizeof(ip6_hdr->dst_addr)); CHKSUM_ADD_UINT32(sum, ip6_hdr->len); CHKSUM_ADD_UINT16(sum, htons(IPPROTO_TCP)); } tcp_hdr->seq = htonl(seq); tcp_hdr->ack = htonl(ack); tcp_hdr->flags = htons(0x5000 | flags); /* data offset 5 words */ tcp_hdr->win = htons(32767); tcp_hdr->urgp = 0; tcp_hdr->chksum = 0; sz += sizeof(tcp_hdr_t); memcpy(((uint8_t *)tcp_hdr) + sizeof(tcp_hdr_t), payload, payloadlen); CHKSUM_ADD_RANGE(sum, tcp_hdr, sizeof(tcp_hdr_t) + payloadlen); CHKSUM_FINALIZE(sum); tcp_hdr->chksum = sum; return sz + payloadlen; } #ifndef WITHOUT_MIRROR /* * Build a packet using libnet intended for mirroring mode. The packet will * be dynamically allocated on the heap by the libnet instance *libnet*. */ static int logpkt_mirror_build(libnet_t *libnet, uint8_t *src_ether, uint8_t *dst_ether, const struct sockaddr *src_addr, const struct sockaddr *dst_addr, char flags, uint32_t seq, uint32_t ack, const uint8_t *payload, size_t payloadlen) { libnet_ptag_t ptag; ptag = libnet_build_tcp( htons(src_addr->sa_family == AF_INET ? CSIN(src_addr)->sin_port : CSIN6(src_addr)->sin6_port), htons(dst_addr->sa_family == AF_INET ? CSIN(dst_addr)->sin_port : CSIN6(dst_addr)->sin6_port), seq, ack, flags, 32767, /* window size */ 0, /* checksum */ 0, /* urgent pointer */ LIBNET_TCP_H + payloadlen, (uint8_t *)payload, payloadlen, libnet, 0); if(ptag == -1) { printf("Error building tcp header: %s", libnet_geterror(libnet)); return -1; } if(dst_addr->sa_family == AF_INET) { ptag = libnet_build_ipv4( LIBNET_IPV4_H + LIBNET_TCP_H + payloadlen, 0, /* TOS */ (uint16_t)sys_rand16(), /* id */ 0x4000, /* frag */ 64, /* TTL */ IPPROTO_TCP, /* protocol */ 0, /* checksum */ CSIN(src_addr)->sin_addr.s_addr, CSIN(dst_addr)->sin_addr.s_addr, NULL, 0, libnet, 0); } else { ptag = libnet_build_ipv6( 0, /* traffic class */ 0, /* flow label */ LIBNET_IPV6_H + LIBNET_TCP_H + payloadlen, IPPROTO_TCP, 255, /* hop limit */ *(struct libnet_in6_addr *)&CSIN6(src_addr)->sin6_addr, *(struct libnet_in6_addr *)&CSIN6(dst_addr)->sin6_addr, NULL, 0, libnet, 0); } if(ptag == -1) { printf("Error building ip header: %s", libnet_geterror(libnet)); return -1; } ptag = libnet_build_ethernet( dst_ether, src_ether, dst_addr->sa_family == AF_INET ? ETHERTYPE_IP : ETHERTYPE_IPV6, NULL, 0, libnet, 0); if(ptag == -1) { printf("Error building ethernet header: %s", libnet_geterror(libnet)); return -1; } return 0; } #endif /* !WITHOUT_MIRROR */ /* * Write a single packet to either PCAP (*fd* != -1) or a network interface * (*fd* == -1). Caller must ensure that *ctx* was initialized accordingly. * The packet will be in direction *direction*, use TCP flags *flags*, and * transmit a payload *payload*. TCP sequence and acknowledgement numbers as * well as source and destination identifiers are taken from *ctx*. * * Caller must ensure that *payload* fits into a frame depending on the MTU * selected (interface in mirroring mode, MTU value in PCAP writing mode). */ static int logpkt_write_packet(logpkt_ctx_t *ctx, int fd, int direction, char flags, const uint8_t *payload, size_t payloadlen) { int rv; if(fd != -1) { uint8_t buf[MAX_PKTSZ]; size_t sz; if(direction == LOGPKT_REQUEST) { sz = logpkt_pcap_build(buf, ctx->src_ether, ctx->dst_ether, CSA(&ctx->src_addr), CSA(&ctx->dst_addr), flags, ctx->src_seq, ctx->dst_seq, payload, payloadlen); } else { sz = logpkt_pcap_build(buf, ctx->dst_ether, ctx->src_ether, CSA(&ctx->dst_addr), CSA(&ctx->src_addr), flags, ctx->dst_seq, ctx->src_seq, payload, payloadlen); } rv = logpkt_pcap_write(buf, sz, fd, ctx->timestamp_sec, ctx->timestamp_usec); if(rv == -1) { printf("Error writing packet to PCAP file\n"); return -1; } } else { #ifndef WITHOUT_MIRROR /* Source and destination ether are determined by the actual * local MAC address and target MAC address for mirroring the * packets to; use them as-is for both directions. */ if(direction == LOGPKT_REQUEST) { rv = logpkt_mirror_build(ctx->libnet, ctx->src_ether, ctx->dst_ether, CSA(&ctx->src_addr), CSA(&ctx->dst_addr), flags, ctx->src_seq, ctx->dst_seq, payload, payloadlen); } else { rv = logpkt_mirror_build(ctx->libnet, ctx->src_ether, ctx->dst_ether, CSA(&ctx->dst_addr), CSA(&ctx->src_addr), flags, ctx->dst_seq, ctx->src_seq, payload, payloadlen); } if(rv == -1) { printf("Error building packet\n"); return -1; } rv = libnet_write(ctx->libnet); if(rv == -1) { printf("Error writing packet: %s\n", libnet_geterror(ctx->libnet)); } libnet_clear_packet(ctx->libnet); #else /* WITHOUT_MIRROR */ rv = -1; #endif /* WITHOUT_MIRROR */ } return rv; } /* * Emulate the initial SYN handshake. */ static int logpkt_write_syn_handshake(logpkt_ctx_t *ctx, int fd) { ctx->src_seq = sys_rand32(); if(logpkt_write_packet(ctx, fd, LOGPKT_REQUEST, TH_SYN, NULL, 0) == -1) return -1; ctx->src_seq += 1; ctx->dst_seq = sys_rand32(); if(logpkt_write_packet(ctx, fd, LOGPKT_RESPONSE, TH_SYN | TH_ACK, NULL, 0) == -1) return -1; ctx->dst_seq += 1; if(logpkt_write_packet(ctx, fd, LOGPKT_REQUEST, TH_ACK, NULL, 0) == -1) return -1; return 0; } /* * Emulate the necessary packets to write a single payload segment. If * necessary, a SYN handshake will automatically be generated before emitting * the packet carrying the payload plus a matching ACK. */ int logpkt_write_payload(logpkt_ctx_t *ctx, int fd, int direction, const uint8_t *payload, size_t payloadlen) { int other_direction = (direction == LOGPKT_REQUEST) ? LOGPKT_RESPONSE : LOGPKT_REQUEST; if(ctx->src_seq == 0) { if(logpkt_write_syn_handshake(ctx, fd) == -1) return -1; } while(payloadlen > 0) { size_t n = payloadlen > ctx->mss ? ctx->mss : payloadlen; if(logpkt_write_packet(ctx, fd, direction, TH_PUSH | TH_ACK, payload, n) == -1) { printf( "Warning: Failed to write to pcap log" ": %s\n", strerror(errno)); return -1; } if(direction == LOGPKT_REQUEST) { ctx->src_seq += n; } else { ctx->dst_seq += n; } payload += n; payloadlen -= n; } if(logpkt_write_packet(ctx, fd, other_direction, TH_ACK, NULL, 0) == -1) { printf("Warning: Failed to write to pcap log: %s\n", strerror(errno)); return -1; } return 0; } /* * Emulate a connection close, emitting a FIN handshake in the correct * direction. Does not close the file descriptor. */ int logpkt_write_close(logpkt_ctx_t *ctx, int fd, int direction) { int other_direction = (direction == LOGPKT_REQUEST) ? LOGPKT_RESPONSE : LOGPKT_REQUEST; if(ctx->src_seq == 0) { if(logpkt_write_syn_handshake(ctx, fd) == -1) return -1; } if(logpkt_write_packet(ctx, fd, direction, TH_FIN | TH_ACK, NULL, 0) == -1) { printf("Warning: Failed to write packet\n"); return -1; } if(direction == LOGPKT_REQUEST) { ctx->src_seq += 1; } else { ctx->dst_seq += 1; } if(logpkt_write_packet(ctx, fd, other_direction, TH_FIN | TH_ACK, NULL, 0) == -1) { printf("Warning: Failed to write packet\n"); return -1; } if(other_direction == LOGPKT_REQUEST) { ctx->src_seq += 1; } else { ctx->dst_seq += 1; } if(logpkt_write_packet(ctx, fd, direction, TH_ACK, NULL, 0) == -1) { printf("Warning: Failed to write packet\n"); return -1; } return 0; } #ifndef WITHOUT_MIRROR typedef struct { uint32_t ip; int result; uint8_t ether[ETHER_ADDR_LEN]; } logpkt_recv_arp_reply_ctx_t; /* * Receive a single ARP reply and copy the resulting ether to ctx->ether. */ static void logpkt_recv_arp_reply(uint8_t *user, UNUSED const struct pcap_pkthdr *h, const uint8_t *packet) { logpkt_recv_arp_reply_ctx_t *ctx = (logpkt_recv_arp_reply_ctx_t *)user; struct libnet_802_3_hdr *heth = (void *)packet; struct libnet_arp_hdr *harp = (void *)((char *)heth + LIBNET_ETH_H); /* skip if wrong protocol */ if(htons(harp->ar_op) != ARPOP_REPLY) return; if(htons(harp->ar_pro) != ETHERTYPE_IP) return; if(htons(harp->ar_hrd) != ARPHRD_ETHER) return; /* skip if wrong target IP address */ if(!!memcmp(&ctx->ip, (char *)harp + harp->ar_hln + LIBNET_ARP_H, 4)) return; /* skip if source ether mismatch */ if(!!memcmp((u_char *)harp + sizeof(struct libnet_arp_hdr), heth->_802_3_shost, ETHER_ADDR_LEN)) return; memcpy(ctx->ether, (u_char *)harp + sizeof(struct libnet_arp_hdr), ETHER_ADDR_LEN); ctx->result = 0; } /* * Look up the appropriate source and destination ethernet addresses for * mirroring packets to dst_ip_s on interface dst_if_s. * Only IPv4 mirror targets are supported. */ int logpkt_ether_lookup(libnet_t *libnet, uint8_t *src_ether, uint8_t *dst_ether, const char *dst_ip_s, const char *dst_if_s) { char errbuf[PCAP_ERRBUF_SIZE]; uint8_t broadcast_ether[ETHER_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; uint8_t zero_ether[ETHER_ADDR_LEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; struct libnet_ether_addr *src_ether_addr; uint32_t src_ip; struct bpf_program bp; int count = 50; logpkt_recv_arp_reply_ctx_t ctx; if(sys_get_af(dst_ip_s) != AF_INET) { printf("Mirroring target must be an IPv4 address.\n"); return -1; } ctx.result = -1; ctx.ip = libnet_name2addr4(libnet, (char *)dst_ip_s, LIBNET_DONT_RESOLVE); if(ctx.ip == (uint32_t)-1) { printf("Error converting dst IP address: %s\n", libnet_geterror(libnet)); goto out; } src_ip = libnet_get_ipaddr4(libnet); if(src_ip == (uint32_t)-1) { printf("Error getting src IP address: %s\n", libnet_geterror(libnet)); goto out; } src_ether_addr = libnet_get_hwaddr(libnet); if(src_ether_addr == NULL) { printf("Error getting src ethernet address: %s\n", libnet_geterror(libnet)); goto out; } memcpy(src_ether, src_ether_addr->ether_addr_octet, ETHER_ADDR_LEN); if(libnet_autobuild_arp(ARPOP_REQUEST, src_ether, (uint8_t *)&src_ip, zero_ether, (uint8_t *)&ctx.ip, libnet) == -1) { printf("Error building arp header: %s\n", libnet_geterror(libnet)); goto out; } if(libnet_autobuild_ethernet(broadcast_ether, ETHERTYPE_ARP, libnet) == -1) { printf("Error building ethernet header: %s", libnet_geterror(libnet)); goto out; } pcap_t *pcap = pcap_open_live(dst_if_s, 100, 0, 10, errbuf); if(pcap == NULL) { printf("Error in pcap_open_live(): %s\n", errbuf); goto out; } if(pcap_compile(pcap, &bp, "arp", 0, -1) == -1) { printf("Error in pcap_compile(): %s\n", pcap_geterr(pcap)); goto out2; } if(pcap_setfilter(pcap, &bp) == -1) { printf("Error in pcap_setfilter(): %s\n", pcap_geterr(pcap)); goto out3; } do { if(libnet_write(libnet) != -1) { /* Limit # of packets to process, so we can loop to * send arp requests on busy networks. */ if(pcap_dispatch(pcap, 1000, (pcap_handler)logpkt_recv_arp_reply, (u_char *)&ctx) < 0) { printf("Error in pcap_dispatch(): %s\n", pcap_geterr(pcap)); break; } } else { printf("Error writing arp packet: %s", libnet_geterror(libnet)); break; } sleep(1); } while(ctx.result == -1 && --count > 0); if(ctx.result == 0) { memcpy(dst_ether, &ctx.ether, ETHER_ADDR_LEN); // log_dbg_printf("Mirror target is up: " // "%02x:%02x:%02x:%02x:%02x:%02x\n", // dst_ether[0], dst_ether[1], dst_ether[2], // dst_ether[3], dst_ether[4], dst_ether[5]); } out3: pcap_freecode(&bp); out2: pcap_close(pcap); out: libnet_clear_packet(libnet); return ctx.result; } #endif /* !WITHOUT_MIRROR */ /* vim: set noet ft=c: */ ssldump-1.9/pcap/logpkt.h000066400000000000000000000057051470411077700154650ustar00rootroot00000000000000/*- * SSLsplit - transparent SSL/TLS interception * https://www.roe.ch/SSLsplit * * Copyright (c) 2009-2019, Daniel Roethlisberger . * 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 COPYRIGHT HOLDER 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 COPYRIGHT HOLDER 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. */ #ifndef LOGPKT_H #define LOGPKT_H #include "attrib.h" #include #include #include #ifndef WITHOUT_MIRROR #include #else /* WITHOUT_MIRROR */ #define libnet_t void #define ETHER_ADDR_LEN 6 #endif /* WITHOUT_MIRROR */ typedef struct { libnet_t *libnet; uint8_t src_ether[ETHER_ADDR_LEN]; uint8_t dst_ether[ETHER_ADDR_LEN]; struct sockaddr_storage src_addr; struct sockaddr_storage dst_addr; uint32_t src_seq; uint32_t dst_seq; size_t mss; uint32_t timestamp_sec; uint32_t timestamp_usec; } logpkt_ctx_t; #define LOGPKT_REQUEST 0 #define LOGPKT_RESPONSE 1 int logpkt_pcap_open_fd(int fd) WUNRES; void logpkt_ctx_init(logpkt_ctx_t *, libnet_t *, size_t, const uint8_t *, const uint8_t *, const struct sockaddr *, socklen_t, const struct sockaddr *, socklen_t, const uint32_t *, const uint32_t *); int logpkt_write_payload(logpkt_ctx_t *, int, int, const unsigned char *, size_t) WUNRES; int logpkt_write_close(logpkt_ctx_t *, int, int); int logpkt_ether_lookup(libnet_t *, uint8_t *, uint8_t *, const char *, const char *) WUNRES; #endif /* !LOGPKT_H */ ssldump-1.9/pcap/pcap_logger.c000066400000000000000000000112161470411077700164340ustar00rootroot00000000000000 #include #include #ifndef __OpenBSD__ #include #endif #include #include #include #include "network.h" #include "proto_mod.h" #include "debug.h" #include "pcap_logger.h" #include "logpkt.h" #define DFLT_FILEMODE 0666 static int init_pcap_logger PROTO_LIST((void *data)); static int deinit_pcap_logger PROTO_LIST(()); static int create_pcap_logger PROTO_LIST((proto_obj * *objp, struct sockaddr_storage *i_addr, u_short i_port, struct sockaddr_storage *r_addr, u_short r_port, struct timeval *base_time)); static int destroy_pcap_logger PROTO_LIST((proto_obj * *objp)); static int data_pcap_logger PROTO_LIST( (proto_obj * _obj, unsigned char *data, unsigned int len, int dir)); static int close_pcap_logger PROTO_LIST( (proto_obj * _obj, unsigned char *data, unsigned int len, int dir)); int pcap_fd = -1; static uint8_t content_pcap_src_ether[ETHER_ADDR_LEN] = {0x02, 0x00, 0x00, 0x11, 0x11, 0x11}; static uint8_t content_pcap_dst_ether[ETHER_ADDR_LEN] = {0x02, 0x00, 0x00, 0x22, 0x22, 0x22}; static int init_pcap_logger(void *data) { char *pcap_outfile = (char *)data; pcap_fd = open(pcap_outfile, O_RDWR | O_CREAT, DFLT_FILEMODE); if(pcap_fd == -1) { // printf("Failed to open pcap '%s' for writing\n", pcap_outfile); return -1; } if(logpkt_pcap_open_fd(pcap_fd) == -1) { // printf("Failed to prepare '%s' for PCAP writing\n", pcap_outfile); close(pcap_fd); pcap_fd = -1; return -1; } return 0; } static int deinit_pcap_logger(void) { #if defined(_POSIX_SYNCHRONIZED_IO) && (_POSIX_SYNCHRONIZED_IO > 0) fdatasync(pcap_fd); #else fsync(pcap_fd); #endif close(pcap_fd); return 0; } static int create_pcap_logger(proto_obj **objp, struct sockaddr_storage *i_addr, u_short i_port, struct sockaddr_storage *r_addr, u_short r_port, struct timeval *base_time) { int _status; logpkt_ctx_t *pcap_obj = 0; struct sockaddr_in src_addr, dst_addr; uint32_t timestamp_sec, timestamp_usec; timestamp_sec = base_time->tv_sec; timestamp_usec = base_time->tv_usec; if(!(pcap_obj = (logpkt_ctx_t *)calloc(1, sizeof(logpkt_ctx_t)))) ABORT(R_NO_MEMORY); // src_addr.sin_family = AF_INET; // src_addr.sin_addr = *i_addr; memcpy(&src_addr, i_addr, sizeof(struct sockaddr_in)); src_addr.sin_port = htons(i_port); // dst_addr.sin_family = AF_INET; // dst_addr.sin_addr = *r_addr; memcpy(&dst_addr, r_addr, sizeof(struct sockaddr_in)); dst_addr.sin_port = htons(r_port); logpkt_ctx_init(pcap_obj, NULL, 0, content_pcap_src_ether, content_pcap_dst_ether, (const struct sockaddr *)&src_addr, sizeof(src_addr), (const struct sockaddr *)&dst_addr, sizeof(dst_addr), ×tamp_sec, ×tamp_usec); *objp = (proto_obj *)pcap_obj; _status = 0; abort: if(_status) { destroy_pcap_logger((proto_obj **)&pcap_obj); } return _status; } static int destroy_pcap_logger(proto_obj **objp) { logpkt_ctx_t *pcap_obj; if(!objp || !*objp) return 0; pcap_obj = (logpkt_ctx_t *)*objp; free(pcap_obj); *objp = 0; return 0; } static int data_pcap_logger(proto_obj *_obj, unsigned char *data, unsigned int len, int dir) { logpkt_ctx_t *pcap_obj = (logpkt_ctx_t *)_obj; int direction; int status; if(dir == DIR_I2R) direction = LOGPKT_REQUEST; else direction = LOGPKT_RESPONSE; status = logpkt_write_payload(pcap_obj, pcap_fd, direction, data, len); return status; } int close_pcap_logger(proto_obj *_obj, unsigned char *data, unsigned int len, int dir) { logpkt_ctx_t *pcap_obj = (logpkt_ctx_t *)_obj; int direction; int status; if(dir == DIR_I2R) direction = LOGPKT_REQUEST; else direction = LOGPKT_RESPONSE; status = logpkt_write_close(pcap_obj, pcap_fd, direction); return status; } static struct logger_mod_vtbl_ pcap_vtbl = { init_pcap_logger, deinit_pcap_logger, create_pcap_logger, destroy_pcap_logger, data_pcap_logger, close_pcap_logger, }; struct logger_mod_ pcap_mod = {"PCAP", &pcap_vtbl}; ssldump-1.9/pcap/pcap_logger.h000066400000000000000000000001231470411077700164340ustar00rootroot00000000000000#ifndef _pcap_logger_h #define _pcap_logger_h extern logger_mod pcap_mod; #endif ssldump-1.9/pcap/sys.c000066400000000000000000000052711470411077700147740ustar00rootroot00000000000000/*- * SSLsplit - transparent SSL/TLS interception * https://www.roe.ch/SSLsplit * * Copyright (c) 2009-2019, Daniel Roethlisberger . * 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 COPYRIGHT HOLDER 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 COPYRIGHT HOLDER 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. */ #include "sys.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* * Determine address family of addr */ int sys_get_af(const char *addr) { if(strstr(addr, ":")) return AF_INET6; else if(!strpbrk(addr, "abcdefghijklmnopqrstu" "vwxyzABCDEFGHIJKLMNOP" "QRSTUVWXYZ-")) return AF_INET; else return AF_UNSPEC; } static int sys_rand_seeded = 0; static void sys_rand_seed(void) { struct timeval seed; if(gettimeofday(&seed, NULL) == -1) { srandom((unsigned)time(NULL)); } else { srandom((unsigned)(seed.tv_sec ^ seed.tv_usec)); } sys_rand_seeded = 1; } uint16_t sys_rand16(void) { if(unlikely(!sys_rand_seeded)) sys_rand_seed(); return random(); } uint32_t sys_rand32(void) { if(unlikely(!sys_rand_seeded)) sys_rand_seed(); return random(); } /* vim: set noet ft=c: */ ssldump-1.9/pcap/sys.h000066400000000000000000000033101470411077700147710ustar00rootroot00000000000000/*- * SSLsplit - transparent SSL/TLS interception * https://www.roe.ch/SSLsplit * * Copyright (c) 2009-2019, Daniel Roethlisberger . * 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 COPYRIGHT HOLDER 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 COPYRIGHT HOLDER 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. */ #ifndef SYS_H #define SYS_H #include "attrib.h" #include #include #include int sys_get_af(const char *); uint16_t sys_rand16(void); uint32_t sys_rand32(void); #endif /* !SYS_H */ /* vim: set noet ft=c: */ ssldump-1.9/samples/000077500000000000000000000000001470411077700145265ustar00rootroot00000000000000ssldump-1.9/samples/log.txt000066400000000000000000000156001470411077700160520ustar00rootroot00000000000000SERVER_HANDSHAKE_TRAFFIC_SECRET 1ba4a034638a63221f55e3e684fa4e6a5bbbb9f9711c035e23441810b82667c8 aa87c1bd965ea9e1361d15e7fd671792980da373f34e4eefe1fd21effbd65a80 CLIENT_HANDSHAKE_TRAFFIC_SECRET 1ba4a034638a63221f55e3e684fa4e6a5bbbb9f9711c035e23441810b82667c8 533b0dcc030ecac8feace33031a405f5e05ecd0d7c7e64a6e30fa7bbee9bb813 EXPORTER_SECRET 1ba4a034638a63221f55e3e684fa4e6a5bbbb9f9711c035e23441810b82667c8 027a31d81dfa560205e25a50740b13dc7ce6f5c18004dac45e2b68517c0a75e1 SERVER_TRAFFIC_SECRET_0 1ba4a034638a63221f55e3e684fa4e6a5bbbb9f9711c035e23441810b82667c8 15f1d79f92d5b5cc15a1ebb67c39bfc4cce4934aac2722fb89a0e055c81c562e CLIENT_TRAFFIC_SECRET_0 1ba4a034638a63221f55e3e684fa4e6a5bbbb9f9711c035e23441810b82667c8 e7cd79a7d0bd712d966261ddc5a7eec31b1e9d5cff667843eafa7e01348d1dcc SERVER_HANDSHAKE_TRAFFIC_SECRET 1ca51d8032bbf6e0748bc3852de83b111463295f913ea8a0695ee384a4503848 53f1bfdfbc44559025a6562937995d9406033304bf59a457e1b1eb817f530e16 CLIENT_HANDSHAKE_TRAFFIC_SECRET 1ca51d8032bbf6e0748bc3852de83b111463295f913ea8a0695ee384a4503848 b8412c25f615a5674f51817604e28b8bf70b269007c05cd408b1a24cfaa9a936 EXPORTER_SECRET 1ca51d8032bbf6e0748bc3852de83b111463295f913ea8a0695ee384a4503848 fb2e70cca12d1e15534b3c2b6b67b85a2a148ee4318922451bc2d7cc768a4c91 SERVER_TRAFFIC_SECRET_0 1ca51d8032bbf6e0748bc3852de83b111463295f913ea8a0695ee384a4503848 17e8205e0f334bd5c34c9b73e7f791386f3c8e3316d3bdf133d8227380555109 CLIENT_TRAFFIC_SECRET_0 1ca51d8032bbf6e0748bc3852de83b111463295f913ea8a0695ee384a4503848 eaedfbfff17ffe92267845cda264104c3ba8da6d6d10a1233ef388bfb8bbbf2d SERVER_HANDSHAKE_TRAFFIC_SECRET 2e78ab0ab702be305ae81cf0886bc93d09967eb60d9a1d837677c0af52b88c89 91e7f391b276856033a47e458e1d64bf81d08a3292ff30aa582bcbd140d764cc8626c16742ebd6d9a7f500a68aeb5ebb CLIENT_HANDSHAKE_TRAFFIC_SECRET 2e78ab0ab702be305ae81cf0886bc93d09967eb60d9a1d837677c0af52b88c89 ef2ac5e176b3e5713a6c205790e3b58b12b64cc4628fbb6ac0b12273a73be6e6913a0556f823eebe12c4e42199bfbcc6 EXPORTER_SECRET 2e78ab0ab702be305ae81cf0886bc93d09967eb60d9a1d837677c0af52b88c89 ad46dd23b08dd4135c63f3291953254977a7526630d3cc9455d8da59eb5cf712cf671d9970dad31f1c793617a60c6f99 SERVER_TRAFFIC_SECRET_0 2e78ab0ab702be305ae81cf0886bc93d09967eb60d9a1d837677c0af52b88c89 3f4de0cda8b51bf7533e12279bebd1062459700be861c1a951e4224652872aec2162bd2b8ae16a3a16fe580aa941e6ff CLIENT_TRAFFIC_SECRET_0 2e78ab0ab702be305ae81cf0886bc93d09967eb60d9a1d837677c0af52b88c89 7ea195809a87dc2b3af3f1a1f0317a4f5d51d0e26012e59bc2aeba8c867c0ab735140853234354feb6adc49ea24714b8 SERVER_HANDSHAKE_TRAFFIC_SECRET 172f0e36bede6f9f78157e8e338ee8b5d501a0c264a7c248d4d2092283badd19 574e234b9ed1fe38053194bd7641126bde6e0e005ce33162d5743ab34a99327fce670b1fa134caf943dfbc0a5d686ecc CLIENT_HANDSHAKE_TRAFFIC_SECRET 172f0e36bede6f9f78157e8e338ee8b5d501a0c264a7c248d4d2092283badd19 838049b240d1ae3a80ff4ff0268e248588ec6913f4caae68dfeaf4ea03f330bcab4606d1bee74d299be6c800b2671595 EXPORTER_SECRET 172f0e36bede6f9f78157e8e338ee8b5d501a0c264a7c248d4d2092283badd19 13965d7ae6d230cee91ebe990c07e7d5ca46ed40a6924a91bf60901618226a88d606fb5467827cd1d3765fa827476a50 SERVER_TRAFFIC_SECRET_0 172f0e36bede6f9f78157e8e338ee8b5d501a0c264a7c248d4d2092283badd19 da4c9bb2d82ce66a35ec5899a9f7bf67e2f24e2b190f9cabc94dd56bfdbf39f54d001da93120554293f711972f03fb16 CLIENT_TRAFFIC_SECRET_0 172f0e36bede6f9f78157e8e338ee8b5d501a0c264a7c248d4d2092283badd19 f7f968b5b7eee2b521cda8575822bfdb2887913764a08e35648a26ab4ff98aad230b192ae6b376701395575a372c1c3e SERVER_HANDSHAKE_TRAFFIC_SECRET 4b038c23f532ba8c893ead81d1f07f1681e4d18987b65333408e20957fde7e71 9eb2c91bcc6e0864c364858e0864d041c52f41ca3ce396d128d4fb5dc386ac00 CLIENT_HANDSHAKE_TRAFFIC_SECRET 4b038c23f532ba8c893ead81d1f07f1681e4d18987b65333408e20957fde7e71 8577431055b2a50669270c3bf08aaf32dc7dd66a7e9a5efbeb93677db231fd72 EXPORTER_SECRET 4b038c23f532ba8c893ead81d1f07f1681e4d18987b65333408e20957fde7e71 6a58ac33631d88787f62a919a8f0d2b6c0f8d03075aeb04b880ce2330cb9b2fc SERVER_TRAFFIC_SECRET_0 4b038c23f532ba8c893ead81d1f07f1681e4d18987b65333408e20957fde7e71 243d0b750befa5d25af82ea4d5eaacf7f52c5343dc260f75344dcaadc69544b3 CLIENT_TRAFFIC_SECRET_0 4b038c23f532ba8c893ead81d1f07f1681e4d18987b65333408e20957fde7e71 0a921480912454ce03a14c5eeb75ae44c7c9a82a883eb632e7279cbdab3d1188 SERVER_HANDSHAKE_TRAFFIC_SECRET 169637b581d83e615cee48ae69fd0d810f24e8855dac989600b48fac970c36d9 182ed636bf590c245fea0ad4b04d9b2304bb30279e1a2f7bfef16861d13e2462 CLIENT_HANDSHAKE_TRAFFIC_SECRET 169637b581d83e615cee48ae69fd0d810f24e8855dac989600b48fac970c36d9 1e4ad1aaddf8a4f64f35859461df54d193d1cd081845a422ef44d71f5ca71f71 EXPORTER_SECRET 169637b581d83e615cee48ae69fd0d810f24e8855dac989600b48fac970c36d9 23136badd3a8975b1ceea1b4d9523055cbe296dfe75596b1e90ab6f0b7100350 SERVER_TRAFFIC_SECRET_0 169637b581d83e615cee48ae69fd0d810f24e8855dac989600b48fac970c36d9 e15200b68d7f703abe7b04165c8885566d90c4dd509c7d174dc4c2cf130cf4d2 CLIENT_TRAFFIC_SECRET_0 169637b581d83e615cee48ae69fd0d810f24e8855dac989600b48fac970c36d9 c5fef93efea3e4a24499a408af7e3de26411738cf25063c9efaad9b8d045487d SERVER_HANDSHAKE_TRAFFIC_SECRET 86c98dd9032df8ef2e6f74b4396c2c2acd8da6f35406412400f9da8d2b48ffbc 783799f80f8d03250acd957dac465e0cb95a5c3b5a1adf4b928a8bceda57246c9d722d02675504a512d7800ebd21f7c0 EXPORTER_SECRET 86c98dd9032df8ef2e6f74b4396c2c2acd8da6f35406412400f9da8d2b48ffbc 363ac8e9af29c6063792ca3e2bc7301b6cbbbfbe646f82254a843528ff708846ea934d55b4e37d8b22797f842c4b5aad SERVER_TRAFFIC_SECRET_0 86c98dd9032df8ef2e6f74b4396c2c2acd8da6f35406412400f9da8d2b48ffbc f5402ccfccbf4a46844be1f356931700bb5881ad4dfd07fe57e7330afdfeac08a753035684ffb2b48f504ae836fca1c5 CLIENT_HANDSHAKE_TRAFFIC_SECRET 86c98dd9032df8ef2e6f74b4396c2c2acd8da6f35406412400f9da8d2b48ffbc d5f5c7ac89b41eb782181a5d230c8ddf51233f6d3989b4944a95dc95924ee200fe4b1fa02b3e6cf07908c334905a8961 CLIENT_TRAFFIC_SECRET_0 86c98dd9032df8ef2e6f74b4396c2c2acd8da6f35406412400f9da8d2b48ffbc 6b37aa85b4698e4d6abfb66933e3fd4283f9fe08faee2a314ce8e1b95a245ceead2f64f4024c27e0cb4fc3c7b20f7ad5 CLIENT_RANDOM ff71dd83376f0a35a8b86e8b9f516d9938a36ec3803e48b5a256fc7cd597528d 6bf5b5d1515d70facf6f2a76c997add2a9464b5712b17ee0273dbfeaa3c1ddc7daf5ff21e552cc1ab09ad45fe815d616 SERVER_HANDSHAKE_TRAFFIC_SECRET 3c5b65efb7b4424f2f1bb4d263befa34af2fbb14058f16428ba0187586ee6973 fcb2538d16f80d242d51c0a35395169944182eb5710fb984d03c7b8df864b181642af07af807a75bc133382641ed8bd3 CLIENT_HANDSHAKE_TRAFFIC_SECRET 3c5b65efb7b4424f2f1bb4d263befa34af2fbb14058f16428ba0187586ee6973 551c476c45b74d91062991523ff7374b211575d497a41eb0902c3d8329382b51c00df6ebc461da6f2bead0a637352c09 EXPORTER_SECRET 3c5b65efb7b4424f2f1bb4d263befa34af2fbb14058f16428ba0187586ee6973 e4c4e35876208551f3f3db9916db2841e2c81b730e9815e52c319ca82e718cad579e351fee75b7a94181419f83d705a2 SERVER_TRAFFIC_SECRET_0 3c5b65efb7b4424f2f1bb4d263befa34af2fbb14058f16428ba0187586ee6973 035eed62f0d1ff88326220347fbb3e60e4ee76c99b3a73415f55af9d5cb0d7a2e73e0faa29097acd718fea92c811558e CLIENT_TRAFFIC_SECRET_0 3c5b65efb7b4424f2f1bb4d263befa34af2fbb14058f16428ba0187586ee6973 869488a30d316752c049f2704315bd505f2aa59c608f20867bc9adce929aa25a774500214a0bc06c34dc6774add3b82a ssldump-1.9/samples/tls1.2_aes256.pcap000066400000000000000000000066241470411077700175130ustar00rootroot00000000000000òed JJEHV|՗R8,0̨̩̪+/$(k#'g 9 3=<5/d 127.0.0.1  # *(   ed BBE49@@Q`sG|( ed> E9@@4Q`sG| A="|y Ƥ&:Uµi, # 00YȚaL)};`9F0 *H=0Y1 0 UAU10U Some-State1!0U Internet Widgits Pty Ltd10U localhost0 220526110308Z 230526110308Z0Y1 0 UAU10U Some-State1!0U Internet Widgits Pty Ltd10U localhost00*H=+#U_wn%}rn=5g-2,Wf't({HDov:_ P D>CZq4je5$!qs[do]JK3!Z`2sa7˶ڰɻ|ڣS0Q0Ui|u#ٮ0U#0i|u#ٮ0U00 *H=0Bz.2>\+oNZ 4^Bޱ7EuFO7t%iQ B}l@(mfo`K( 5%u3p>o`1@iJ(3]94oY/ 4  M֖Dj-@;6!hoI @0Bdj_P2}m䦈-y d(rv#r7P#U&(4 y)A ,.zzXq"c<yd<_#VCpr|EVLE qedV BBE4q@@jPQG|`( ed] Er@@iQG|` %! ¯yʕErO˽T %Il7gY(iTAϹ'#>-37@MY(3%v_`DE"v@edp BBE49@@Q`Gـ( ed $$E9@@Q`Gـ   wA&DsYeԒϙ_H ֆG Nw7=F-)$?l n?@iSm}D玲SإvoD>s\ #l'KB'2Sѹ0/r@/pԁ(x8"tP԰LHo,Q?ed BBE4s@@jNQG`( ed^zkkE]t@@j$QG`Q S$iTA*];iiz5YTUR3$4yĊedvzBBE49@@Q`G ( SSedzkkE]9@@Q`G Q TS$x8"t Jx;zmGl?xb 3y zedzBBE4u@@jLQG `*( TTed ccEUv@@j*QG `*I TiTA#rXRi" Ǝed BBE49@@Q`*G #( ed{ ccEU9@@Q`*G #I x8"t!$yvk1VdGed BBE4w@@jJQG #`K( edBBE4x@@jIQG #`K( edaaES9@@Q`KG $G x8"t"&#bBO=Ⱥ[ed66E(@@<QG $P$ssldump-1.9/samples/tls1.3_aes128.pcap000066400000000000000000000104221470411077700175010ustar00rootroot00000000000000òc-JJE<ˆ@@q3|Ql0 ʸc-JJE<@@<Q|pbZl0 ʸʸc-BBE4ˇ@@q:|Qlpb[( ʸʸc311E#ˈ@@pJ|Qlpb[ ʺʸ7>a\Hi $] 6 Dv;iJܗW+r%]q 127.0.0.1  #    +-3&$ P>2+ B罊}{q2c43BBE4@@OQ|pb[m( ʺʺc@=||En@@KQ|pb[mc ʼʺzv:^V ugok?QK Dv;iJܗW+r%]q.+3$ 7rh~zW@yL$(sn:5s+Eگ=eӀYWd!6@<shyxMwWr{x#$x:mH=$Qn:w~1 A-r`.MVuiwŃT` F9b9XEȴ,[AٷV\X=h VJ'锪".(D!g}UŖ|7 b%G#/|z‰Pw:+٥!8hHYV# }<˜8$}f2>;[~j(HS^cs(ƅwi]xH\jz]iC&qr^‚iQWɋl `Z؈Bȼ切X9A‹Pꟈg2*z[=\A5 4f'sV -,xF{&3! wx,[حBIcU=BBE4ˉ@@q8|Qmpf( ʼʼcEEtˊ@@p|Qmpfh ʾʼ5ٴfmz5[ hC画G,GGJ{DӸ<҇cd?m)PGWZ1YT'm6"JׯVJz-@D>W0^;X$@%]bX+iZ9XC؇Q\#"|cEBBE4ˌ@@q5|QmBphs( ʿʿc ^^EPˍ@@q|QmBphsD ʿ=*c̔ BBE4 @@OQ|phsm^( c# ^^EP @@OQ|phsm^D N-&ڷ=T0i}Abc5 BBE4ˎ@@q3|Qm^ph( cU \\ENˏ@@q|Qm^phB kR5R܅ªcp BBE4@@OQ|phmx( c \\EN@@OQ|phmxB NC?l^*U^c BBE4ː@@q1|Qmxph( c]]EOˑ@@q|QmxphC fs hЪ cBBE4@@OQ|phm( c%ZZEL@@OQ|phm@ 4H ]c8BBE4˒@@q/|Qmph( cpBBE4@@OQ|phm( cZZEL˓@@q|Qmph€@ dNcf0'~_lc66E(@@<Q|phP Gssldump-1.9/samples/tls1.3_aes256gcm.pcap000066400000000000000000000123631470411077700202000ustar00rootroot00000000000000òdJJE/0^Fsx$By&+əxXг0)7)u$MKA)cH16l,|ʕG0)sA"=,+5N9#d5e.נpU e2`/5 @kry\W,3 Գ5l*D&bRbY愢7֠`&ِg$K.BIUGYhGXGu 0x\ ڲxIB!u eO&,v8Bmho|%?Mn3rʿ$"aOcԧe?w kZ̔L ;^+KjÛZDQr_ 27,,B?q7lA8\.R0i#AQbLg[1I~ɷw,vkJ 7R'm෼ -(_eSAkxrhb Ͽ$y&@[G7O(`WCRV\)KxH7+}Gڟni]9X/:Atc;eu89?k;tui_ɺOnbIkVvSA  Y~6wڦ4td*VrQ b{6:VB{1h֑"Dauiv~dSYJāi Յ;a4z)*bϵoJfjK8l-9c -gE vwCƕB v]b5vtbe$, AJ߰d0a}_`SgdcBBE4o@@nQg&E:( 9O9OdEo@@̎nQg&E:x 9Q9OEj6k9E!⮂\ms(8m1;p'L0SdBBE4t@@MQn&E:gf( 9Q9QdxAAE3u@@~MQn&E:gf' 9Q9QT{:wF0I6F+Z5KhxǗ~FP;@Cn_Ǎ賺̜/|āa![1(Ќ+w|LK"8I`'EY,'Ia7k^.=?: Ӓwփ\^O + 穩֌MeSQcYWx C*2bQd gݸr&Wg{0cQcu,r1̒d{BBE4o@@nQgf&F9( 9Q9QdAAE3v@@~LQn&F9gf' 9Q9Q% ;4r'؜ 0N30d3mD^ Obb,~s1 ش]ܢ$^$1Oĺ+L$ ݲHsykp|J1>wm+ .w~\4я(z+S *獪KI7+UBO_2}kg]Ol } -%+c'/.u}@ÅkdBBE4o@@nQgf&G8( 9Q9Qd>^^EPo@@̿nQgf&G8D H,9Q!vEYY2EidfBBE4w@@JQn&G8g( H,H,d^^EPx@@-Qn&G8gD H,H,Sm SI@ri/ܖdBBE4o@@nQg>( H-H,d_]]EOo@@̾nQg>C PrH,¶<;@܎bA)Vd{BBE4y@@HQn>g( PrPrdbbETo@@̸nQg>H PrPr owJZl{E.yn)dBBE4z@@GQn>g( PrPrd]]EO{@@+Qn>gC PrPrᢀBפzy;IdBBE4o@@nQg&Go( PrPrdbbET|@@%Qn&GogH PrPr$=rsK5Eyr8v$?d BBE4o@@nQg&G( PrPrd ^^EPo@@̹nQg&GD aPrB|}/'EE Ed BBE4}@@DQn&Ggـ( aad] ^^EP~@@'Qn&GgـD aa96i$b;bpdn BBE4o@@nQg&G( aad1]]EOo@@̸nQg&GC jJaŃo:Y$ <d2]]EO@@'Qn&GgC jJjJ^+``S*~1M>kd2BBE4o@@nQg&Gƀ( jJjJd` ]]EOo@@̶nQg&GƀC q jJz} kɍ[eG-da ZZEL@@)Qn&Gg@ q q XiFk!#da BBE4o@@nQg&Gހ( q q da ZZELo@@̷nQg&Gހ@ q q nvUYdb BBE4@@@Qn&Gg'( q q ssldump-1.9/samples/tls1.3_ccm.pcap000066400000000000000000000076261470411077700172540ustar00rootroot00000000000000òIdOJJE< p@@/JQR0 IdOJJE<@@<Q@ R0 ﷐IdOBBE4 q@@/QQR@ ( ﷐IdP11E# r@@.aQR@  ︐K#2>щS3@ ~q 䬩cza7/ݻ2 Hz4W 127.0.0.1  #    +-3&$ l1ݷEt97KIFԔ'IdPBBE4wc@@^Q@ R( ︐IdZ||Enwd@@#Q@ Rc ﺐzvՐ5GPos[vB8;fl0}}| 䬩cza7/ݻ2 Hz4W.+3$ A>~`Q^A>՘ ;;F{EÖ)l1-ܴs#! ZYɢ+'tU'3+mjiCkqҀPyoz(<} sкeX%Vb7j>ʼn=Y($,pE{IxܢĻn-Psآ>4#g2 r"! >'>Auc%OAtdXҪuUlRe$y懄y\Oq(n2Uv4Į_j ihi*buSU=?k 8,*Ri~y~7&7cPsȘ]S\XupwV3z=g5cS>|q})4ف_ oĺ,:.ǼJ[تpЏ3=!]8g DNJfFzhЖ>?g|ڮj8f9,Jp"iJn 'B] }ȅ`ވݚ[`ee5k)4~V6l=uzyuiwƵ87Elf e;(:Id[BBE4 s@@/OQRDF( ﺐIdveEt t@@/QRDFh p5 ?%qڹ/]?\Nd+@r}3o+IdeBBE4we@@\QDFR 6( pIdf11E#wf@@lQDFR 6 p)*c [J?#EN@^#|^fi+{IűE"ž'gCd^15Mu@J0]ʬ"f!z/?0  wFA*rNS3#I O*9{%vGɢV'U6NVzm+bO=:l랝zķ2]Ae48=":-x B<IdfBBE4 u@@/MQR 6E5( pIdf11E#wg@@kQE5R 6 pPGWq+1V#%1;pʁű#XKc545!=:ء.1~vj <@#Uh9ԇG;;=TXRue` mS2js׊M }}[}фs'#Kv ^J%튫hmp&l\W xfV k&΀M4iK!t&gN!6IdfBBE4 v@@/LQR 6F$( pKdذ^^EP w@@//QR 6F$D #|&v/_+ Yъ+RKdBBE4wh@@YQF$R R( ##Kd0^^EPwi@@<QF$R RD ##-?Ta~^R~o(ƌ#3Kd3BBE4 x@@/JQR RF@( ##NdAT]]EO y@@/.QR RF@C M#uPUerxog*~-cNd[TBBE4wj@@WQF@R m( MMNdTZZELwk@@>QF@R m@ MMgIlH-݌Z)]NdTBBE4 z@@/HQR mFX( MMNdTBBE4wl@@UQFXR m( MMNdUZZEL {@@//QR mFX@ MM$9[-V' 3NdU66E(@@<QFXPssldump-1.9/samples/tls1.3_ccm8.pcap000066400000000000000000000074671470411077700173470ustar00rootroot00000000000000òd JJE<@@Q/0 r:d JJE<@@<QZ/̠0 r:r:d BBE4@@Q/Z( r:r:d0 11E#@@Q/Z r;r:4cc"UNj[q^#D&g yšJ׆f`2UQx# Ѻm 127.0.0.1  #    +-3&$ Q}Rq$vǚ]ώ{0?AdG BBE4@@%QZ/滀( r;r;d \\EN@@!QZ/滀C r>r;zv/M'7C7*n:(/' > =UaIxՙ wyCe) ~Ky|?&TUOb-@t3ݻ=lL+fwB[eNqSNnsq -=dn;3mh ./,_7RƍedW/yw$0\Bm` r5ij\(1E2|M!3;Bڎ CTp N dL%抷F Zr>d zzEl@@Q/Z!` rAr>-|gubjݙ^aT`1,Sh=]E af (^N_Z/|ڢ )BN,ުzD d BBE4@@Q/Z( rArAd# ))E@@$QZ/ rArAF64à=ǻBoÐ-b)Fڑ[9"{H PD{sJF- ҍHkmҟYȜT/ߟdg?ȭZ{JO񘯥|rSe`Jo5 TA2kb .(!*{G(iomy ->Тu1#r,ca ˖cwnmc (d% BBE4@@Q/Z( rArAd$ VVEH@@Q/Z< rA{ ؘkd1d@ BBE4@@%QZ/( dt VVEH@@%QZ/< {`*` ѐdw BBE4@@Q/Z( dTTEF@@Q/Z:  I6;0ydBBE4@@%QZ/( d6TTEF@@%QZ/:  !j7뽧4dGBBE4@@Q/Z( d>WBBE4@@Q/Z( >dWRRED@@%QZ/8 >> ExM #dX66E(@@<Q/Pessldump-1.9/samples/tls1.3_chacha.pcap000066400000000000000000000103141470411077700177050ustar00rootroot00000000000000ò߆ceJJEi^ㄤP8H Ŝ0hOO=uz% 127.0.0.1  #    +-3&$ Trm˛_[uF VBfv&߆cBBE4պ@@gQZG( XX߆c!||Enջ@@bQZGc XXzv;s΄%fJvtQo#PHKhw Ŝ0hOO=uz%.+3$ OB;(ZcMWi_4fZJفK؊Poz +e#wBڈgǖ;xզhVtd {p= ;| pg1ǭ8ɾ:1_x<؂~8=}bjL~L֋gRɌtt:~o fuvPw4-AaSy2#n`ލ |n'|KB-=X8Sr^GtE.pEѥ^ƎښD3?}a wY)4S.GAy ]KU.+ UUD+s {Oua~7|q=9;9J6Rrqt5o5dž [Dy;yIQCu5;SއgT YOͯ?z."%<\q Uf- :=x0}ǘN &s'ѸXFhn-JA(O$18Gx {ْDr=$)]F>swug`-dz% 5% :uKu '%H%|AȐQ*ۉDžA>lt`EMЖ7iwrBzŨFr<1F: f('ߘ7P:w$&yt=0|&`@Yv8{_2C a 1wY-X."nQi=A3-\F ]_n{ضWc H 'gr¤in;^`N ˹.xmƌ|5a‰`!cF0?ݟrPn, @7[e EEaHƊ>y߆c!BBE4q@@˺ZQG,( XX߆c+Etq@@yZQG,h XX5DŞ:n*c&SJ/b!LA]sw>}O؝߆c+BBE4ռ@@gQZ,( XX߆c,11E#ս@@fQZ, XXꚙNwK`E8Q\z}fM`E͡,5L)V~߆sZ$\ RPO0N50L 2wuF>:m 2}Df.!0 ^33|Z_ƨj*q;7e-ae1n2J( : ;ɚWXv/߆c,BBE4q @@˸ZQ( XX߆c"-11E#վ@@fQZ XXLslbLyat"&ju[w* \E/1##AHn&kr*LcMl#6F iYS, d0'aG~qX=u68%.߆c$-BBE4q @@˷ZQ ( XXc"Q^^EPq @@˚ZQ D X X65r Xc;QBBE4տ@@gQZ ( X X cxQ^^EP@@fQZ D X X + BJuQ!l(zU tJIc{QBBE4q @@˵ZQ&( X X c\\ENq @@˚ZQ&B X&X g `RYhr^cBBE4@@gQZ&( X&X&c\\EN@@fQZ&B X&X&1+͎`]o=cBBE4q@@˳ZQ@( X&X&cK]]EOq@@˗ZQ@C XX&K~.u^ŝDcfBBE4@@fQZ@؀( XXcZZEL@@fQZ@؀@ XXW-0.JLڱ]<1cBBE4q@@˱ZQX( XXc՞ZZELq@@˘ZQX@ XXD7qP6U>-cBBE4@@fQZX( XXssldump-1.9/samples/tls1.3_curl_google.pcap000066400000000000000000000641111470411077700210030ustar00rootroot00000000000000òy'dtJJ]$%]xE<((@@l۬5(FV6wwwgooglecomy'dtJJ]$%]xE<()@@k۬5(FVwwwgooglecomy'd5wtt]x]$%Ef:705R U؁wwwgooglecomwwwgooglecom$h@ y'dXhh]x]$%EZ;7;5F6ځwwwgooglecomwwwgooglecomC$y'dIJJ]$%]xE<Y@@IێC$V|H Ky'd~JJ]x]$%E<@v"C$%Vt Ky'dBB]$%]xE4Z@@PێC$V%|@ K܁y'dJGG]$%]xE9[@@JێC$V%~E Kɍ-.ot9l,*͍TA$ڍ+H FmIɢ!nFa+C>,0̨̩̪+/$(k#'g 9 3=<5/uwww.google.com  3t h2http/1.11 *(   +-3&$ ,L3pۦPd=nؒy'dCBB]x]$%E4ֽvlC$%V Ky'dc]x]$%EVvaC$%V Kzvrt܆j9PK ŗJwq FmIɢ!nFa+C.3$ B!ÆfAom#;V!jYK<+Fg|oZ>(Z3p%~z'm1RoǍT-mwZbyG&[d>9/ ϼP\[~U^r/^$] u'\8-TvޡED*/aq͢MH&7thcM^t<эPI$RL?,N-i<7HM9 7i, 9aK !2[wnAP1ͬ8(Zd8NPwiwёnXm2|Ob:xo%i8NȴW5I%7FTynD%RaOR[f*#" @T Ҝ((ej,h}_]o,!VVٖ@Zɐ>:Ϲ.QnU's$4$"YŢMXS`֏Făn0t}r3^y_cKOi^+mnKD_Q0=( ~CT+2XN!6 Gޮ=bFi:jyp6gk}6+2:x|=%k*击Gi~3m_!ggǍbNXB`ՁAsmGQ~#(FPDKr_MRG¡nF?=ٙ~3(oGny-R2]k=ԑs߾fhC TqSڄX&eS֎J}giznS` cS,j [csh_1w1 }d$CgPHM}oE9V,PaX%PYjV01ۨZ>sT6rLH)uM([DEQ537~:SxIqߎJmZj;o֍tT\P D5 0Waܰ @#m[;㛕IJm B  >JJI'$RY7& OžA@wr^|NxFӰ!B)Ƅ)Nq)qaIڌq/vIU6'cy`4 ĉ rgBU TMr# (#֊CmXBT#\bXxItnЃ?N5..Y9g1,.Ҟ+3,SG2c<}DLLI=1&OU0qsy=deḙ̌gVRO( AoSلw. nF))6^3tN~yկA) SvJHFRAOerb% Zmmh_XW3Bh(*wEBkűfEέ⵮X$/|\]#d>ZPYgѿHk0ijA)x>f5̎f;Tuw&3C~!yL$ʪRRF]9n*{aY;}z!wm[7L#̑"~ټ`e0cAGAPo#&9qҜohAm80J<=fdZjO;4S]/5هkm@[%AJǷ|\ȰD\wȮAstj]Hy~7C) d9M]Ř"]&E6W:.VY)JJX`%HGh[%;0$ ׂ.qu\J-|pKwk!&.) nO^G Afo~wo0-޲Ƃ<hnwyrf v yzufu'~ud EسO^Fx-7&;F6e(A] lak3P-)!=k=WƖb4EhH@b=_&4r MlگTƗ 1l1=.0L)&1( n{RՐh lSW :wRpLT Կu (2t.afPHk49 ww[c!]y'dc]x]$%EvC$6aV Kf$&c2̺ !HȬd跴?9@foqܛ:?H256%ZHK:M-"Agio.Fi08y'd\f]$%]xE_@@ێC$VJ6ɀ| K )oL9G[&wzy'df]$%]xE`@@ێC$V6ɀ| K 2R"6W_Q ;q0qoN[9$C!A{ո׼ M>*%[T}]@skk}=+辦y'dP]x]$%EvߎC$6V ? KE-xzD\{{M_ukɨɶlxBwݽFnEU`YYS`Kh?eTiI.:S-ŇtlE_밹vA^І1]Q /99v' .{͔rsE|N`Hsc!i^:9ԝ{RZwfn rLnqTnS`4F6YsGR69R(A/Qklg-**Nc= (iN|>x[;y94S樍EbeWA5hDGH},_`0=̠'ls!ۘ@GfY HƸItxu % c*;ӳiє/a6`;!MڒOOn1JkKc2sg[z@ -.y;1mLI]ub@y5*>3! & ڗ,3^1t;T%Ep"g#s-$bo1rm+,txqu$5Sq;i_Ȫob9ǷZy-+?O-wlU.p"oc6 v_xCf -Է"Ɛ=<~D"Ž$@Ή_ѲДoH4 koxEy{Yr0v.[ƂGRB`G>%dc#Cj&AQߟΛMsoՂ@-Oі9ӛnHE!wrF&'P:AQU%E5ebɂժomѽ6>l ,KUxS$W5S4mU)m4%9Ҥ 2.?۪ŪCqk2{oyۏּ:ll`g+Sg':_M/ H0N{p<j3;?Ԁ"2إF@$P?'  oyr'dV.[pUsZFe.Iz+܁de ]GDy~?d-r>05'vy4'EU%*vKxaQλ,>Ձ Oм}}-[2(:hCjѦN4e=BƷ1remkvH3O>KtR}-Z0B>:/:hݏ*)`s 6ѝuhTXR5Lj&*#n .I#P" 'eu  H9 ^>Rls-jҤL7A$7ٹF1`0t݌Na/Kok?Z4hRѠ1^-ƻn]jg?ۗ}RW%T3'V#S;'u ^NA'C%T2p,5<ˌUD&;AtT؈9aYGfr%c~l+a+>ߞ/L2ZJ&sטu}R^Is.&QalCric͏%f۴Ŋs-2 3'd_K(N%2 ߮Zs(d Ʀk'F 'T Uݫ,TFux+%&VwSndzM[,f'r&f}S1v[y% ?%gҊ.}Dc m :5p>UBNjf4&H%36xBHwJ-Mk 0YyG{|g&*ڙsH3x' Vjo\'Jv!(g2G<0jS9IS<#{g4F>^(*:=l0UbQ}ܸ^fd_唒iq$d5ǵIԜ\vWi]2$Nc|WN;(=!tQi kJ4W;7ri-:TX] *KZP N_Q3̨Da4a2!6M@p.TP(?A vؽƾ7Ijt\;0 GF Vh7q_?Nb"D܂Wnf;ca#*NfmX,]v,dw& ~r![%wCjJ颠1cqT8t=sJ,8릩6)J57̻̀ 5RZc|ړ+ 0^kr]1GPp ^UH 7#siIh37bK$ł(=D(L@&xUSVfQzP;n|ŒsSbe8u(šY`SyћhXA;'tlp'5k*i\ۋ`DEI>k1biIdytB;\9{atHR#&16yV{- qk]G18 MV|MEK|$ztۣFc)6Ly^|6m“Vb+IlƂTYxkKӭoIewTSl{[eH|lhņRֱs =f8rm|Sdzps5M̐O`;Uʼ/QC 뽆0rjלu-9~{XH4cwՓ$)BK`Y8ʢb`v6kXn~%@=.^7;7sd1vh)ˆy ̙uQcʴ5~!ODQ@s ;RfwxK!Q^hdRz-Ƈ1+uF%~! "o$>HsGO9/+|X4u dJb(cSF+ԿP.rh.\[&!q[aӸJ`/&eӂqcuGUFR}xg+iZ?.5Դv 4|ϳ{1idT!J-RFRUTNBSՀQhAƀopɛ>NohƿSCJ$mզ:>%YIuBVSN"tfط/

zҶ>$_`-aŧq 9pt.z&%^2[S|ь;|q j'Ğǂ/+r=-Pՠ ZAbi[F B](qysQI|v(FD4~ś2/1)<(` kdL6>[!RmՀzZ_f[, {~-8|%mC*19h{ L {tjwkHfkh]=y vG[(v+*iNM5;U}s7%"E'U=A5pX>5~-S; E?H!~lN,y\ҝIxlw!+^$\W!&fTՄ۾\ꎦ0[VPa):k_"ZS:z9jG -35MCPkL6 ūn] sqQ@5ZGl_, Trݿjcǡ9x({m\23~a1KOM(F|5RH=Z?v1C2u^gp-ıu+q$>}M1a.ܿ "sMtV/˝pMTs;?oFMd:v W˦M$J~ gl%/ )j8W\dn\tF eqCW옇PN$b euaS)=}^WvxwJпTb@i&GxeQ?" Wvڇa~dαm;]Q jhb?hih̶h6P2wmOtr/"d!"`/=zli8k!ȪRg#/OhI!͹>'ZN̻(eIz:ǝ$JOTO 1hB,s2';$jBZHrtмV.d?\2ea6'zo:ՐoU'~rV"iJYs+Χg ԜUP-ۼV7rgKI7v*bD^hn3A"dŋaۻz6A+yrAl$ թuKJ4d7NeпB3hljQv25 {eՕz5kVB^-o.[XB6%):omV!'#W=` M=p8S= OlRi-o:L!ey+VS:C~xE |q޹ded'dJEAؔLqAC&9~̒9u+f]}9^rO~ϚpF7Ï7M+@奨,Y#IT&!?8v)&(/$W>$ͻLGK,GzLuuFT7qYx4=imnPK^_Ş2%*"[Kl0H2(Y`\|C[a`rK`@/ b>t^{ב6\`rYyV|*[ DbƍAS3dJos;q\e|RUu2tI"Qxݸ*C|v_ROR)&H9J'PP>k;ȗuT;_ 62$-`*]S y+x@gT;:سC?*"IqJ("Y\JФV#A Ȇ!%Hˉwd]9xף|%}]=mCi~ ho:SoZDG:tj+~#LDFy6IDlZ IZ&X[_7 '>B(b66$})H1;."_/V{]{N [".cVȴV{)WqeΈ+ Lt:{Ba[35`"{g0?چ KI+`A3I }9m[.š`mAY18cDzk۶Cy'd! BB]$%]xE4f@@DێC$V)]|@ Ky'd! 2 2 ]x]$%E $V6C$]V)0 Ks`^XR'wE+w;ˊ70 rsNjlTR HPG(g@kxR!o;W2mlCֿfzg'K HW̃51ӡP]i SKbf['o<nȠ;cOoλbk@haةOh1G۾["}=@F6.U tБ.&3`K<7'M͔ vztJ+ād]G?HɹՀ=UP;-~(6y8xnyKV^)6+T<#@$ EJR tKM= eU 2cJ(߀zQ8*ˣE-Ơ 9}4gN,2vqBJ@Za XqHuo?( fI@Q;D1ѭ(+nSWCPtM?䤟)"7-vg}N!e:FZ?SLz5o\|DOˤZq*ls"8,1uqHT0~nƤg&ti4 R 1CPmq]V<3b{H&/S8NZ=!%Sd`lD<.SWY儇n4uo"6Uq>412%ž܁es?>x'_LocD艗1y2̞_ݑNiд6,b'5ayS.Rek%^RԩG =rk-~"^LkgRD&}S?fi+@KG)C ur~"/F{eIkvT&z-Q'ZE,~ud:zwZR7G68W2\CJG^]qG/Éi5;9lTIoqlg[k=zƲ`s2vT'l648ٱa _ PN_gK@ m`nŘzޮޟJQ^f8!C^]3=U:T#Y̾} FOV]r#t*uܚ8CF#eʖݣch| !/] kmAel /}NvsSa=VV#3~}s[ /9BgͧI<`zg1^s!T,˗Aa-)Qov +k^n)Y8cbbyKUGHQ1+ǍŸŦ gfm_QHnzj~rtzM7l*1E~c=K"J{Pb9zFbzf;1[FIASbBOfЍqhZ63M:ڌȆ(ĐĂ vtƶJj4a~ZeŒ kH|O—@L׼'XStɄr UuJ >CZ3rLhQg*zz3 痄VӠ|U|ݲ1l̏vp.ldE0!{%ƒhް؜T̲__AIeF/#͌|يiHRMk:b-}(luL:Ux˭jĥAϡFesͩ'ُ&^j-KnkXtEpyDMs饉 dނL`O"pHX肤bʺ?'UZ6=|H-M79okA4QKsi&U)FkeUcVF֖\҂Xÿ|aaךG6{Tو^;|jk>"rElUTTZIAn+X= WGҠp.( 07P՝lYiX؉]xʞ|1ZOCٰf瓩hވŒu4xLzꖡIy5t7.ch)I d(1H^`StOaTG=҃s!gۅlTi?Sfp+ j. iP^NWQ<# †wV)05('`AX~*jT"ۮL@InO;*z1GGUvi$qbF0fnP >llǣTbǞdGY>ҌsFn8(,&òZE ao'@->)N1@4!,Qliœ)>>OQn-Own<] 2}{"xJ~ T1P%Zo |o3RCa>?[-WC|p,DX wf~y&gMَ͟qUdJ5<>x/OywFNFQ33-gy'd! BB]$%]xE4g@@CێC$V)h|@ Ky'd# 2 2 ]x]$%E $V6C$hV)0 Ks1Ҍ?i)Z78Jɽ:wYpR6M@%lP'LkӚӎۺ++.ԱDackd~T8~1N2oLWq +2~!?Ry&acקpgdtóN[AY 4ã0GuQ{@If&ɚXA7r1RyE?Q0CO7T cqѶKvL~,0|ϚBT5V*I03%j?W3ijzPc?/OA% K&|aZ!֖X~┮eevUx|UGN[r# 'iv5-^jux0riȀ*p, 2gV/VύVi^|F!=k}a pJDh,_EOrHpH,k mDF] s3zVsizߘ傭_wx`^0v#Xk1[s!l *z 1TS8/Lo+܌#jv%;g RE,|67؇|!ʯeǺ}8A)+ic#~}=h w%X.k U ǐz=H!7Z6ݖ8 t%NfR<.Lw޷r{k3ދ+wVq*O .YU<0p*`jXEq 耺BzQW{']W71;8sNL[mHXy b|bpq5 scpee,tLk H4f Bݴ݇|Ri7hn:3"shM0DwF"I ܭ OlX, rWQL؝sx%<Xg[㺠ҏ.kMȜgA4BȅnKxK"@M[CiKΆ ޒxsH!)3{ht%{J<+=,OOmc M2{jӟy9GW4޷Ot QeѩFM~9!Te%n{X`G&HH)0Y\avjX߼Ҵ9&厃Xm݈ԓ^d}K_u- v5 \p󉷖@pSF )4٣(ٻ%ނChZE+diێnLվ>; Ot-&XZ|Lnx MpCH8ACe K`\gͿ[@ ¾:;T&pgˈyXs2Ytt MkɛߐoVH";`F>L-j:{*Y6&jh(ՅHa*N<7r^2/no^աnYΆXj'qW.½) ,P{)jN2B>7sBDYa?! GWI缬[l͑Ϫ:RHPQ; Gm%:T`]% X6V,bp9$y{'Abz °PF¥Bp׳cÿ mx3X;fTiB~xSTb-nٓbKOMV{/^L/?Η$_RJhH [e:E] `spo$0fZ, og>oK(NEhD N2w !p$^up9 =wv]Z߯8UHLhy0[a͘8!d'TUc6ʋ hXGo?+]bCbpWɧ8Kt %i&^8 my5P<y'd# ]x]$%E6,bC$stV)P Ks/ĉIntv.oNVK~OSA1.*" GfjJ!uCԔ|rSsD )hvEנ_νsOk>Nˏ}FK 8aBڲKȻLt⟋災n8埬es,"jH8eRO~Y2jl#[ajo.6`X&?Y ~p.gG7'~&|i*E; J3Js]ReG~>?; [N3$uk7!mQ%eǾ :ōߟnQ}FjW`IrrhXu`}r̭`VW(f22K%.Ⱦ+vk+=A|=*A_#8hKN?žĎ<0l-\ܪlKI"K(:pޗ<+6uwз|{ZȭBSUy}7c앮`).w-x5du ޤr{vA.YʾDf_ *HeNeǠVJE-tHi,vVyMY1̥2zLUd2e i!)O$q9uӝ|現T\`{!w-zuUןu.oIA^?(§+w KoMu^1%Y?[;pY@;Uޠ{#Ĭ*/@nGZ}{ρ:Cy2Pը0C1 tGmYۋ=LrkYݙD YXctM g n2dg7Q5`i'VV`:\/,\ol uJXyYEv13`F25uVݣ]JT:( |_=0~Kq*!i1V2,#"6u73.Lԫh- Rm}%W%gOjo&۾ޘCM2^3ϓ0ܵb;ZbHQ`t/IMg ~Gr{:j6~D@ vTI+=ABs,m22eIWNeVsS`ar鹚W,IaGreA-$O& iw4nUXGyjq@3!a38Qh[%]8S>;\eK^ :fr9Mj;G R+4sLtbIwMI'Ó,iBDy'd# BB]$%]xE4h@@BێC$V)st|@ Ky'd0# BB]$%]xE4i@@AێC$V)x|@ Ky'd& ]x]$%E6,C$xV) K$[}Еdh-:NRIv̍3];4Prʠel#]*N;cp ]&<~shMQWr&U>_؟eYT ³nYQJkլ©}=>QCk?gulxT=_Pjk.zf̱ ႔qW1-4Ɓ+(""~;A/I'<_tRC1䏜%0K֝Ջ+& ]6l57 0`+!/xGC)/̒息EN(+n0sA[e9֩Nl&dՆM=`񃥵BmR\Xer6Ƞ>VOc$Pք:g\*pT/X~7F/=RtoԚUA&7 ׈ n<^qT0뛗z0F3d4;C˗L3[Ɓ^}*~?Q8j\Gl A!3>ZgѢ?|jlo42_>a;Lj7,~QRd5_%$I!K<6ƹn5~ h13h 0AmjD)jMu+lC*p z̬ef`2ԽӁVL  X3e! +A㻌R&b{OLoXa/vqm{4U28/;b<;laiDPgo!#_M.T<W$3>@ H v P4|SEglj P2`X3qBEj/~ښ~ר35B+GjEʮ h fMDe+wOW3'~0+&Ygr4($CbB5߉{Ups' &a%IDծW6B">kWR[o9\ v}xb'/f3[y'd& BB]$%]xE4j@@@ێC$V)~:|@ KÁy'd'' ZZ]$%]xELk@@'ێC$V)~:|X KÁKl~UPI'sc>Oy'd( BB]$%]xE4l@@>ێC$VA~:|@ Kāssldump-1.9/samples/tls1.3_keyupdates_aes256.pcap000066400000000000000000000125031470411077700217430ustar00rootroot00000000000000òF d#JJE\DzquK1ZfXOv;@s}f# !L-Ζm<Ucme\hb"->"8D[pV6 [Ys+&9kH6 L IGRuhdhК/vp)Ih#m瀎&P7jokΏ#?-h{e&]Dj{Z lHÑt-%cԦ]Bō s+: NΆDDNXP|b:S{ Yryhighi}dihuKS|תzhNϧ׽H72 :<} Mi sgp-88QnS,C+$53%SeW)S&i`u5[v齳xKQQك]8J"vr[@4%4\]QR KUnRN<#cU쑃Z\VOG$i3Kѭ 0[b/u.Ezheum`/+VYv] Shޠ iD8V=)(!ι0j$xI|s a;PG3)fm¡.r#F dFBBE4l@@Q D}( FFF dFAAE3@@3QD} ' FF-7+YZ)D @3Hۤ妢t ぶkConXR5,xXAzzjمcy~\2{|\D6󯿱4.2)hжW)\byg N|TT:F? JI dCABBE4@@.QE ߀( FFI dxA]]EO@@QE ߀C FFZ93_5]sH5ܒI dABBE4l@@Q E( FFI dAbbET@@ QE ߀H FFU E'Vwmgi0SH逼fI dABBE4l@@Q EӀ( FFL d)^^EPl@@Q EӀD FFJH=c#;)o9L dEBBE4@@+QE ( FFL d^^EP@@QE D FF-!I2¨L dBBE4l@@Q E( FFL d\\\ENl@@Q EB F-F|\ƒ5o%Q6L d\\EN@@QE B F-F-5(xg,yL dBBE4l@@Q F ( F-F-M dH]]EOl@@Q F C FF-FűnRf*dyM dzHZZEL@@QF 0@ FF _(sWX\/M dHBBE4l@@Q 0F!( FFM dHZZELl@@Q 0F!@ FF1J03(] DM dHBBE4@@'QF! H( FFM dHBBE4l@@Q HF!( FFssldump-1.9/samples/tls1.3_session_resumption.pcap000066400000000000000000000057551470411077700224630ustar00rootroot00000000000000ò](d`JJE<@@Q80 t̖](d`JJE<@@<Q]%8֠0 t̖t̖](daBBE4@@Q8]&( t̖t̖](deDDE6@@Q8]&+ t̖t̖<[eﷴBO/c4/Buis SNg^nV"Ke?Ē9mmFja) ';_00)6E10^/(B8ISj!GJ 3ca Q D ?b|#"4cHwtxzuo͸EKnk6r`T[QXl5y"t3(Ӷ(vK]ZWsy\ӞAM5/2ܷlN+*3zrE'! "7Tg拾4,TJYCFyԶU_ ,10m#1x$⢉!}#L;O^AS7f](deBBE4@@Q]&:؀( t̖t̖](dg33E%@@%Q]&:؀ t̖t̖|ޱC'M͞XS0],26CPv SNg^nc](dgBBE4@@Q:]( t̖t̖](d^iE@@tQ:]x t̖t̖E5);eώj)-tBz5rRJt۶|i7}PP&y(v(>#9JゖNj) X#ҥ](d,jBBE4@@Q;(]( t̖t̖_(d ^^EP@@Q;(]D t̡t̖v/fs>ߔ9 KO_(d BBE4@@Q];D( t̡t̡_(d% ^^EP@@Q];DD t̡t̡t>8zgs7)*w_(d( BBE4@@Q;D]2( t̡t̡a(d]]EO@@Q;D]2C ţt̡pK{;,a`AC!Yd+ta(d2BBE4@@Q]2;_( ţţa(dZZEL@@Q]2;_@ ţţfӚJPI$Sa(dBBE4@@Q;_]J( ţţa(dBBE4@@Q]J;_( ţţa(dZZEL@@Q;_]K@ ţţJg2kup0ԩda(d 66E(@@<Q]KPssldump-1.9/ssl/000077500000000000000000000000001470411077700136635ustar00rootroot00000000000000ssldump-1.9/ssl/ciphersuites.c000066400000000000000000000354761470411077700165550ustar00rootroot00000000000000/** ciphersuites.c Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: ciphersuites.c,v 1.3 2002/08/17 01:33:17 ekr Exp $ ekr@rtfm.com Tue Mar 30 17:19:56 1999 */ #include #include "sslciphers.h" static SSL_CipherSuite CipherSuites[] = { {1, KEX_RSA, SIG_RSA, ENC_NULL, 0, 0, 0, DIG_MD5, 16, 0}, {2, KEX_RSA, SIG_RSA, ENC_NULL, 0, 0, 0, DIG_SHA, 20, 0}, {3, KEX_RSA, SIG_RSA, ENC_RC4, 1, 128, 40, DIG_MD5, 16, 1}, {4, KEX_RSA, SIG_RSA, ENC_RC4, 1, 128, 128, DIG_MD5, 16, 0}, {5, KEX_RSA, SIG_RSA, ENC_RC4, 1, 128, 128, DIG_SHA, 20, 0}, {6, KEX_RSA, SIG_RSA, ENC_RC2, 8, 128, 40, DIG_SHA, 20, 1}, {7, KEX_RSA, SIG_RSA, ENC_IDEA, 8, 128, 128, DIG_SHA, 20, 0}, {8, KEX_RSA, SIG_RSA, ENC_DES, 8, 64, 40, DIG_SHA, 20, 1}, {9, KEX_RSA, SIG_RSA, ENC_DES, 8, 64, 64, DIG_SHA, 20, 0}, {10, KEX_RSA, SIG_RSA, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0}, {11, KEX_DH, SIG_DSS, ENC_DES, 8, 64, 40, DIG_SHA, 20, 1}, {12, KEX_DH, SIG_DSS, ENC_DES, 8, 64, 64, DIG_SHA, 20, 0}, {13, KEX_DH, SIG_DSS, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0}, {14, KEX_DH, SIG_RSA, ENC_DES, 8, 64, 40, DIG_SHA, 20, 1}, {15, KEX_DH, SIG_RSA, ENC_DES, 8, 64, 64, DIG_SHA, 20, 0}, {16, KEX_DH, SIG_RSA, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0}, {17, KEX_DH, SIG_DSS, ENC_DES, 8, 64, 40, DIG_SHA, 20, 1}, {18, KEX_DH, SIG_DSS, ENC_DES, 8, 64, 64, DIG_SHA, 20, 0}, {19, KEX_DH, SIG_DSS, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0}, {20, KEX_DH, SIG_RSA, ENC_DES, 8, 64, 40, DIG_SHA, 20, 1}, {21, KEX_DH, SIG_RSA, ENC_DES, 8, 64, 64, DIG_SHA, 20, 0}, {22, KEX_DH, SIG_RSA, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0}, {23, KEX_DH, SIG_NONE, ENC_RC4, 1, 128, 40, DIG_MD5, 16, 1}, {24, KEX_DH, SIG_NONE, ENC_RC4, 1, 128, 128, DIG_MD5, 16, 0}, {25, KEX_DH, SIG_NONE, ENC_DES, 8, 64, 40, DIG_MD5, 16, 1}, {26, KEX_DH, SIG_NONE, ENC_DES, 8, 64, 64, DIG_MD5, 16, 0}, {27, KEX_DH, SIG_NONE, ENC_3DES, 8, 192, 192, DIG_MD5, 16, 0}, // Missing: 44-46 {47, KEX_RSA, SIG_RSA, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0}, {48, KEX_DH, SIG_DSS, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0}, {49, KEX_DH, SIG_RSA, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0}, {50, KEX_DH, SIG_DSS, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0}, {51, KEX_DH, SIG_RSA, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0}, {52, KEX_DH, SIG_NONE, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0}, {53, KEX_RSA, SIG_RSA, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0}, {54, KEX_DH, SIG_DSS, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0}, {55, KEX_DH, SIG_RSA, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0}, {56, KEX_DH, SIG_DSS, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0}, {57, KEX_DH, SIG_RSA, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0}, {58, KEX_DH, SIG_NONE, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0}, {59, KEX_RSA, SIG_RSA, ENC_NULL, 0, 0, 0, DIG_SHA256, 32, 0}, {60, KEX_RSA, SIG_RSA, ENC_AES128, 16, 128, 128, DIG_SHA256, 32, 0}, {61, KEX_RSA, SIG_RSA, ENC_AES256, 16, 256, 256, DIG_SHA256, 32, 0}, {62, KEX_DH, SIG_DSS, ENC_AES128, 16, 128, 128, DIG_SHA256, 32, 0}, {63, KEX_DH, SIG_RSA, ENC_AES128, 16, 128, 128, DIG_SHA256, 32, 0}, {64, KEX_DH, SIG_DSS, ENC_AES128, 16, 128, 128, DIG_SHA256, 32, 0}, {65, KEX_RSA, SIG_RSA, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA, 20, 0}, {66, KEX_DH, SIG_DSS, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA, 20, 0}, {67, KEX_DH, SIG_RSA, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA, 20, 0}, {68, KEX_DH, SIG_DSS, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA, 20, 0}, {69, KEX_DH, SIG_RSA, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA, 20, 0}, {70, KEX_DH, SIG_NONE, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA, 20, 0}, {96, KEX_RSA, SIG_RSA, ENC_RC4, 1, 128, 56, DIG_MD5, 16, 1}, {97, KEX_RSA, SIG_RSA, ENC_RC2, 1, 128, 56, DIG_MD5, 16, 1}, {98, KEX_RSA, SIG_RSA, ENC_DES, 8, 64, 64, DIG_SHA, 20, 1}, {99, KEX_DH, SIG_DSS, ENC_DES, 8, 64, 64, DIG_SHA, 20, 1}, {100, KEX_RSA, SIG_RSA, ENC_RC4, 1, 128, 56, DIG_SHA, 20, 1}, {101, KEX_DH, SIG_DSS, ENC_RC4, 1, 128, 56, DIG_SHA, 20, 1}, {102, KEX_DH, SIG_DSS, ENC_RC4, 1, 128, 128, DIG_SHA, 20, 0}, {103, KEX_DH, SIG_RSA, ENC_AES128, 16, 128, 128, DIG_SHA256, 32, 0}, {104, KEX_DH, SIG_DSS, ENC_AES256, 16, 256, 256, DIG_SHA256, 32, 0}, {105, KEX_DH, SIG_RSA, ENC_AES256, 16, 256, 256, DIG_SHA256, 32, 0}, {106, KEX_DH, SIG_DSS, ENC_AES256, 16, 256, 256, DIG_SHA256, 32, 0}, {107, KEX_DH, SIG_RSA, ENC_AES256, 16, 256, 256, DIG_SHA256, 32, 0}, {108, KEX_DH, SIG_NONE, ENC_AES128, 16, 128, 128, DIG_SHA256, 32, 0}, {109, KEX_DH, SIG_NONE, ENC_AES256, 16, 256, 256, DIG_SHA256, 32, 0}, {132, KEX_RSA, SIG_RSA, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA, 20, 0}, {133, KEX_DH, SIG_DSS, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA, 20, 0}, {134, KEX_DH, SIG_RSA, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA, 20, 0}, {135, KEX_DH, SIG_DSS, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA, 20, 0}, {136, KEX_DH, SIG_RSA, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA, 20, 0}, {137, KEX_DH, SIG_NONE, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA, 20, 0}, // Missing: 138-149 {150, KEX_RSA, SIG_RSA, ENC_SEED, 16, 128, 128, DIG_SHA, 20, 0}, {151, KEX_DH, SIG_DSS, ENC_SEED, 16, 128, 128, DIG_SHA, 20, 0}, {152, KEX_DH, SIG_RSA, ENC_SEED, 16, 128, 128, DIG_SHA, 20, 0}, {153, KEX_DH, SIG_DSS, ENC_SEED, 16, 128, 128, DIG_SHA, 20, 0}, {154, KEX_DH, SIG_RSA, ENC_SEED, 16, 128, 128, DIG_SHA, 20, 0}, {155, KEX_DH, SIG_NONE, ENC_SEED, 16, 128, 128, DIG_SHA, 20, 0}, {156, KEX_RSA, SIG_RSA, ENC_AES128_GCM, 4, 128, 128, DIG_SHA256, 32, 0}, {157, KEX_RSA, SIG_RSA, ENC_AES256_GCM, 4, 256, 256, DIG_SHA384, 48, 0}, {158, KEX_DH, SIG_RSA, ENC_AES128_GCM, 4, 128, 128, DIG_SHA256, 32, 0}, {159, KEX_DH, SIG_RSA, ENC_AES256_GCM, 4, 256, 256, DIG_SHA384, 48, 0}, {160, KEX_DH, SIG_RSA, ENC_AES128_GCM, 4, 128, 128, DIG_SHA256, 32, 0}, {161, KEX_DH, SIG_RSA, ENC_AES256_GCM, 4, 256, 256, DIG_SHA384, 48, 0}, {162, KEX_DH, SIG_DSS, ENC_AES128_GCM, 4, 128, 128, DIG_SHA256, 32, 0}, {163, KEX_DH, SIG_DSS, ENC_AES256_GCM, 4, 256, 256, DIG_SHA384, 48, 0}, {164, KEX_DH, SIG_DSS, ENC_AES128_GCM, 4, 128, 128, DIG_SHA256, 32, 0}, {165, KEX_DH, SIG_DSS, ENC_AES256_GCM, 4, 256, 256, DIG_SHA384, 48, 0}, {166, KEX_DH, SIG_NONE, ENC_AES128_GCM, 4, 128, 128, DIG_SHA256, 32, 0}, {167, KEX_DH, SIG_NONE, ENC_AES256_GCM, 4, 256, 256, DIG_SHA384, 48, 0}, // Missing: 168-185 {186, KEX_RSA, SIG_RSA, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA256, 32, 0}, {187, KEX_DH, SIG_DSS, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA256, 32, 0}, {188, KEX_DH, SIG_RSA, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA256, 32, 0}, {189, KEX_DH, SIG_DSS, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA256, 32, 0}, {190, KEX_DH, SIG_RSA, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA256, 32, 0}, {191, KEX_DH, SIG_NONE, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA256, 32, 0}, {192, KEX_RSA, SIG_RSA, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA256, 32, 0}, {193, KEX_DH, SIG_DSS, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA256, 32, 0}, {194, KEX_DH, SIG_RSA, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA256, 32, 0}, {195, KEX_DH, SIG_DSS, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA256, 32, 0}, {196, KEX_DH, SIG_RSA, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA256, 32, 0}, {197, KEX_DH, SIG_NONE, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA256, 32, 0}, {4865, KEX_DH, SIG_NONE, ENC_AES128_GCM, 16, 128, 128, DIG_SHA256, 32, 0}, {4866, KEX_DH, SIG_NONE, ENC_AES256_GCM, 16, 256, 256, DIG_SHA384, 48, 0}, {4867, KEX_DH, SIG_NONE, ENC_CHACHA20_POLY1305, 64, 256, 256, DIG_SHA256, 32, 0}, {4868, KEX_DH, SIG_NONE, ENC_AES128_CCM, 16, 128, 128, DIG_SHA256, 32, 0}, {4869, KEX_DH, SIG_NONE, ENC_AES128_CCM_8, 16, 128, 128, DIG_SHA256, 32, 0}, {49153, KEX_DH, SIG_DSS, ENC_NULL, 0, 0, 0, DIG_SHA, 20, 0}, {49154, KEX_DH, SIG_DSS, ENC_RC4, 1, 128, 128, DIG_SHA, 20, 0}, {49155, KEX_DH, SIG_DSS, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0}, {49156, KEX_DH, SIG_DSS, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0}, {49157, KEX_DH, SIG_DSS, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0}, {49158, KEX_DH, SIG_DSS, ENC_NULL, 0, 0, 0, DIG_SHA, 20, 0}, {49159, KEX_DH, SIG_DSS, ENC_RC4, 1, 128, 128, DIG_SHA, 20, 0}, {49160, KEX_DH, SIG_DSS, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0}, {49161, KEX_DH, SIG_DSS, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0}, {49162, KEX_DH, SIG_DSS, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0}, {49163, KEX_DH, SIG_RSA, ENC_NULL, 0, 0, 0, DIG_SHA, 20, 0}, {49164, KEX_DH, SIG_RSA, ENC_RC4, 1, 128, 128, DIG_SHA, 20, 0}, {49165, KEX_DH, SIG_RSA, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0}, {49166, KEX_DH, SIG_RSA, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0}, {49167, KEX_DH, SIG_RSA, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0}, {49168, KEX_DH, SIG_RSA, ENC_NULL, 0, 0, 0, DIG_SHA, 20, 0}, {49169, KEX_DH, SIG_RSA, ENC_RC4, 1, 128, 128, DIG_SHA, 20, 0}, {49170, KEX_DH, SIG_RSA, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0}, {49171, KEX_DH, SIG_RSA, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0}, {49172, KEX_DH, SIG_RSA, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0}, {49173, KEX_DH, SIG_NONE, ENC_NULL, 0, 0, 0, DIG_SHA, 20, 0}, {49174, KEX_DH, SIG_NONE, ENC_RC4, 1, 128, 128, DIG_SHA, 20, 0}, {49175, KEX_DH, SIG_NONE, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0}, {49176, KEX_DH, SIG_NONE, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0}, {49177, KEX_DH, SIG_NONE, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0}, {49187, KEX_DH, SIG_DSS, ENC_AES128, 16, 128, 128, DIG_SHA256, 32, 0}, {49188, KEX_DH, SIG_DSS, ENC_AES256, 16, 256, 256, DIG_SHA384, 48, 0}, {49189, KEX_DH, SIG_DSS, ENC_AES128, 16, 128, 128, DIG_SHA256, 32, 0}, {49190, KEX_DH, SIG_DSS, ENC_AES256, 16, 256, 256, DIG_SHA384, 48, 0}, {49191, KEX_DH, SIG_RSA, ENC_AES128, 16, 128, 128, DIG_SHA256, 32, 0}, {49192, KEX_DH, SIG_RSA, ENC_AES256, 16, 256, 256, DIG_SHA384, 48, 0}, {49193, KEX_DH, SIG_RSA, ENC_AES128, 16, 128, 128, DIG_SHA256, 32, 0}, {49194, KEX_DH, SIG_RSA, ENC_AES256, 16, 256, 256, DIG_SHA384, 48, 0}, {49195, KEX_DH, SIG_DSS, ENC_AES128_GCM, 4, 128, 128, DIG_SHA256, 32, 0}, {49196, KEX_DH, SIG_DSS, ENC_AES256_GCM, 4, 256, 256, DIG_SHA384, 48, 0}, {49197, KEX_DH, SIG_DSS, ENC_AES128_GCM, 4, 128, 128, DIG_SHA256, 32, 0}, {49198, KEX_DH, SIG_DSS, ENC_AES256_GCM, 4, 256, 256, DIG_SHA384, 48, 0}, {49199, KEX_DH, SIG_RSA, ENC_AES128_GCM, 4, 128, 128, DIG_SHA256, 32, 0}, {49200, KEX_DH, SIG_RSA, ENC_AES256_GCM, 4, 256, 256, DIG_SHA384, 48, 0}, {49201, KEX_DH, SIG_RSA, ENC_AES128_GCM, 4, 128, 128, DIG_SHA256, 32, 0}, {49202, KEX_DH, SIG_RSA, ENC_AES256_GCM, 4, 256, 256, DIG_SHA384, 48, 0}, // Missing: 49203-49211 {49266, KEX_DH, SIG_DSS, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA256, 32, 0}, {49267, KEX_DH, SIG_DSS, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA256, 48, 0}, {49268, KEX_DH, SIG_DSS, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA256, 32, 0}, {49269, KEX_DH, SIG_DSS, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA256, 48, 0}, {49270, KEX_DH, SIG_RSA, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA256, 32, 0}, {49271, KEX_DH, SIG_RSA, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA256, 48, 0}, {49272, KEX_DH, SIG_RSA, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA256, 32, 0}, {49273, KEX_DH, SIG_RSA, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA256, 48, 0}, {49274, KEX_RSA, SIG_RSA, ENC_CAMELLIA128, 4, 128, 128, DIG_SHA256, 32, 0}, {49275, KEX_RSA, SIG_RSA, ENC_CAMELLIA256, 4, 256, 256, DIG_SHA384, 48, 0}, {49276, KEX_DH, SIG_RSA, ENC_CAMELLIA128, 4, 128, 128, DIG_SHA256, 32, 0}, {49277, KEX_DH, SIG_RSA, ENC_CAMELLIA256, 4, 256, 256, DIG_SHA384, 48, 0}, {49278, KEX_DH, SIG_RSA, ENC_CAMELLIA128, 4, 128, 128, DIG_SHA256, 32, 0}, {49279, KEX_DH, SIG_RSA, ENC_CAMELLIA256, 4, 256, 256, DIG_SHA384, 48, 0}, {49280, KEX_DH, SIG_DSS, ENC_CAMELLIA128, 4, 128, 128, DIG_SHA256, 32, 0}, {49281, KEX_DH, SIG_DSS, ENC_CAMELLIA256, 4, 256, 256, DIG_SHA384, 48, 0}, {49282, KEX_DH, SIG_DSS, ENC_CAMELLIA128, 4, 128, 128, DIG_SHA256, 32, 0}, {49283, KEX_DH, SIG_DSS, ENC_CAMELLIA256, 4, 256, 256, DIG_SHA384, 48, 0}, {49284, KEX_DH, SIG_NONE, ENC_CAMELLIA128, 4, 128, 128, DIG_SHA256, 32, 0}, {49285, KEX_DH, SIG_NONE, ENC_CAMELLIA256, 4, 256, 256, DIG_SHA384, 48, 0}, {49286, KEX_DH, SIG_DSS, ENC_CAMELLIA128, 4, 128, 128, DIG_SHA256, 32, 0}, {49287, KEX_DH, SIG_DSS, ENC_CAMELLIA256, 4, 256, 256, DIG_SHA384, 48, 0}, {49288, KEX_DH, SIG_DSS, ENC_CAMELLIA128, 4, 128, 128, DIG_SHA256, 32, 0}, {49289, KEX_DH, SIG_DSS, ENC_CAMELLIA256, 4, 256, 256, DIG_SHA384, 48, 0}, {49290, KEX_DH, SIG_RSA, ENC_CAMELLIA128, 4, 128, 128, DIG_SHA256, 32, 0}, {49291, KEX_DH, SIG_RSA, ENC_CAMELLIA256, 4, 256, 256, DIG_SHA384, 48, 0}, {49292, KEX_DH, SIG_RSA, ENC_CAMELLIA128, 4, 128, 128, DIG_SHA256, 32, 0}, {49293, KEX_DH, SIG_RSA, ENC_CAMELLIA256, 4, 256, 256, DIG_SHA384, 48, 0}, // Missing: 49294-49307 {-1}}; int ssl_find_cipher(int num, SSL_CipherSuite **cs) { SSL_CipherSuite *c; for(c = CipherSuites; c->number != -1; c++) { if(c->number == num) { *cs = c; return 0; } } ERETURN(R_NOT_FOUND); } ssldump-1.9/ssl/ssl.enums.c000066400000000000000000002033521470411077700157630ustar00rootroot00000000000000#include #include #include "network.h" #include "ssl_h.h" #include "sslprint.h" #include "sslxprint.h" #ifdef OPENSSL #include #endif #include "ssl.enums.h" static int decode_extension(ssl_obj *ssl, int dir, segment *seg, Data *data); static int decode_server_name(ssl_obj *ssl, int dir, segment *seg, Data *data); static int decode_ContentType_ChangeCipherSpec(ssl_obj *ssl, int dir, segment *seg, Data *data) { struct json_object *jobj; jobj = ssl->cur_json_st; json_object_object_add(jobj, "msg_type", json_object_new_string("ChangeCipherSpec")); ssl_process_change_cipher_spec(ssl, ssl->decoder, dir); if(dir == DIR_I2R) { ssl->i_state = SSL_ST_SENT_CHANGE_CIPHER_SPEC; } else { ssl->r_state = SSL_ST_SENT_CHANGE_CIPHER_SPEC; } LF; return 0; } static int decode_ContentType_Alert(ssl_obj *ssl, int dir, segment *seg, Data *data) { int r; struct json_object *jobj; if(ssl->record_encryption == REC_CIPHERTEXT) { LF; return 0; } if(data->len != 2) { fprintf(stderr, "Wrong length for alert message: %d\n", data->len); ERETURN(R_EOD); } jobj = ssl->cur_json_st; json_object_object_add(jobj, "msg_type", json_object_new_string("Alert")); P_(P_HL) { LF; SSL_DECODE_ENUM(ssl, "level", 1, AlertLevel_decoder, P_HL, data, 0); LF; SSL_DECODE_ENUM(ssl, "value", 1, AlertDescription_decoder, P_HL, data, 0); LF; } else { SSL_DECODE_ENUM(ssl, 0, 1, AlertLevel_decoder, SSL_PRINT_ALL, data, 0); SSL_DECODE_ENUM(ssl, 0, 1, AlertDescription_decoder, SSL_PRINT_ALL, data, 0); LF; } return 0; } static int decode_ContentType_Handshake(ssl_obj *ssl, int dir, segment *seg, Data *data) { extern decoder HandshakeType_decoder[]; int r; UINT4 t, l; int rs = 0; Data d; struct json_object *jobj; if(ssl->record_encryption == REC_CIPHERTEXT) { LF; return 0; } while(data->len > 0) { SSL_DECODE_UINT8(ssl, 0, 0, data, &t); SSL_DECODE_UINT24(ssl, 0, 0, data, &l); if(data->len < l) { fprintf(stderr, "Error: short handshake length: expected %d got %d\n", l, data->len); ERETURN(R_EOD); } jobj = ssl->cur_json_st; json_object_object_add(jobj, "msg_type", json_object_new_string("Handshake")); d.data = data->data; d.len = l; data->len -= l; data->data += l; P_(P_HL) { if(!rs) { LF; rs = 1; } } ssl_decode_switch(ssl, HandshakeType_decoder, t, dir, seg, &d); } return 0; } static int decode_ContentType_application_data(ssl_obj *ssl, int dir, segment *seg, Data *data) { int r; Data d; struct json_object *jobj; jobj = ssl->cur_json_st; json_object_object_add(jobj, "msg_type", json_object_new_string("application data")); SSL_DECODE_OPAQUE_ARRAY(ssl, "data", data->len, 0, data, &d); if(NET_print_flags & NET_PRINT_JSON) { json_object_object_add(jobj, "msg_data", json_object_new_string_len((char *)d.data, d.len)); } else P_(P_AD) { print_data(ssl, &d); } else { LF; } return 0; } decoder ContentType_decoder[] = { {20, "ChangeCipherSpec", decode_ContentType_ChangeCipherSpec}, {21, "Alert", decode_ContentType_Alert}, {22, "Handshake", decode_ContentType_Handshake}, {23, "application_data", decode_ContentType_application_data}, {-1}}; static int decode_HandshakeType_HelloRequest(ssl_obj *ssl, int dir, segment *seg, Data *data) { struct json_object *jobj; jobj = ssl->cur_json_st; json_object_object_add(jobj, "handshake_type", json_object_new_string("HelloRequest")); LF; return 0; } static int decode_HandshakeType_ClientHello(ssl_obj *ssl, int dir, segment *seg, Data *data) { struct json_object *jobj; jobj = ssl->cur_json_st; json_object_object_add(jobj, "handshake_type", json_object_new_string("ClientHello")); UINT4 vj, vn, cs, cslen, complen, comp, odd, exlen, ex; Data session_id, random; int r; char *ja3_fp = NULL; char *ja3_str = NULL; char *ja3_ver_str = NULL; char *ja3_cs_str = NULL; char *ja3_ex_str = NULL; char *ja3_ec_str = NULL; char *ja3_ecp_str = NULL; ssl->cur_ja3_ec_str = NULL; ssl->cur_ja3_ecp_str = NULL; extern decoder cipher_suite_decoder[]; extern decoder compression_method_decoder[]; extern decoder extension_decoder[]; LF; ssl_update_handshake_messages(ssl, data); SSL_DECODE_UINT8(ssl, 0, 0, data, &vj); SSL_DECODE_UINT8(ssl, 0, 0, data, &vn); ja3_ver_str = calloc(7, sizeof(char)); snprintf(ja3_ver_str, 7, "%u", ((vj & 0xff) << 8) | (vn & 0xff)); P_(P_HL) { explain(ssl, "Version %d.%d ", vj, vn); LF; } SSL_DECODE_OPAQUE_ARRAY(ssl, "random", 32, P_ND, data, &random); ssl_set_client_random(ssl->decoder, random.data, random.len); SSL_DECODE_OPAQUE_ARRAY(ssl, "session_id", -32, 0, data, &session_id); ssl_set_client_session_id(ssl->decoder, session_id.data, session_id.len); P_(P_HL) { if(session_id.len) exdump(ssl, "resume ", &session_id); } ssl_process_client_session_id(ssl, ssl->decoder, session_id.data, session_id.len); P_(P_HL) { SSL_DECODE_UINT16(ssl, "cipher Suites len", 0, data, &cslen); explain(ssl, "cipher suites\n"); odd = cslen % 2; if(odd) { printf("Wrong cipher suites length, fixing ...\n"); cslen -= odd; } for(; cslen; cslen -= 2) { if(ssl_decode_enum(ssl, 0, 2, cipher_suite_decoder, 0, data, &cs)) return 1; ssl_print_cipher_suite(ssl, (vj << 8) | vn, P_HL, cs); if(!ja3_cs_str) ja3_cs_str = calloc(7, 1); else ja3_cs_str = realloc(ja3_cs_str, strlen(ja3_cs_str) + 7); snprintf(ja3_cs_str + strlen(ja3_cs_str), 7, "%u-", cs); LF; } if(ja3_cs_str && ja3_cs_str[strlen(ja3_cs_str) - 1] == '-') ja3_cs_str[strlen(ja3_cs_str) - 1] = '\0'; } SSL_DECODE_UINT8(ssl, "compressionMethod len", 0, data, &complen); if(complen) { explain(ssl, "compression methods\n"); for(; complen; complen--) { SSL_DECODE_ENUM(ssl, 0, 1, compression_method_decoder, P_HL, data, &comp); LF; } } SSL_DECODE_UINT16(ssl, "extensions len", 0, data, &exlen); if(exlen) { explain(ssl, "extensions\n"); while(data->len > 0) { SSL_DECODE_UINT16(ssl, "extension type", 0, data, &ex); if(!ja3_ex_str) ja3_ex_str = calloc(7, 1); else ja3_ex_str = realloc(ja3_ex_str, strlen(ja3_ex_str) + 7); snprintf(ja3_ex_str + strlen(ja3_ex_str), 7, "%u-", ex); if(ssl_decode_switch(ssl, extension_decoder, ex, dir, seg, data) == R_NOT_FOUND) { decode_extension(ssl, dir, seg, data); P_(P_RH) { explain(ssl, "Extension type: %u not yet implemented in ssldump\n", ex); } continue; } LF; } if(ja3_ex_str && ja3_ex_str[strlen(ja3_ex_str) - 1] == '-') ja3_ex_str[strlen(ja3_ex_str) - 1] = '\0'; } ja3_ec_str = ssl->cur_ja3_ec_str; ja3_ecp_str = ssl->cur_ja3_ecp_str; if(!ja3_ver_str) { ja3_ver_str = calloc(1, 1); *ja3_ver_str = '\0'; } if(!ja3_cs_str) { ja3_cs_str = calloc(1, 1); *ja3_cs_str = '\0'; } if(!ja3_ex_str) { ja3_ex_str = calloc(1, 1); *ja3_ex_str = '\0'; } if(!ja3_ec_str) { ja3_ec_str = calloc(1, 1); *ja3_ec_str = '\0'; } if(!ja3_ecp_str) { ja3_ecp_str = calloc(1, 1); *ja3_ecp_str = '\0'; } int ja3_str_len = strlen(ja3_ver_str) + 1 + strlen(ja3_cs_str) + 1 + strlen(ja3_ex_str) + 1 + strlen(ja3_ec_str) + 1 + strlen(ja3_ecp_str) + 1; ja3_str = calloc(ja3_str_len, 1); snprintf(ja3_str, ja3_str_len, "%s,%s,%s,%s,%s", ja3_ver_str, ja3_cs_str, ja3_ex_str, ja3_ec_str, ja3_ecp_str); EVP_MD_CTX *mdctx; const EVP_MD *md; unsigned char md_value[EVP_MAX_MD_SIZE]; unsigned int md_len, i; md = EVP_get_digestbyname("MD5"); mdctx = EVP_MD_CTX_new(); EVP_DigestInit_ex(mdctx, md, NULL); EVP_DigestUpdate(mdctx, ja3_str, strlen(ja3_str)); EVP_DigestFinal_ex(mdctx, md_value, &md_len); EVP_MD_CTX_free(mdctx); ja3_fp = calloc(33, 1); *ja3_fp = '\0'; for(i = 0; i < 16; i++) { snprintf(ja3_fp + strlen(ja3_fp), 3, "%02x", md_value[i]); } json_object_object_add(jobj, "ja3_str", json_object_new_string(ja3_str)); json_object_object_add(jobj, "ja3_fp", json_object_new_string(ja3_fp)); explain(ssl, "ja3 string: %s\n", ja3_str); explain(ssl, "ja3 fingerprint: %s\n", ja3_fp); free(ja3_fp); free(ja3_str); free(ja3_ver_str); free(ja3_cs_str); free(ja3_ex_str); free(ja3_ec_str); free(ja3_ecp_str); return 0; } static int decode_HandshakeType_ServerHello(ssl_obj *ssl, int dir, segment *seg, Data *data) { int r; Data rnd, session_id; UINT4 vj, vn, exlen, ex; char *ja3s_fp = NULL; char *ja3s_str = NULL; char *ja3s_ver_str = NULL; char *ja3s_c_str = NULL; char *ja3s_ex_str = NULL; extern decoder extension_decoder[]; struct json_object *jobj; jobj = ssl->cur_json_st; json_object_object_add(jobj, "handshake_type", json_object_new_string("ServerHello")); LF; ssl_update_handshake_messages(ssl, data); SSL_DECODE_UINT8(ssl, 0, 0, data, &vj); SSL_DECODE_UINT8(ssl, 0, 0, data, &vn); ja3s_ver_str = calloc(7, sizeof(char)); snprintf(ja3s_ver_str, 7, "%u", ((vj & 0xff) << 8) | (vn & 0xff)); ssl->version = vj * 256 + vn; P_(P_HL) { explain(ssl, "Version %d.%d ", vj, vn); LF; } SSL_DECODE_OPAQUE_ARRAY(ssl, "random", 32, P_ND, data, &rnd); ssl_set_server_random(ssl->decoder, rnd.data, rnd.len); SSL_DECODE_OPAQUE_ARRAY(ssl, "session_id", -32, P_HL, data, &session_id); SSL_DECODE_ENUM(ssl, "cipherSuite", 2, cipher_suite_decoder, 0, data, &ssl->cipher_suite); P_(P_HL) { explain(ssl, "cipherSuite "); ssl_print_cipher_suite(ssl, ssl->version, P_HL, ssl->cipher_suite); } ssl_find_cipher(ssl->cipher_suite, &ssl->cs); ja3s_c_str = calloc(6, 1); snprintf(ja3s_c_str, 6, "%u", ssl->cipher_suite); P_(P_HL) LF; SSL_DECODE_ENUM(ssl, "compressionMethod", 1, compression_method_decoder, P_HL, data, 0); P_(P_HL) LF; SSL_DECODE_UINT16(ssl, "extensions len", 0, data, &exlen); if(exlen) { explain(ssl, "extensions\n"); while(data->len) { SSL_DECODE_UINT16(ssl, "extension type", 0, data, &ex); if(!ja3s_ex_str) ja3s_ex_str = calloc(7, 1); else ja3s_ex_str = realloc(ja3s_ex_str, strlen(ja3s_ex_str) + 7); snprintf(ja3s_ex_str + strlen(ja3s_ex_str), 7, "%u-", ex); if(ssl_decode_switch(ssl, extension_decoder, ex, dir, seg, data) == R_NOT_FOUND) { decode_extension(ssl, dir, seg, data); P_(P_RH) { explain(ssl, "Extension type: %u not yet implemented in ssldump,\n", ex); } continue; } LF; } if(ja3s_ex_str && ja3s_ex_str[strlen(ja3s_ex_str) - 1] == '-') ja3s_ex_str[strlen(ja3s_ex_str) - 1] = '\0'; } if(ssl->version == TLSV13_VERSION) { // tls version is known in server hello for tls1.3 hence generate keying // material here ssl_tls13_generate_keying_material(ssl, ssl->decoder); } ssl_process_server_session_id(ssl, ssl->decoder, session_id.data, session_id.len); if(!ja3s_ver_str) { ja3s_ver_str = calloc(1, 1); *ja3s_ver_str = '\0'; } if(!ja3s_c_str) { ja3s_c_str = calloc(1, 1); *ja3s_c_str = '\0'; } if(!ja3s_ex_str) { ja3s_ex_str = calloc(1, 1); *ja3s_ex_str = '\0'; } int ja3s_str_len = strlen(ja3s_ver_str) + 1 + strlen(ja3s_c_str) + 1 + strlen(ja3s_ex_str) + 1; ja3s_str = calloc(ja3s_str_len, 1); snprintf(ja3s_str, ja3s_str_len, "%s,%s,%s", ja3s_ver_str, ja3s_c_str, ja3s_ex_str); EVP_MD_CTX *mdctx; const EVP_MD *md; unsigned char md_value[EVP_MAX_MD_SIZE]; unsigned int md_len, i; md = EVP_get_digestbyname("MD5"); mdctx = EVP_MD_CTX_new(); EVP_DigestInit_ex(mdctx, md, NULL); EVP_DigestUpdate(mdctx, ja3s_str, strlen(ja3s_str)); EVP_DigestFinal_ex(mdctx, md_value, &md_len); EVP_MD_CTX_free(mdctx); ja3s_fp = calloc(33, 1); *ja3s_fp = '\0'; for(i = 0; i < 16; i++) { snprintf(ja3s_fp + strlen(ja3s_fp), 3, "%02x", md_value[i]); } json_object_object_add(jobj, "ja3s_str", json_object_new_string(ja3s_str)); json_object_object_add(jobj, "ja3s_fp", json_object_new_string(ja3s_fp)); explain(ssl, "ja3s string: %s\n", ja3s_str); explain(ssl, "ja3s fingerprint: %s\n", ja3s_fp); free(ja3s_fp); free(ja3s_str); free(ja3s_ver_str); free(ja3s_c_str); free(ja3s_ex_str); return 0; } static int decode_HandshakeType_Certificate(ssl_obj *ssl, int dir, segment *seg, Data *data) { UINT4 len, exlen, ex; Data cert; int r; struct json_object *jobj; jobj = ssl->cur_json_st; json_object_object_add(jobj, "handshake_type", json_object_new_string("Certificate")); extern decoder extension_decoder[]; LF; ssl_update_handshake_messages(ssl, data); if(ssl->version == TLSV13_VERSION) { SSL_DECODE_OPAQUE_ARRAY(ssl, "certificate request context", -((1 << 7) - 1), 0, data, NULL); } SSL_DECODE_UINT24(ssl, "certificates len", 0, data, &len); json_object_object_add(jobj, "cert_chain", json_object_new_array()); while(len) { SSL_DECODE_OPAQUE_ARRAY(ssl, "certificate", -((1 << 23) - 1), 0, data, &cert); sslx_print_certificate(ssl, &cert, P_ND); len -= (cert.len + 3); if(ssl->version == TLSV13_VERSION) { // TLS 1.3 has certificate extensions SSL_DECODE_UINT16(ssl, "certificate extensions len", 0, data, &exlen); len -= 2; while(exlen) { SSL_DECODE_UINT16(ssl, "extension type", 0, data, &ex); len -= (2 + ex); if(ssl_decode_switch(ssl, extension_decoder, ex, dir, seg, data) == R_NOT_FOUND) { decode_extension(ssl, dir, seg, data); P_(P_RH) { explain(ssl, "Extension type: %u not yet implemented in ssldump\n", ex); } continue; } LF; } } } return 0; } static int decode_HandshakeType_SessionTicket(ssl_obj *ssl, int dir, segment *seg, Data *data) { int r; UINT4 exlen, ex, val; extern decoder extension_decoder[]; SSL_DECODE_UINT32(ssl, "ticket_lifetime", P_HL, data, &val); if(ssl->version == TLSV13_VERSION) { SSL_DECODE_UINT32(ssl, "ticket_age_add", P_HL, data, &val); SSL_DECODE_OPAQUE_ARRAY(ssl, "ticket_nonce", -((1 << 7) - 1), P_ND, data, NULL); } SSL_DECODE_OPAQUE_ARRAY(ssl, "ticket", -((1 << 15) - 1), P_ND, data, NULL); if(ssl->version == TLSV13_VERSION) { SSL_DECODE_UINT16(ssl, "exlen", 0, data, &exlen); if(exlen) { while(data->len) { SSL_DECODE_UINT16(ssl, "extension type", 0, data, &ex); if(ssl_decode_switch(ssl, extension_decoder, ex, dir, seg, data) == R_NOT_FOUND) { if((r = decode_extension(ssl, dir, seg, data))) ERETURN(r); P_(P_RH) { explain(ssl, "Extension type: %u not yet implemented in ssldump\n", ex); } continue; } LF; } } } return 0; } static int decode_HandshakeType_EncryptedExtensions(ssl_obj *ssl, int dir, segment *seg, Data *data) { int r; UINT4 exlen, ex; extern decoder extension_decoder[]; SSL_DECODE_UINT16(ssl, 0, 0, data, &exlen); LF; if(exlen) { while(data->len) { SSL_DECODE_UINT16(ssl, "extension type", 0, data, &ex); if(ssl_decode_switch(ssl, extension_decoder, ex, dir, seg, data) == R_NOT_FOUND) { decode_extension(ssl, dir, seg, data); P_(P_RH) { explain(ssl, "Extension type: %u not yet implemented in ssldump\n", ex); } continue; } LF; } } return 0; } static int decode_HandshakeType_ServerKeyExchange(ssl_obj *ssl, int dir, segment *seg, Data *data) { int r; struct json_object *jobj; jobj = ssl->cur_json_st; json_object_object_add(jobj, "handshake_type", json_object_new_string("ServerKeyExchange")); LF; ssl_update_handshake_messages(ssl, data); if(ssl->cs) { P_(P_ND) { explain(ssl, "params\n"); } INDENT_INCR; switch(ssl->cs->kex) { case KEX_DH: SSL_DECODE_OPAQUE_ARRAY(ssl, "DH_p", -((1 << 15) - 1), P_ND, data, 0); SSL_DECODE_OPAQUE_ARRAY(ssl, "DH_g", -((1 << 15) - 1), P_ND, data, 0); SSL_DECODE_OPAQUE_ARRAY(ssl, "DH_Ys", -((1 << 15) - 1), P_ND, data, 0); break; case KEX_RSA: SSL_DECODE_OPAQUE_ARRAY(ssl, "RSA_modulus", -((1 << 15) - 1), P_ND, data, 0); SSL_DECODE_OPAQUE_ARRAY(ssl, "RSA_exponent", -((1 << 15) - 1), P_ND, data, 0); break; } INDENT_POP; SSL_DECODE_OPAQUE_ARRAY(ssl, "signature", -((1 << 15) - 1), P_ND, data, 0); } return 0; } static int decode_HandshakeType_CertificateRequest(ssl_obj *ssl, int dir, segment *seg, Data *data) { UINT4 len; Data ca; int r; struct json_object *jobj; jobj = ssl->cur_json_st; json_object_object_add(jobj, "handshake_type", json_object_new_string("CertificateRequest")); LF; ssl_update_handshake_messages(ssl, data); SSL_DECODE_UINT8(ssl, "certificate_types len", 0, data, &len); for(; len; len--) { SSL_DECODE_ENUM(ssl, "certificate_types", 1, client_certificate_type_decoder, P_HL, data, 0); P_(P_HL) { LF; } }; SSL_DECODE_UINT16(ssl, "certificate_authorities len", 0, data, &len); while(len) { SSL_DECODE_OPAQUE_ARRAY(ssl, "certificate_authorities", -((1 << 15) - 1), 0, data, &ca); explain(ssl, "certificate_authority\n"); INDENT_INCR; sslx_print_dn(ssl, &ca, P_HL); INDENT_POP; len -= (ca.len + 2); } return 0; } static int decode_HandshakeType_ServerHelloDone(ssl_obj *ssl, int dir, segment *seg, Data *data) { struct json_object *jobj; jobj = ssl->cur_json_st; json_object_object_add(jobj, "handshake_type", json_object_new_string("ServerHelloDone")); LF; ssl_update_handshake_messages(ssl, data); return 0; } static int decode_HandshakeType_CertificateVerify(ssl_obj *ssl, int dir, segment *seg, Data *data) { int r; UINT4 signature_type; struct json_object *jobj; jobj = ssl->cur_json_st; json_object_object_add(jobj, "handshake_type", json_object_new_string("CertificateVerify")); LF; ssl_update_handshake_messages(ssl, data); if(ssl->version == TLSV13_VERSION) { SSL_DECODE_UINT16(ssl, "signature_type", P_HL, data, &signature_type); } SSL_DECODE_OPAQUE_ARRAY(ssl, "Signature", -((1 << 15) - 1), P_HL, data, 0); return 0; } static int decode_HandshakeType_ClientKeyExchange(ssl_obj *ssl, int dir, segment *seg, Data *data) { int r; Data pms; struct json_object *jobj; jobj = ssl->cur_json_st; json_object_object_add(jobj, "handshake_type", json_object_new_string("ClientKeyExchange")); LF; ssl_update_handshake_messages(ssl, data); if(ssl->cs) { switch(ssl->cs->kex) { case KEX_RSA: if(ssl->version > 768) { SSL_DECODE_OPAQUE_ARRAY(ssl, "EncryptedPreMasterSecret", -((1 << 15) - 1), P_ND, data, &pms); } else { SSL_DECODE_OPAQUE_ARRAY(ssl, "EncryptedPreMasterSecret", data->len, P_ND, data, &pms); } ssl_process_client_key_exchange(ssl, ssl->decoder, pms.data, pms.len); break; case KEX_DH: SSL_DECODE_OPAQUE_ARRAY(ssl, "DiffieHellmanClientPublicValue", -((1 << 7) - 1), P_HL, data, 0); ssl_process_client_key_exchange(ssl, ssl->decoder, NULL, 0); } } return 0; } static int decode_HandshakeType_Finished(ssl_obj *ssl, int dir, segment *seg, Data *data) { int r; struct json_object *jobj; jobj = ssl->cur_json_st; json_object_object_add(jobj, "handshake_type", json_object_new_string("Finished")); LF; switch(ssl->version) { case 0x300: SSL_DECODE_OPAQUE_ARRAY(ssl, "md5_hash", 16, P_ND, data, 0); SSL_DECODE_OPAQUE_ARRAY(ssl, "sha_hash", 20, P_ND, data, 0); break; case 0x301: SSL_DECODE_OPAQUE_ARRAY(ssl, "verify_data", 12, P_ND, data, 0); P_(P_ND) LF; break; } ssl_process_handshake_finished(ssl, ssl->decoder, data); return 0; } static int decode_HandshakeType_KeyUpdate(ssl_obj *ssl, int dir, segment *seg, Data *data) { LF; ssl_tls13_update_keying_material(ssl, ssl->decoder, dir); return 0; } decoder HandshakeType_decoder[] = { {0, "HelloRequest", decode_HandshakeType_HelloRequest}, {1, "ClientHello", decode_HandshakeType_ClientHello}, {2, "ServerHello", decode_HandshakeType_ServerHello}, {4, "SessionTicket", decode_HandshakeType_SessionTicket}, {8, "EncryptedExtensions", decode_HandshakeType_EncryptedExtensions}, {11, "Certificate", decode_HandshakeType_Certificate}, {12, "ServerKeyExchange", decode_HandshakeType_ServerKeyExchange}, {13, "CertificateRequest", decode_HandshakeType_CertificateRequest}, {14, "ServerHelloDone", decode_HandshakeType_ServerHelloDone}, {15, "CertificateVerify", decode_HandshakeType_CertificateVerify}, {16, "ClientKeyExchange", decode_HandshakeType_ClientKeyExchange}, {20, "Finished", decode_HandshakeType_Finished}, {24, "KeyUpdate", decode_HandshakeType_KeyUpdate}, {-1}}; decoder cipher_suite_decoder[] = { // https://www.iana.org/assignments/tls-parameters/tls-parameters.txt {0, "TLS_NULL_WITH_NULL_NULL", 0}, {1, "TLS_RSA_WITH_NULL_MD5", 0}, {2, "TLS_RSA_WITH_NULL_SHA", 0}, {3, "TLS_RSA_EXPORT_WITH_RC4_40_MD5", 0}, {4, "TLS_RSA_WITH_RC4_128_MD5", 0}, {5, "TLS_RSA_WITH_RC4_128_SHA", 0}, {6, "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5", 0}, {7, "TLS_RSA_WITH_IDEA_CBC_SHA", 0}, {8, "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA", 0}, {9, "TLS_RSA_WITH_DES_CBC_SHA", 0}, {10, "TLS_RSA_WITH_3DES_EDE_CBC_SHA", 0}, {11, "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", 0}, {12, "TLS_DH_DSS_WITH_DES_CBC_SHA", 0}, {13, "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA", 0}, {14, "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", 0}, {15, "TLS_DH_RSA_WITH_DES_CBC_SHA", 0}, {16, "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA", 0}, {17, "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", 0}, {18, "TLS_DHE_DSS_WITH_DES_CBC_SHA", 0}, {19, "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA", 0}, {20, "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", 0}, {21, "TLS_DHE_RSA_WITH_DES_CBC_SHA", 0}, {22, "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA", 0}, {23, "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5", 0}, {24, "TLS_DH_anon_WITH_RC4_128_MD5", 0}, {25, "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA", 0}, {26, "TLS_DH_anon_WITH_DES_CBC_SHA", 0}, {27, "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA", 0}, {30, "TLS_KRB5_WITH_DES_CBC_SHA", 0}, {31, "TLS_KRB5_WITH_3DES_EDE_CBC_SHA", 0}, {32, "TLS_KRB5_WITH_RC4_128_SHA", 0}, {33, "TLS_KRB5_WITH_IDEA_CBC_SHA", 0}, {34, "TLS_KRB5_WITH_DES_CBC_MD5", 0}, {35, "TLS_KRB5_WITH_3DES_EDE_CBC_MD5", 0}, {36, "TLS_KRB5_WITH_RC4_128_MD5", 0}, {37, "TLS_KRB5_WITH_IDEA_CBC_MD5", 0}, {38, "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA", 0}, {39, "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA", 0}, {40, "TLS_KRB5_EXPORT_WITH_RC4_40_SHA", 0}, {41, "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5", 0}, {42, "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5", 0}, {43, "TLS_KRB5_EXPORT_WITH_RC4_40_MD5", 0}, {44, "TLS_PSK_WITH_NULL_SHA", 0}, {45, "TLS_DHE_PSK_WITH_NULL_SHA", 0}, {46, "TLS_RSA_PSK_WITH_NULL_SHA", 0}, {47, "TLS_RSA_WITH_AES_128_CBC_SHA", 0}, {48, "TLS_DH_DSS_WITH_AES_128_CBC_SHA", 0}, {49, "TLS_DH_RSA_WITH_AES_128_CBC_SHA", 0}, {50, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", 0}, {51, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", 0}, {52, "TLS_DH_anon_WITH_AES_128_CBC_SHA", 0}, {53, "TLS_RSA_WITH_AES_256_CBC_SHA", 0}, {54, "TLS_DH_DSS_WITH_AES_256_CBC_SHA", 0}, {55, "TLS_DH_RSA_WITH_AES_256_CBC_SHA", 0}, {56, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", 0}, {57, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", 0}, {58, "TLS_DH_anon_WITH_AES_256_CBC_SHA", 0}, {59, "TLS_RSA_WITH_NULL_SHA256", 0}, {60, "TLS_RSA_WITH_AES_128_CBC_SHA256", 0}, {61, "TLS_RSA_WITH_AES_256_CBC_SHA256", 0}, {62, "TLS_DH_DSS_WITH_AES_128_CBC_SHA256", 0}, {63, "TLS_DH_RSA_WITH_AES_128_CBC_SHA256", 0}, {64, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", 0}, {65, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA", 0}, {66, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA", 0}, {67, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA", 0}, {68, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA", 0}, {69, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA", 0}, {70, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA", 0}, {103, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", 0}, {104, "TLS_DH_DSS_WITH_AES_256_CBC_SHA256", 0}, {105, "TLS_DH_RSA_WITH_AES_256_CBC_SHA256", 0}, {106, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", 0}, {107, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", 0}, {108, "TLS_DH_anon_WITH_AES_128_CBC_SHA256", 0}, {109, "TLS_DH_anon_WITH_AES_256_CBC_SHA256", 0}, {132, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA", 0}, {133, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA", 0}, {134, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA", 0}, {135, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA", 0}, {136, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA", 0}, {137, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA", 0}, {138, "TLS_PSK_WITH_RC4_128_SHA", 0}, {139, "TLS_PSK_WITH_3DES_EDE_CBC_SHA", 0}, {140, "TLS_PSK_WITH_AES_128_CBC_SHA", 0}, {141, "TLS_PSK_WITH_AES_256_CBC_SHA", 0}, {142, "TLS_DHE_PSK_WITH_RC4_128_SHA", 0}, {143, "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA", 0}, {144, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA", 0}, {145, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA", 0}, {146, "TLS_RSA_PSK_WITH_RC4_128_SHA", 0}, {147, "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA", 0}, {148, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA", 0}, {149, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA", 0}, {150, "TLS_RSA_WITH_SEED_CBC_SHA", 0}, {151, "TLS_DH_DSS_WITH_SEED_CBC_SHA", 0}, {152, "TLS_DH_RSA_WITH_SEED_CBC_SHA", 0}, {153, "TLS_DHE_DSS_WITH_SEED_CBC_SHA", 0}, {154, "TLS_DHE_RSA_WITH_SEED_CBC_SHA", 0}, {155, "TLS_DH_anon_WITH_SEED_CBC_SHA", 0}, {156, "TLS_RSA_WITH_AES_128_GCM_SHA256", 0}, {157, "TLS_RSA_WITH_AES_256_GCM_SHA384", 0}, {158, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", 0}, {159, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", 0}, {160, "TLS_DH_RSA_WITH_AES_128_GCM_SHA256", 0}, {161, "TLS_DH_RSA_WITH_AES_256_GCM_SHA384", 0}, {162, "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", 0}, {163, "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", 0}, {164, "TLS_DH_DSS_WITH_AES_128_GCM_SHA256", 0}, {165, "TLS_DH_DSS_WITH_AES_256_GCM_SHA384", 0}, {166, "TLS_DH_anon_WITH_AES_128_GCM_SHA256", 0}, {167, "TLS_DH_anon_WITH_AES_256_GCM_SHA384", 0}, {168, "TLS_PSK_WITH_AES_128_GCM_SHA256", 0}, {169, "TLS_PSK_WITH_AES_256_GCM_SHA384", 0}, {170, "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256", 0}, {171, "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384", 0}, {172, "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256", 0}, {173, "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384", 0}, {174, "TLS_PSK_WITH_AES_128_CBC_SHA256", 0}, {175, "TLS_PSK_WITH_AES_256_CBC_SHA384", 0}, {176, "TLS_PSK_WITH_NULL_SHA256", 0}, {177, "TLS_PSK_WITH_NULL_SHA384", 0}, {178, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256", 0}, {179, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384", 0}, {180, "TLS_DHE_PSK_WITH_NULL_SHA256", 0}, {181, "TLS_DHE_PSK_WITH_NULL_SHA384", 0}, {182, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256", 0}, {183, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384", 0}, {184, "TLS_RSA_PSK_WITH_NULL_SHA256", 0}, {185, "TLS_RSA_PSK_WITH_NULL_SHA384", 0}, {186, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0}, {187, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256", 0}, {188, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0}, {189, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256", 0}, {190, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0}, {191, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256", 0}, {192, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256", 0}, {193, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256", 0}, {194, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256", 0}, {195, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256", 0}, {196, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256", 0}, {197, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256", 0}, {255, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV", 0}, {4865, "TLS_AES_128_GCM_SHA256", 0}, {4866, "TLS_AES_256_GCM_SHA384", 0}, {4867, "TLS_CHACHA20_POLY1305_SHA256", 0}, {4868, "TLS_AES_128_CCM_SHA256", 0}, {4869, "TLS_AES_128_CCM_8_SHA256", 0}, {22016, "TLS_FALLBACK_SCSV", 0}, {49153, "TLS_ECDH_ECDSA_WITH_NULL_SHA", 0}, {49154, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA", 0}, {49155, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", 0}, {49156, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", 0}, {49157, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", 0}, {49158, "TLS_ECDHE_ECDSA_WITH_NULL_SHA", 0}, {49159, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", 0}, {49160, "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", 0}, {49161, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", 0}, {49162, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", 0}, {49163, "TLS_ECDH_RSA_WITH_NULL_SHA", 0}, {49164, "TLS_ECDH_RSA_WITH_RC4_128_SHA", 0}, {49165, "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", 0}, {49166, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", 0}, {49167, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", 0}, {49168, "TLS_ECDHE_RSA_WITH_NULL_SHA", 0}, {49169, "TLS_ECDHE_RSA_WITH_RC4_128_SHA", 0}, {49170, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", 0}, {49171, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", 0}, {49172, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", 0}, {49173, "TLS_ECDH_anon_WITH_NULL_SHA", 0}, {49174, "TLS_ECDH_anon_WITH_RC4_128_SHA", 0}, {49175, "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", 0}, {49176, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA", 0}, {49177, "TLS_ECDH_anon_WITH_AES_256_CBC_SHA", 0}, {49178, "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA", 0}, {49179, "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA", 0}, {49180, "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA", 0}, {49181, "TLS_SRP_SHA_WITH_AES_128_CBC_SHA", 0}, {49182, "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA", 0}, {49183, "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA", 0}, {49184, "TLS_SRP_SHA_WITH_AES_256_CBC_SHA", 0}, {49185, "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA", 0}, {49186, "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA", 0}, {49187, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", 0}, {49188, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", 0}, {49189, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", 0}, {49190, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", 0}, {49191, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", 0}, {49192, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", 0}, {49193, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", 0}, {49194, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", 0}, {49195, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", 0}, {49196, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", 0}, {49197, "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", 0}, {49198, "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", 0}, {49199, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", 0}, {49200, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", 0}, {49201, "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", 0}, {49202, "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", 0}, {49203, "TLS_ECDHE_PSK_WITH_RC4_128_SHA", 0}, {49204, "TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA", 0}, {49205, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", 0}, {49206, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", 0}, {49207, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256", 0}, {49208, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384", 0}, {49209, "TLS_ECDHE_PSK_WITH_NULL_SHA", 0}, {49210, "TLS_ECDHE_PSK_WITH_NULL_SHA256", 0}, {49211, "TLS_ECDHE_PSK_WITH_NULL_SHA384", 0}, {49212, "TLS_RSA_WITH_ARIA_128_CBC_SHA256", 0}, {49213, "TLS_RSA_WITH_ARIA_256_CBC_SHA384", 0}, {49214, "TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256", 0}, {49215, "TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384", 0}, {49216, "TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256", 0}, {49217, "TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384", 0}, {49218, "TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256", 0}, {49219, "TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384", 0}, {49220, "TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256", 0}, {49221, "TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384", 0}, {49222, "TLS_DH_anon_WITH_ARIA_128_CBC_SHA256", 0}, {49223, "TLS_DH_anon_WITH_ARIA_256_CBC_SHA384", 0}, {49224, "TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256", 0}, {49225, "TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384", 0}, {49226, "TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256", 0}, {49227, "TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384", 0}, {49228, "TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256", 0}, {49229, "TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384", 0}, {49230, "TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256", 0}, {49231, "TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384", 0}, {49232, "TLS_RSA_WITH_ARIA_128_GCM_SHA256", 0}, {49233, "TLS_RSA_WITH_ARIA_256_GCM_SHA384", 0}, {49234, "TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256", 0}, {49235, "TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384", 0}, {49236, "TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256", 0}, {49237, "TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384", 0}, {49238, "TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256", 0}, {49239, "TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384", 0}, {49240, "TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256", 0}, {49241, "TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384", 0}, {49242, "TLS_DH_anon_WITH_ARIA_128_GCM_SHA256", 0}, {49243, "TLS_DH_anon_WITH_ARIA_256_GCM_SHA384", 0}, {49244, "TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256", 0}, {49245, "TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384", 0}, {49246, "TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256", 0}, {49247, "TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384", 0}, {49248, "TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256", 0}, {49249, "TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384", 0}, {49250, "TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256", 0}, {49251, "TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384", 0}, {49252, "TLS_PSK_WITH_ARIA_128_CBC_SHA256", 0}, {49253, "TLS_PSK_WITH_ARIA_256_CBC_SHA384", 0}, {49254, "TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256", 0}, {49255, "TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384", 0}, {49256, "TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256", 0}, {49257, "TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384", 0}, {49258, "TLS_PSK_WITH_ARIA_128_GCM_SHA256", 0}, {49259, "TLS_PSK_WITH_ARIA_256_GCM_SHA384", 0}, {49260, "TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256", 0}, {49261, "TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384", 0}, {49262, "TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256", 0}, {49263, "TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384", 0}, {49264, "TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256", 0}, {49265, "TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384", 0}, {49266, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", 0}, {49267, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", 0}, {49268, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", 0}, {49269, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", 0}, {49270, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0}, {49271, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384", 0}, {49272, "TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0}, {49273, "TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384", 0}, {49274, "TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256", 0}, {49275, "TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384", 0}, {49276, "TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", 0}, {49277, "TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", 0}, {49278, "TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256", 0}, {49279, "TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384", 0}, {49280, "TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256", 0}, {49281, "TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384", 0}, {49282, "TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256", 0}, {49283, "TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384", 0}, {49284, "TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256", 0}, {49285, "TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384", 0}, {49286, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256", 0}, {49287, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384", 0}, {49288, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256", 0}, {49289, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384", 0}, {49290, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", 0}, {49291, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", 0}, {49292, "TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256", 0}, {49293, "TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384", 0}, {49294, "TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256", 0}, {49295, "TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384", 0}, {49296, "TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256", 0}, {49297, "TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384", 0}, {49298, "TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256", 0}, {49299, "TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384", 0}, {49300, "TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256", 0}, {49301, "TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384", 0}, {49302, "TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", 0}, {49303, "TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", 0}, {49304, "TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256", 0}, {49305, "TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384", 0}, {49306, "TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", 0}, {49307, "TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", 0}, {49308, "TLS_RSA_WITH_AES_128_CCM", 0}, {49309, "TLS_RSA_WITH_AES_256_CCM", 0}, {49310, "TLS_DHE_RSA_WITH_AES_128_CCM", 0}, {49311, "TLS_DHE_RSA_WITH_AES_256_CCM", 0}, {49312, "TLS_RSA_WITH_AES_128_CCM_8", 0}, {49313, "TLS_RSA_WITH_AES_256_CCM_8", 0}, {49314, "TLS_DHE_RSA_WITH_AES_128_CCM_8", 0}, {49315, "TLS_DHE_RSA_WITH_AES_256_CCM_8", 0}, {49316, "TLS_PSK_WITH_AES_128_CCM", 0}, {49317, "TLS_PSK_WITH_AES_256_CCM", 0}, {49318, "TLS_DHE_PSK_WITH_AES_128_CCM", 0}, {49319, "TLS_DHE_PSK_WITH_AES_256_CCM", 0}, {49320, "TLS_PSK_WITH_AES_128_CCM_8", 0}, {49321, "TLS_PSK_WITH_AES_256_CCM_8", 0}, {49322, "TLS_PSK_DHE_WITH_AES_128_CCM_8", 0}, {49323, "TLS_PSK_DHE_WITH_AES_256_CCM_8", 0}, {49324, "TLS_ECDHE_ECDSA_WITH_AES_128_CCM", 0}, {49325, "TLS_ECDHE_ECDSA_WITH_AES_256_CCM", 0}, {49326, "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8", 0}, {49327, "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8", 0}, {52392, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", 0}, {52393, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", 0}, {52394, "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", 0}, {52395, "TLS_PSK_WITH_CHACHA20_POLY1305_SHA256", 0}, {52396, "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", 0}, {52397, "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256", 0}, {52398, "TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256", 0}, // DRAFT-IETF-TLS-ECC {71, "TLS_ECDH_ECDSA_WITH_NULL_SHA", 0}, {72, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA", 0}, {73, "TLS_ECDH_ECDSA_WITH_DES_CBC_SHA", 0}, {74, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", 0}, {75, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", 0}, {76, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", 0}, {75, "TLS_ECDH_ECDSA_EXPORT_WITH_RC4_40_SHA", 0}, {76, "TLS_ECDH_ECDSA_EXPORT_WITH_RC4_56_SHA", 0}, {77, "TLS_ECDH_RSA_WITH_NULL_SHA", 0}, {78, "TLS_ECDH_RSA_WITH_RC4_128_SHA", 0}, {79, "TLS_ECDH_RSA_WITH_DES_CBC_SHA", 0}, {80, "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", 0}, {81, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", 0}, {82, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", 0}, {83, "TLS_ECDH_RSA_EXPORT_WITH_RC4_40_SHA", 0}, {84, "TLS_ECDH_RSA_EXPORT_WITH_RC4_56_SHA", 0}, {85, "TLS_ECDH_anon_NULL_WITH_SHA", 0}, {86, "TLS_ECDH_anon_WITH_RC4_128_SHA", 0}, {87, "TLS_ECDH_anon_WITH_DES_CBC_SHA", 0}, {88, "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", 0}, {89, "TLS_ECDH_anon_EXPORT_WITH_DES40_CBC_SHA", 0}, {90, "TLS_ECDH_anon_EXPORT_WITH_RC4_40_SHA", 0}, // DRAFT-IETF-TLS-56-BIT-CIPHERSUITES {96, "TLS_RSA_EXPORT1024_WITH_RC4_56_MD5", 0}, {97, "TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5", 0}, {98, "TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA", 0}, {99, "TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA", 0}, {100, "TLS_RSA_EXPORT1024_WITH_RC4_56_SHA", 0}, {101, "TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA", 0}, {102, "TLS_DHE_DSS_WITH_RC4_128_SHA", 0}, // FIPS SSL (Netscape) {65278, "SSL_RSA_FIPS_WITH_DES_CBC_SHA", 0}, {65279, "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA", 0}, // SSL 2.0 {65664, "SSL2_RC4_128_WITH_MD5", 0}, {131200, "SSL2_RC4_128_EXPORT40_WITH_MD5", 0}, {196736, "SSL2_RC2_CBC_128_CBC_WITH_MD5", 0}, {262272, "SSL2_RC2_128_CBC_EXPORT40_WITH_MD5", 0}, {327808, "SSL2_IDEA_128_CBC_WITH_MD5", 0}, {393280, "SSL2_DES_64_CBC_WITH_MD5", 0}, {393536, "SSL2_DES_64_CBC_WITH_SHA", 0}, {458944, "SSL2_DES_192_EDE3_CBC_WITH_MD5", 0}, {459200, "SSL2_DES_192_EDE3_CBC_WITH_SHA", 0}, {524416, "SSL2_RC4_64_WITH_MD5", 0}, {2570, "GREASE 0x0A0A", 0}, {6682, "GREASE 0x1A1A", 0}, {10794, "GREASE 0x2A2A", 0}, {14906, "GREASE 0x3A3A", 0}, {19018, "GREASE 0x4A4A", 0}, {23130, "GREASE 0x5A5A", 0}, {27242, "GREASE 0x6A6A", 0}, {31354, "GREASE 0x7A7A", 0}, {35466, "GREASE 0x8A8A", 0}, {39578, "GREASE 0x9A9A", 0}, {43690, "GREASE 0xAAAA", 0}, {47802, "GREASE 0xBABA", 0}, {51914, "GREASE 0xCACA", 0}, {56026, "GREASE 0xDADA", 0}, {60138, "GREASE 0xEAEA", 0}, {64250, "GREASE 0xFAFA", 0}, {-1}}; static int decode_AlertLevel_warning(ssl_obj *ssl, int dir, segment *seg, Data *data) { struct json_object *jobj; jobj = ssl->cur_json_st; json_object_object_add(jobj, "alert_level", json_object_new_string("warning")); return 0; } static int decode_AlertLevel_fatal(ssl_obj *ssl, int dir, segment *seg, Data *data) { struct json_object *jobj; jobj = ssl->cur_json_st; json_object_object_add(jobj, "alert_level", json_object_new_string("fatal")); return 0; } decoder AlertLevel_decoder[] = {{1, "warning", decode_AlertLevel_warning}, {2, "fatal", decode_AlertLevel_fatal}, {-1}}; static int decode_AlertDescription_close_notify(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_AlertDescription_unexpected_message(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_AlertDescription_bad_record_mac(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_AlertDescription_decryption_failed(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_AlertDescription_record_overflow(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_AlertDescription_decompression_failure(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_AlertDescription_handshake_failure(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_AlertDescription_bad_certificate(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_AlertDescription_unsupported_certificate(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_AlertDescription_certificate_revoked(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_AlertDescription_certificate_expired(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_AlertDescription_certificate_unknown(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_AlertDescription_illegal_parameter(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_AlertDescription_unknown_ca(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_AlertDescription_access_denied(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_AlertDescription_decode_error(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_AlertDescription_decrypt_error(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_AlertDescription_export_restriction(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_AlertDescription_protocol_version(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_AlertDescription_insufficient_security(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_AlertDescription_internal_error(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_AlertDescription_user_canceled(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_AlertDescription_no_renegotiation(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } decoder AlertDescription_decoder[] = { {0, "close_notify", decode_AlertDescription_close_notify}, {10, "unexpected_message", decode_AlertDescription_unexpected_message}, {20, "bad_record_mac", decode_AlertDescription_bad_record_mac}, {21, "decryption_failed", decode_AlertDescription_decryption_failed}, {22, "record_overflow", decode_AlertDescription_record_overflow}, {30, "decompression_failure", decode_AlertDescription_decompression_failure}, {40, "handshake_failure", decode_AlertDescription_handshake_failure}, {42, "bad_certificate", decode_AlertDescription_bad_certificate}, {43, "unsupported_certificate", decode_AlertDescription_unsupported_certificate}, {44, "certificate_revoked", decode_AlertDescription_certificate_revoked}, {45, "certificate_expired", decode_AlertDescription_certificate_expired}, {46, "certificate_unknown", decode_AlertDescription_certificate_unknown}, {47, "illegal_parameter", decode_AlertDescription_illegal_parameter}, {48, "unknown_ca", decode_AlertDescription_unknown_ca}, {49, "access_denied", decode_AlertDescription_access_denied}, {50, "decode_error", decode_AlertDescription_decode_error}, {51, "decrypt_error", decode_AlertDescription_decrypt_error}, {60, "export_restriction", decode_AlertDescription_export_restriction}, {70, "protocol_version", decode_AlertDescription_protocol_version}, {71, "insufficient_security", decode_AlertDescription_insufficient_security}, {80, "internal_error", decode_AlertDescription_internal_error}, {90, "user_canceled", decode_AlertDescription_user_canceled}, {100, "no_renegotiation", decode_AlertDescription_no_renegotiation}, {-1}}; decoder compression_method_decoder[] = {{0, "NULL", 0}, {-1}}; static int decode_client_certificate_type_rsa_sign(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_client_certificate_type_dss_sign(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_client_certificate_type_rsa_fixed_dh(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } static int decode_client_certificate_type_dss_fixed_dh(ssl_obj *ssl, int dir, segment *seg, Data *data) { return 0; } decoder client_certificate_type_decoder[] = { {1, "rsa_sign", decode_client_certificate_type_rsa_sign}, {2, "dss_sign", decode_client_certificate_type_dss_sign}, {3, "rsa_fixed_dh", decode_client_certificate_type_rsa_fixed_dh}, {4, "dss_fixed_dh", decode_client_certificate_type_dss_fixed_dh}, {-1}}; static int decode_extension_server_name(ssl_obj *ssl, int dir, segment *seg, Data *data) { UINT4 t, l; int r, p; extern decoder server_name_type_decoder[]; SSL_DECODE_UINT16(ssl, "extension length", 0, data, &l); if(dir == DIR_I2R) { SSL_DECODE_UINT16(ssl, "server name list length", 0, data, &l); LF; while(l) { p = data->len; SSL_DECODE_UINT8(ssl, "server name type", 0, data, &t); if(ssl_decode_switch(ssl, server_name_type_decoder, t, dir, seg, data) == R_NOT_FOUND) { decode_server_name(ssl, dir, seg, data); P_(P_RH) { explain(ssl, "Server Name type: %u not yet implemented in ssldump\n", t); } continue; } l -= (p - data->len); } } else { data->len -= l; data->data += l; } return 0; } static int decode_extension_encrypt_then_mac(ssl_obj *ssl, int dir, segment *seg, Data *data) { int r, *etm; UINT4 l; etm = &ssl->extensions->encrypt_then_mac; SSL_DECODE_UINT16(ssl, "extension length", 0, data, &l); data->len -= l; data->data += l; dir == DIR_I2R ? *etm = 1 : ++*etm; return 0; } static int decode_extension_extended_master_secret(ssl_obj *ssl, int dir, segment *seg, Data *data) { int r, *ems; UINT4 l; ems = &ssl->extensions->extended_master_secret; SSL_DECODE_UINT16(ssl, "extension length", 0, data, &l); data->len -= l; data->data += l; dir == DIR_I2R ? *ems = 1 : ++*ems; return 0; } static int decode_extension(ssl_obj *ssl, int dir, segment *seg, Data *data) { int r; UINT4 l; SSL_DECODE_UINT16(ssl, "extension length", 0, data, &l); data->len -= l; data->data += l; return 0; } decoder supported_groups_decoder[] = { {0x0017, "secp256r1", 0}, {0x0018, "secp384r1", 0}, {0x0019, "secp521r1", 0}, {0x001d, "x25519", 0}, {0x001e, "x448", 0}, {0x0100, "ffdhe2048", 0}, {0x0101, "ffdhe3072", 0}, {0x0102, "ffdhe4096", 0}, {0x0103, "ffdhe6144", 0}, {0x0104, "ffdhe8192", 0}, }; // Extension #10 supported_groups (renamed from "elliptic_curves") static int decode_extension_supported_groups(ssl_obj *ssl, int dir, segment *seg, Data *data) { int r, p; UINT4 l, g; char *ja3_ec_str = NULL; SSL_DECODE_UINT16(ssl, "extension length", 0, data, &l); if(dir == DIR_I2R) { SSL_DECODE_UINT16(ssl, "supported_groups list length", 0, data, &l); LF; while(l) { p = data->len; SSL_DECODE_ENUM(ssl, "supported group", 2, supported_groups_decoder, SSL_PRINT_ALL, data, &g); LF; if(!ja3_ec_str) ja3_ec_str = calloc(7, 1); else ja3_ec_str = realloc(ja3_ec_str, strlen(ja3_ec_str) + 7); snprintf(ja3_ec_str + strlen(ja3_ec_str), 7, "%u-", g); l -= (p - data->len); } if(ja3_ec_str && ja3_ec_str[strlen(ja3_ec_str) - 1] == '-') ja3_ec_str[strlen(ja3_ec_str) - 1] = '\0'; } else { data->len -= l; data->data += l; } ssl->cur_ja3_ec_str = ja3_ec_str; return 0; } decoder ec_point_formats_decoder[] = {{ 0, "uncompressed", 0, }, { 1, "ansiX962_compressed_prime", 0, }, { 2, "ansiX962_compressed_char2", 0, }}; // Extension #11 ec_point_formats static int decode_extension_ec_point_formats(ssl_obj *ssl, int dir, segment *seg, Data *data) { int r, p; UINT4 l, f; char *ja3_ecp_str = NULL; SSL_DECODE_UINT16(ssl, "extension length", 0, data, &l); if(dir == DIR_I2R) { SSL_DECODE_UINT8(ssl, "ec_point_formats list length", 0, data, &l); LF; while(l) { p = data->len; SSL_DECODE_ENUM(ssl, "ec point format", 1, ec_point_formats_decoder, SSL_PRINT_ALL, data, &f); LF; if(!ja3_ecp_str) ja3_ecp_str = calloc(5, 1); else ja3_ecp_str = realloc(ja3_ecp_str, strlen(ja3_ecp_str) + 5); snprintf(ja3_ecp_str + strlen(ja3_ecp_str), 5, "%u-", f); l -= (p - data->len); } if(ja3_ecp_str && ja3_ecp_str[strlen(ja3_ecp_str) - 1] == '-') ja3_ecp_str[strlen(ja3_ecp_str) - 1] = '\0'; } else { data->len -= l; data->data += l; } ssl->cur_ja3_ecp_str = ja3_ecp_str; return 0; } static int decode_extension_supported_versions(ssl_obj *ssl, int dir, segment *seg, Data *data) { int r; UINT4 len, version; SSL_DECODE_UINT16(ssl, "extensions length", 0, data, &len); LF; if(dir == DIR_I2R) SSL_DECODE_UINT8(ssl, "supported versions length", 0, data, &len); // client sends extension<..> while(len) { SSL_DECODE_UINT16(ssl, "supported version", 0, data, &version); explain(ssl, "version: %u.%u", (version >> 8) & 0xff, version & 0xff); len -= 2; if(len) printf("\n"); } if(dir == DIR_R2I) ssl->version = version; // Server sets the tls version return 0; } decoder tls13_certificate_types[] = {{0, "x509", 0}, {1, "openpgp", 0}, {2, "raw public key", 0}, {3, "1609 dot 2", 0}}; static int decode_extension_client_certificate_type(ssl_obj *ssl, int dir, segment *seg, Data *data) { int r; UINT4 len, certificate_type; SSL_DECODE_UINT16(ssl, "extensions length", 0, data, &len); LF; if(dir == DIR_I2R) SSL_DECODE_UINT8(ssl, "client certificates length", 0, data, &len); // client sends certificates<..> while(len) { SSL_DECODE_ENUM(ssl, "certificate type", 1, tls13_certificate_types, SSL_PRINT_ALL, data, &certificate_type); len -= 1; data += 1; if(len) printf("\n"); } if(dir == DIR_R2I) ssl->extensions->client_certificate_type = certificate_type; // Server sets the client_certificate_type return 0; } static int decode_extension_server_certificate_type(ssl_obj *ssl, int dir, segment *seg, Data *data) { int r; UINT4 len, certificate_type; SSL_DECODE_UINT16(ssl, "extensions length", 0, data, &len); LF; if(dir == DIR_I2R) SSL_DECODE_UINT8(ssl, "server certificates length", 0, data, &len); // client sends certificates<..> while(len) { SSL_DECODE_ENUM(ssl, "certificate type", 1, tls13_certificate_types, SSL_PRINT_ALL, data, &certificate_type); len -= 1; data += 1; if(len) printf("\n"); } if(dir == DIR_R2I) ssl->extensions->server_certificate_type = certificate_type; // Server sets the server_certificate_type return 0; } decoder extension_decoder[] = { { 0, "server_name", decode_extension_server_name, }, {1, "max_fragment_length", decode_extension}, {2, "client_certificate_url", decode_extension}, {3, "trusted_ca_keys", decode_extension}, {4, "truncated_hmac", decode_extension}, {5, "status_request", decode_extension}, {6, "user_mapping", decode_extension}, {7, "client_authz", decode_extension}, {8, "server_authz", decode_extension}, {9, "cert_type", decode_extension}, {10, "supported_groups", decode_extension_supported_groups}, {11, "ec_point_formats", decode_extension_ec_point_formats}, {12, "srp", decode_extension}, {13, "signature_algorithms", decode_extension}, {14, "use_srtp", decode_extension}, {15, "heartbeat", decode_extension}, {16, "application_layer_protocol_negotiation", decode_extension}, {17, "status_request_v2", decode_extension}, {18, "signed_certificate_timestamp", decode_extension}, {19, "client_certificate_type", decode_extension_client_certificate_type}, {20, "server_certificate_type", decode_extension_server_certificate_type}, {21, "padding", decode_extension}, {22, "encrypt_then_mac", decode_extension_encrypt_then_mac}, {23, "extended_master_secret", decode_extension_extended_master_secret}, {24, "token_binding", decode_extension}, {25, "cached_info", decode_extension}, {26, "tls_lts", decode_extension}, {27, "compress_certificate", decode_extension}, {28, "record_size_limit", decode_extension}, {29, "pwd_protect", decode_extension}, {30, "pwd_clear", decode_extension}, {31, "password_salt", decode_extension}, {32, "ticket_pinning", decode_extension}, {33, "tls_cert_with_extern_psk", decode_extension}, {34, "delegated_credentials", decode_extension}, {35, "session_ticket", decode_extension}, {36, "TLMSP", decode_extension}, {37, "TLMSP_proxying", decode_extension}, {38, "TLMSP_delegate", decode_extension}, {39, "supported_ekt_ciphers", decode_extension}, {41, "pre_shared_key", decode_extension}, {42, "early_data", decode_extension}, {43, "supported_versions", decode_extension_supported_versions}, {44, "cookie", decode_extension}, {45, "psk_key_exchange_modes", decode_extension}, {47, "certificate_authorities", decode_extension}, {48, "oid_filters", decode_extension}, {49, "post_handshake_auth", decode_extension}, {50, "signature_algorithms_cert", decode_extension}, {51, "key_share", decode_extension}, {52, "transparency_info", decode_extension}, {53, "connection_id", decode_extension}, {55, "external_id_hash", decode_extension}, {56, "external_session_id", decode_extension}, {13172, "next_protocol_negotiation", decode_extension}, {0xfe0d, "encrypted_client_hello", decode_extension}, {0xff01, "renegotiation_info", decode_extension}, {-1}}; static int decode_server_name_type_host_name(ssl_obj *ssl, int dir, segment *seg, Data *data) { int r; UINT4 l; SSL_DECODE_UINT16(ssl, "server name length", 0, data, &l); if(!(NET_print_flags & NET_PRINT_JSON)) printf(": %.*s", l, data->data); /* Possibly use data->data to set/modify ssl->server_name */ if(l != 0) { char *server_name; server_name = calloc(l + 1, sizeof(char)); if(server_name != NULL) { if(ssl->server_name) free(ssl->server_name); if(l > data->len) l = data->len; memcpy(server_name, data->data, l); ssl->server_name = server_name; } } data->len -= l; data->data += l; return 0; } static int decode_server_name(ssl_obj *ssl, int dir, segment *seg, Data *data) { int r; UINT4 l; SSL_DECODE_UINT16(ssl, "server name length", 0, data, &l); data->len -= l; data->data += l; return 0; } decoder server_name_type_decoder[] = { {0, "host_name", decode_server_name_type_host_name}, {-1}}; ssldump-1.9/ssl/ssl.enums.h000066400000000000000000000004441470411077700157650ustar00rootroot00000000000000extern decoder ContentType_decoder[]; extern decoder HandshakeType_decoder[]; extern decoder cipher_suite_decoder[]; extern decoder AlertLevel_decoder[]; extern decoder AlertDescription_decoder[]; extern decoder compression_method_decoder[]; extern decoder client_certificate_type_decoder[]; ssldump-1.9/ssl/ssl_analyze.c000066400000000000000000000356071470411077700163660ustar00rootroot00000000000000/** ssl_analyze.c Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: ssl_analyze.c,v 1.8 2002/01/21 18:46:13 ekr Exp $ ekr@rtfm.com Fri Jan 8 14:07:05 1999 */ #include #include #include #include "network.h" #include "debug.h" #include "sslprint.h" #include "ssl_h.h" #include "ssl_analyze.h" /*UINT4 SSL_print_flags=P_HL| P_ND;*/ UINT4 SSL_print_flags = 1 | P_HT | P_HL; static int parse_ssl_flags PROTO_LIST((char *str)); static int create_ssl_ctx PROTO_LIST((void *handle, proto_ctx **ctxp)); static int create_ssl_analyzer PROTO_LIST((void *handle, proto_ctx *ctx, tcp_conn *conn, proto_obj **objp, struct sockaddr_storage *i_addr, u_short i_port, struct sockaddr_storage *r_addr, u_short r_port, struct timeval *base_time)); static int destroy_ssl_ctx PROTO_LIST((void *handle, proto_ctx **ctxp)); static int destroy_ssl_analyzer PROTO_LIST((proto_obj * *objp)); static int read_ssl_record PROTO_LIST((ssl_obj * obj, r_queue *q, segment *seg, int offset, segment **lastp, int *offsetp)); static int read_data PROTO_LIST( (r_queue * q, segment *seg, int offset, segment **lastp, int *offsetp)); static int data_ssl_analyzer PROTO_LIST((proto_obj * _obj, segment *seg, int direction)); int close_ssl_analyzer PROTO_LIST((proto_obj * _obj, packet *p, int direction)); static int create_r_queue PROTO_LIST((r_queue * *qp)); static int free_r_queue PROTO_LIST((r_queue * q)); static int print_ssl_record PROTO_LIST( (ssl_obj * obj, int direction, segment *q, UCHAR *data, int len)); char *SSL_keyfile = 0; char *SSL_password = 0; char *SSL_keylogfile = 0; #define NEGATE 0x800000 typedef struct { int ch; char *name; UINT4 flag; } flag_struct; flag_struct flags[] = { { 't', "ts", SSL_PRINT_TIMESTAMP, }, {'e', "tsa", SSL_PRINT_TIMESTAMP | SSL_PRINT_TIMESTAMP_ABSOLUTE}, {'x', "x", SSL_PRINT_HEXDUMP}, {'X', "X", SSL_PRINT_HEX_ONLY}, {'r', "rh", SSL_PRINT_RECORD_HEADER}, {0, "ht", SSL_PRINT_HANDSHAKE_TYPE}, {0, "H", SSL_PRINT_HIGHLIGHTS}, {'A', "all", SSL_PRINT_ALL_FIELDS}, {0, "d", SSL_PRINT_DECODE}, {'y', "nroff", SSL_PRINT_NROFF}, {'N', "asn", SSL_PRINT_DECODE_ASN1}, {0, "crypto", SSL_PRINT_CRYPTO}, {'d', "appdata", SSL_PRINT_APP_DATA}, {'q', "quiet", P_HL | NEGATE}, {0}}; int parse_ssl_flag(int flag) { flag_struct *fl; for(fl = flags; fl->name; fl++) { if(fl->ch == flag) { if(fl->flag & NEGATE) { SSL_print_flags &= ~(fl->flag); } else SSL_print_flags |= fl->flag; break; } } return 0; } static int parse_ssl_flags(char *str) { char *x, *y; flag_struct *fl; int bang; y = str; while((x = strtok(y, ","))) { y = 0; if(*x == '!') { bang = 1; x++; } else bang = 0; for(fl = flags; fl->name; fl++) { if(!strcmp(x, fl->name)) { if(!bang) SSL_print_flags |= fl->flag; else SSL_print_flags &= ~fl->flag; break; } } if(!fl->name) { fprintf(stderr, "SSL: Bad flag %s\n", x); } } return 0; } static int create_ssl_ctx(void *handle, proto_ctx **ctxp) { ssl_decode_ctx *ctx = 0; int r, _status; if((r = ssl_decode_ctx_create(&ctx, SSL_keyfile, SSL_password, SSL_keylogfile))) ABORT(r); *ctxp = (proto_ctx *)ctx; _status = 0; abort: return _status; } static int destroy_ssl_ctx(void *handle, proto_ctx **ctxp) { ssl_decode_ctx *ctx = 0; ctx = (ssl_decode_ctx *)*ctxp; ssl_decode_ctx_destroy(&ctx); return 0; } static int create_ssl_analyzer(void *handle, proto_ctx *ctx, tcp_conn *conn, proto_obj **objp, struct sockaddr_storage *i_addr, u_short i_port, struct sockaddr_storage *r_addr, u_short r_port, struct timeval *base_time) { int r, _status; ssl_obj *obj = 0; if(!(obj = (ssl_obj *)calloc(1, sizeof(ssl_obj)))) ABORT(R_NO_MEMORY); obj->ssl_ctx = (ssl_decode_ctx *)ctx; obj->conn = conn; if((r = create_r_queue(&obj->r2i_queue))) ABORT(r); if((r = create_r_queue(&obj->i2r_queue))) ABORT(r); obj->client_name = strndup(conn->i_name, NI_MAXHOST); obj->client_ip = strndup(conn->i_num, INET6_ADDRSTRLEN); obj->client_port = i_port; obj->server_name = strndup(conn->r_name, NI_MAXHOST); obj->server_ip = strndup(conn->r_num, INET6_ADDRSTRLEN); obj->server_port = r_port; obj->i_state = SSL_ST_SENT_NOTHING; obj->r_state = SSL_ST_HANDSHAKE; memcpy(&obj->time_start, base_time, sizeof(struct timeval)); memcpy(&obj->time_last, base_time, sizeof(struct timeval)); if((r = ssl_decoder_create(&obj->decoder, obj->ssl_ctx))) ABORT(r); if(!(obj->extensions = malloc(sizeof(ssl_extensions)))) ABORT(R_NO_MEMORY); *objp = (proto_obj *)obj; _status = 0; // check logger... if(logger) _status = logger->vtbl->create(&obj->logger_obj, i_addr, i_port, r_addr, r_port, base_time); abort: if(_status) { destroy_ssl_analyzer((proto_obj **)&obj); } return _status; } static int destroy_ssl_analyzer(proto_obj **objp) { ssl_obj *obj; if(!objp || !*objp) return 0; obj = (ssl_obj *)*objp; DBG((0, "Destroying SSL analyzer")); // check logger... if(logger) logger->vtbl->destroy(&obj->logger_obj); free_r_queue(obj->i2r_queue); free_r_queue(obj->r2i_queue); ssl_decoder_destroy(&obj->decoder); free(obj->client_name); free(obj->client_ip); free(obj->server_name); free(obj->server_ip); free(obj->extensions); free(*objp); *objp = 0; return 0; } static int free_r_queue(r_queue *q) { FREE(q->data); if(q->q) free_tcp_segment_queue(q->q); free(q); return 0; } static int create_r_queue(r_queue **qp) { r_queue *q = 0; int _status; if(!(q = (r_queue *)calloc(1, sizeof(r_queue)))) ABORT(R_NO_MEMORY); if(!(q->data = (UCHAR *)malloc(SSL_HEADER_SIZE))) ABORT(R_NO_MEMORY); q->ptr = q->data; q->_allocated = SSL_HEADER_SIZE; q->len = 0; q->state = SSL_READ_NONE; *qp = q; _status = 0; abort: if(_status) { free_r_queue(q); } return _status; } static int read_ssl_record(ssl_obj *obj, r_queue *q, segment *seg, int offset, segment **lastp, int *offsetp) { segment *last = seg; int rec_len, r, _status; switch(q->state) { case SSL_READ_NONE: if(SSL_HEADER_SIZE < q->len) ABORT(-1); q->read_left = SSL_HEADER_SIZE - q->len; if((r = read_data(q, seg, offset, &last, &offset))) ABORT(r); q->state = SSL_READ_HEADER; switch(q->data[0]) { case 20: case 21: case 22: case 23: break; default: DBG((0, "Unknown SSL content type %d for segment %u:%u(%u)", q->data[0] & 255, seg->s_seq, seg->s_seq + seg->len, seg->len)); } rec_len = COMBINE(q->data[3], q->data[4]); /* SSL v3.0 spec says a record may not exceed 2**14 + 2048 == 18432 */ if(rec_len > 18432) ABORT(R_INTERNAL); /*Expand the buffer*/ if(q->_allocated < (rec_len + SSL_HEADER_SIZE)) { if(!(q->data = realloc(q->data, rec_len + 5))) ABORT(R_NO_MEMORY); q->_allocated = rec_len + SSL_HEADER_SIZE; q->ptr = q->data + SSL_HEADER_SIZE; }; q->read_left = rec_len; case SSL_READ_HEADER: if((r = read_data(q, last, offset, &last, &offset))) ABORT(r); break; default: ABORT(R_INTERNAL); } q->state = SSL_READ_NONE; /*Whew. If we get here, we've managed to read a whole record*/ *lastp = last; *offsetp = offset; _status = 0; abort: return _status; } static int read_data(r_queue *q, segment *seg, int offset, segment **lastp, int *offsetp) { int tocpy = 0, r, _status; #ifdef DEBUG int bread = 0; #endif DBG((0, "read_data %d bytes requested", q->read_left)); for(; seg; seg = seg->next, offset = 0) { int left; left = seg->len - offset; tocpy = MIN(q->read_left, left); memcpy(q->ptr, seg->data + offset, tocpy); q->read_left -= tocpy; q->ptr += tocpy; q->len += tocpy; #ifdef DEBUG bread += tocpy; #endif if(!q->read_left) break; }; if(q->read_left) { if((r = copy_tcp_segment_queue(&q->q, seg))) ABORT(r); return SSL_NO_DATA; } if(seg && tocpy == (seg->len - offset)) { *lastp = 0; *offsetp = 0; } else { *lastp = seg; if(seg) *offsetp = tocpy + offset; } if(q->read_left < 0) abort(); DBG((0, "read_data %d bytes read", bread)); _status = 0; abort: return _status; } static int data_ssl_analyzer(proto_obj *_obj, segment *seg, int direction) { int _status, r; r_queue *q; segment *last, *q_next = NULL, *assembled; ssl_obj *ssl = (ssl_obj *)_obj; int offset = 0; q = direction == DIR_R2I ? ssl->r2i_queue : ssl->i2r_queue; /* Handle SSLv2 backwards compat client hello This is sloppy because we'll assume that it's all in one TCP segment -- an assumption we make nowhere else in the code */ if(direction == DIR_I2R && ssl->i_state == SSL_ST_SENT_NOTHING) { r = process_v2_hello(ssl, seg); if(r == SSL_NO_DATA) return 0; if(r == 0) return 0; } if(ssl->i_state == SSL_ST_SENT_NOTHING) { r = process_beginning_plaintext(ssl, seg, direction); if(r == SSL_NO_DATA) return 0; if(r == 0) return 0; } while(!(r = read_ssl_record(ssl, q, seg, offset, &last, &offset))) { if(ssl->i_state == SSL_ST_SENT_NOTHING) ssl->i_state = SSL_ST_HANDSHAKE; if(last) { q_next = last->next; last->next = 0; } if(q->q_last) { q->q_last->next = seg; assembled = q->q; } else assembled = seg; ssl->direction = direction; if((r = print_ssl_record(ssl, direction, assembled, q->data, q->len))) ABORT(r); /*Now reset things, so we can read another record*/ if(q) { if(q->q_last) q->q_last->next = 0; if(last) last->next = q_next; free_tcp_segment_queue(q->q); q->q = 0; q->q_last = 0; q->offset = 0; q->len = 0; q->ptr = q->data; q->state = SSL_READ_NONE; } seg = last; } if(r != SSL_NO_DATA) ABORT(r); _status = 0; abort: return _status; } static int print_ssl_header(ssl_obj *obj, int direction, segment *q, UCHAR *data, int len) { int ct = 0; segment *s; ssl_print_record_num(obj); if(SSL_print_flags & SSL_PRINT_TIMESTAMP) { for(s = q; s; s = s->next) ct++; for(s = q; s; s = s->next) { ssl_print_timestamp(obj, &s->p->ts); if(s->next) printf(", "); } } ssl_print_direction_indicator(obj, direction); return 0; } static int print_ssl_record(ssl_obj *obj, int direction, segment *q, UCHAR *data, int len) { int r; obj->cur_json_st = json_object_new_object(); if((r = print_ssl_header(obj, direction, q, data, len))) ERETURN(r); ssl_expand_record(obj, q, direction, data, len); if(SSL_print_flags & SSL_PRINT_HEXDUMP) { Data d; INIT_DATA(d, data, len); exdump(obj, "Packet data", &d); LF; LF; } if(SSL_print_flags & SSL_PRINT_JSON) printf("%s\n", json_object_to_json_string(obj->cur_json_st)); json_object_put(obj->cur_json_st); obj->cur_json_st = NULL; return 0; } int close_ssl_analyzer(proto_obj *_obj, packet *p, int dir) { ssl_obj *ssl = (ssl_obj *)_obj; char *what; if(p->tcp->th_flags & TH_RST) what = "RST"; else what = "FIN"; // check logger... if(logger) logger->vtbl->close(ssl->logger_obj, NULL, 0, dir); explain(ssl, "%d ", ssl->conn->conn_number); ssl_print_timestamp(ssl, &p->ts); ssl_print_direction_indicator(ssl, dir); explain(ssl, " TCP %s", what); LF; return 0; } static struct proto_mod_vtbl_ ssl_vtbl = { parse_ssl_flags, parse_ssl_flag, create_ssl_ctx, create_ssl_analyzer, destroy_ssl_ctx, destroy_ssl_analyzer, data_ssl_analyzer, close_ssl_analyzer, }; struct proto_mod_ ssl_mod = {0, &ssl_vtbl}; ssldump-1.9/ssl/ssl_analyze.h000066400000000000000000000062621470411077700163660ustar00rootroot00000000000000/** ssl_analyze.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: ssl_analyze.h,v 1.3 2000/11/09 18:52:24 ekr Exp $ ekr@rtfm.com Tue Jan 12 08:45:44 1999 */ #ifndef _ssl_analyze_h #define _ssl_analyze_h extern proto_mod ssl_mod; /*The type of data this is*/ #define P_RH (1 << 3) #define P_HT (1 << 4) #define P_HL (1 << 5) #define P_ND (1 << 6) #define P_DC (1 << 7) #define P_NR (1 << 8) #define P_ASN (1 << 9) #define P_CR (1 << 10) #define P_AD (1 << 11) #define P_TSA (1 << 12) #define P_QT (1 << 13) #define P_HO (1 << 14) #define P_JS (1 << 15) #define SSL_PRINT_TIMESTAMP (1) /*Timestamp records*/ #define SSL_PRINT_HEXDUMP (1 << 2) /*Print the whole record in hex*/ #define SSL_PRINT_RECORD_HEADER P_RH /*Print the record header*/ #define SSL_PRINT_HANDSHAKE_TYPE P_HT /*Print the handshake type*/ #define SSL_PRINT_HIGHLIGHTS (P_HT | P_HL) #define SSL_PRINT_ALL_FIELDS (P_RH | P_HT | P_HL | P_ND) #define SSL_PRINT_DECODE (P_DC) /*Print fields as decoded*/ #define SSL_PRINT_NROFF (P_NR) #define SSL_PRINT_DECODE_ASN1 (P_ASN) #define SSL_PRINT_CRYPTO (P_CR) #define SSL_PRINT_APP_DATA (P_AD) #define SSL_PRINT_TIMESTAMP_ABSOLUTE (P_TSA) #define SSL_PRINT_QUIET (P_QT) #define SSL_PRINT_HEX_ONLY (P_HO) #define SSL_PRINT_JSON (P_JS) #define SSL_PRINT_ALL 0xfffffff extern UINT4 SSL_print_flags; extern char *SSL_keyfile; extern char *SSL_password; extern char *SSL_keylogfile; #endif ssldump-1.9/ssl/ssl_h.h000066400000000000000000000105251470411077700151470ustar00rootroot00000000000000/** ssl.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: ssl_h.h,v 1.6 2002/08/17 01:33:17 ekr Exp $ ekr@rtfm.com Fri Jan 8 14:09:37 1999 */ #ifndef _ssl_h #define _ssl_h #include "sslciphers.h" typedef struct ssl_decode_ctx_ ssl_decode_ctx; typedef struct ssl_decoder_ ssl_decoder; typedef struct d_queue_ { short state; /*What state we're in*/ #define SSL_READ_NONE 1 #define SSL_READ_HEADER 2 int read_left; /*How many more bytes to read in this state*/ int len; /*The length of the total record, including header*/ UCHAR *data; /*The data for this record*/ UCHAR *ptr; /*The data ptr*/ int _allocated; /*The number of data bytes allocated for this record*/ segment *q; /*The segments that match this record*/ segment *q_last; /*The last segment*/ int offset; /*How far into the first segment this record starts*/ } r_queue; typedef struct ssl_extensions_ { int encrypt_then_mac; int extended_master_secret; int client_certificate_type; int server_certificate_type; } ssl_extensions; typedef struct ssl_obj_ { tcp_conn *conn; proto_obj *logger_obj; int r_state; int i_state; int version; UINT4 cipher_suite; char *client_name; char *client_ip; int client_port; char *server_name; char *server_ip; int server_port; struct SSL_CipherSuite_ *cs; r_queue *i2r_queue; r_queue *r2i_queue; struct timeval time_start; struct timeval time_last; ssl_decode_ctx *ssl_ctx; ssl_decoder *decoder; ssl_extensions *extensions; int process_ciphertext; /*Printing bookkeeping*/ #define REC_PLAINTEXT 1 #define REC_DECRYPTED_CIPHERTEXT 2 #define REC_CIPHERTEXT 3 int record_encryption; int direction; /* The direction we're currently working in*/ int record_count; int indent_depth; int indent_name_len; struct json_object *cur_json_st; char *cur_ja3_ec_str; char *cur_ja3_ecp_str; } ssl_obj; typedef struct decoder_ { int type; char *name; int(*print) PROTO_LIST((ssl_obj *, int direction, segment *seg, Data *data)); } decoder; #define SSL_NO_DATA 1 #define SSL_BAD_CONTENT_TYPE 2 #define SSL_BAD_PMS 3 #define SSL_CANT_DO_CIPHER 4 #define SSL_NO_DECRYPT 5 #define SSL_BAD_MAC 6 #define SSL_BAD_DATA 7 /*SSL defines*/ #define COMBINE(a, b) ((a << 8) | b) #define SSL_HEADER_SIZE 5 #define SSLV3_VERSION 0x300 #define TLSV1_VERSION 0x301 #define TLSV11_VERSION 0x302 #define TLSV12_VERSION 0x303 #define TLSV13_VERSION 0x304 /*State defines*/ #define SSL_ST_SENT_NOTHING 0 #define SSL_ST_HANDSHAKE 1 #define SSL_ST_SENT_CHANGE_CIPHER_SPEC 2 #include "ssldecode.h" #endif ssldump-1.9/ssl/ssl_rec.c000066400000000000000000000324741470411077700154730ustar00rootroot00000000000000/** ssl_rec.c Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: ssl_rec.c,v 1.3 2000/11/03 06:38:06 ekr Exp $ ekr@rtfm.com Wed Aug 18 15:46:57 1999 */ #include "network.h" #include "ssl_h.h" #include "sslprint.h" #include "ssl.enums.h" #ifdef OPENSSL #include #include #include #include #endif #include "ssldecode.h" #include "ssl_rec.h" struct ssl_rec_decoder_ { SSL_CipherSuite *cs; Data *mac_key; Data *implicit_iv; /* for AEAD ciphers */ Data *write_key; /* for AEAD ciphers */ #ifdef OPENSSL EVP_CIPHER_CTX *evp; #endif UINT8 seq; }; char *digests[] = {"MD5", "SHA1", "SHA224", "SHA256", "SHA384", "SHA512", NULL}; char *ciphers[] = { "DES", "3DES", "RC4", "RC2", "IDEA", "AES128", "AES256", "CAMELLIA128", "CAMELLIA256", "SEED", NULL, "aes-128-gcm", "aes-256-gcm", "ChaCha20-Poly1305", "aes-128-ccm", "aes-128-ccm", // for ccm 8, uses the same cipher }; static int tls_check_mac PROTO_LIST((ssl_rec_decoder * d, int ct, int ver, UCHAR *data, UINT4 datalen, UCHAR *iv, UINT4 ivlen, UCHAR *mac)); static int fmt_seq PROTO_LIST((UINT4 num, UCHAR *buf)); int ssl_create_rec_decoder(ssl_rec_decoder **dp, ssl_obj *ssl, UCHAR *mk, UCHAR *sk, UCHAR *iv) { int r, _status; ssl_rec_decoder *dec = 0; #ifdef OPENSSL const EVP_CIPHER *ciph = 0; int iv_len = ssl->version == TLSV13_VERSION ? 12 : ssl->cs->block; /* Find the SSLeay cipher */ if(ssl->cs->enc != ENC_NULL) { ciph = (EVP_CIPHER *)EVP_get_cipherbyname(ciphers[ssl->cs->enc - 0x30]); if(!ciph) ABORT(R_INTERNAL); } else { ciph = EVP_enc_null(); } if(!(dec = (ssl_rec_decoder *)calloc(1, sizeof(ssl_rec_decoder)))) ABORT(R_NO_MEMORY); dec->cs = ssl->cs; if((r = r_data_alloc(&dec->mac_key, ssl->cs->dig_len))) ABORT(r); if((r = r_data_alloc(&dec->implicit_iv, iv_len))) ABORT(r); memcpy(dec->implicit_iv->data, iv, iv_len); if((r = r_data_create(&dec->write_key, sk, ssl->cs->eff_bits / 8))) ABORT(r); /* This is necessary for AEAD ciphers, because we must wait to fully initialize the cipher in order to include the implicit IV */ if(IS_AEAD_CIPHER(ssl->cs)) { sk = NULL; iv = NULL; } else memcpy(dec->mac_key->data, mk, ssl->cs->dig_len); if(!(dec->evp = EVP_CIPHER_CTX_new())) ABORT(R_NO_MEMORY); EVP_CIPHER_CTX_init(dec->evp); EVP_CipherInit(dec->evp, ciph, sk, iv, 0); #endif *dp = dec; _status = 0; abort: if(_status) { ssl_destroy_rec_decoder(&dec); } return _status; } int ssl_destroy_rec_decoder(ssl_rec_decoder **dp) { ssl_rec_decoder *d; if(!dp || !*dp) return 0; d = *dp; r_data_destroy(&d->mac_key); r_data_destroy(&d->implicit_iv); r_data_destroy(&d->write_key); #ifdef OPENSSL if(d->evp) { EVP_CIPHER_CTX_free(d->evp); } free(*dp); #endif *dp = 0; return 0; } #define MSB(a) ((a >> 8) & 0xff) #define LSB(a) (a & 0xff) int tls13_update_rec_key(ssl_rec_decoder *d, UCHAR *newkey, UCHAR *newiv) { d->write_key->data = newkey; d->implicit_iv->data = newiv; d->seq = 0; return 0; } int tls13_decode_rec_data(ssl_obj *ssl, ssl_rec_decoder *d, int ct, int version, UCHAR *in, int inl, UCHAR *out, int *outl) { int i; int x, _status = 0; UCHAR aad[5], aead_nonce[12], *tag; int taglen = d->cs->enc == ENC_AES128_CCM_8 ? 8 : 16; CRDUMP("CipherText", in, inl); CRDUMPD("KEY", d->write_key); CRDUMPD("IV", d->implicit_iv); if(!IS_AEAD_CIPHER(d->cs)) { fprintf(stderr, "Non aead cipher in tls13\n"); ABORT(-1); } memcpy(aead_nonce, d->implicit_iv->data, 12); for(i = 0; i < 8; i++) { // AEAD NONCE according to RFC TLS1.3 aead_nonce[12 - 1 - i] ^= ((d->seq >> (i * 8)) & 0xFF); } d->seq++; CRDUMP("NONCE", aead_nonce, 12); tag = in + (inl - taglen); CRDUMP("Tag", tag, taglen); aad[0] = ct; aad[1] = 0x03; aad[2] = 0x03; aad[3] = MSB(inl); aad[4] = LSB(inl); CRDUMP("AAD", aad, 5); inl -= taglen; if(!EVP_CIPHER_CTX_ctrl(d->evp, EVP_CTRL_AEAD_SET_IVLEN, 12, NULL)) { fprintf(stderr, "Unable to set ivlen\n"); ABORT(-1); } if(IS_CCM_CIPHER(d->cs) && !EVP_CIPHER_CTX_ctrl(d->evp, EVP_CTRL_AEAD_SET_TAG, taglen, tag)) { fprintf(stderr, "Unable to set tag for ccm cipher\n"); ABORT(-1); } if(!EVP_DecryptInit_ex(d->evp, NULL, NULL, d->write_key->data, aead_nonce)) { fprintf(stderr, "Unable to init evp1\n"); ABORT(-1); } if(IS_CCM_CIPHER(d->cs) && !EVP_DecryptUpdate(d->evp, NULL, outl, NULL, inl)) { fprintf(stderr, "Unable to update data length\n"); ABORT(-1); } if(!EVP_DecryptUpdate(d->evp, NULL, outl, aad, 5)) { fprintf(stderr, "Unable to update aad\n"); ABORT(-1); } CRDUMP("Real CipherText", in, inl); if(!EVP_DecryptUpdate(d->evp, out, outl, in, inl)) { fprintf(stderr, "Unable to update with CipherText\n"); ABORT(-1); } if(!IS_CCM_CIPHER(d->cs) && (!EVP_CIPHER_CTX_ctrl(d->evp, EVP_CTRL_GCM_SET_TAG, taglen, tag) || !EVP_DecryptFinal(d->evp, NULL, &x))) { fprintf(stderr, "BAD MAC\n"); ABORT(SSL_BAD_MAC); } abort: ERR_print_errors_fp(stderr); return _status; } int ssl_decode_rec_data(ssl_obj *ssl, ssl_rec_decoder *d, int ct, int version, UCHAR *in, int inl, UCHAR *out, int *outl) { #ifdef OPENSSL int pad; int r, encpadl, x; UCHAR *mac, aead_tag[13], aead_nonce[12]; CRDUMP("Ciphertext", in, inl); if(IS_AEAD_CIPHER(d->cs)) { memcpy(aead_nonce, d->implicit_iv->data, d->implicit_iv->len); memcpy(aead_nonce + d->implicit_iv->len, in, 12 - d->implicit_iv->len); in += 12 - d->implicit_iv->len; inl -= 12 - d->implicit_iv->len; EVP_DecryptInit(d->evp, NULL, d->write_key->data, aead_nonce); /* Then tag is always 16 bytes, as per: https://tools.ietf.org/html/rfc5116#section-5.2 */ EVP_CIPHER_CTX_ctrl(d->evp, EVP_CTRL_GCM_SET_TAG, 16, in + (inl - 16)); inl -= 16; fmt_seq(d->seq, aead_tag); d->seq++; aead_tag[8] = ct; aead_tag[9] = MSB(version); aead_tag[10] = LSB(version); aead_tag[11] = MSB(inl); aead_tag[12] = LSB(inl); EVP_DecryptUpdate(d->evp, NULL, outl, aead_tag, 13); EVP_DecryptUpdate(d->evp, out, outl, in, inl); if(!(x = EVP_DecryptFinal(d->evp, NULL, &x))) ERETURN(SSL_BAD_MAC); } /* Encrypt-then-MAC is not used with AEAD ciphers, as per: https://tools.ietf.org/html/rfc7366#section-3 */ else if(ssl->extensions->encrypt_then_mac == 2) { *outl = inl; /* First strip off the MAC */ *outl -= d->cs->dig_len; mac = in + (*outl); encpadl = *outl; /* Now decrypt */ EVP_Cipher(d->evp, out, in, *outl); CRDUMP("Plaintext", out, *outl); /* And then strip off the padding*/ if(d->cs->block > 1) { pad = out[*outl - 1]; *outl -= (pad + 1); } /* TLS 1.1 and beyond: remove explicit IV, only used with * non-stream ciphers. */ if(ssl->version >= 0x0302 && ssl->cs->block > 1) { UINT4 blk = ssl->cs->block; if(blk <= *outl) { *outl -= blk; memmove(out, out + blk, *outl); } else { DBG((0, "Block size greater than Plaintext!")); ERETURN(SSL_BAD_MAC); } if((r = tls_check_mac(d, ct, version, in + blk, encpadl, in, blk, mac))) ERETURN(r); } else if((r = tls_check_mac(d, ct, version, in, encpadl, NULL, 0, mac))) ERETURN(r); } else { /* First decrypt*/ EVP_Cipher(d->evp, out, in, inl); CRDUMP("Plaintext", out, inl); *outl = inl; /* Now strip off the padding*/ if(d->cs->block > 1) { pad = out[inl - 1]; *outl -= (pad + 1); } /* And the MAC */ *outl -= d->cs->dig_len; mac = out + (*outl); CRDUMP("Record data", out, *outl); /* Now check the MAC */ if(ssl->version == 0x300) { if((r = ssl3_check_mac(d, ct, version, out, *outl, mac))) ERETURN(r); } else { /* TLS 1.1 and beyond: remove explicit IV, only used with * non-stream ciphers. */ if(ssl->version >= 0x0302 && ssl->cs->block > 1) { UINT4 blk = ssl->cs->block; if(blk <= *outl) { *outl -= blk; memmove(out, out + blk, *outl); } else { DBG((0, "Block size greater than Plaintext!")); ERETURN(SSL_BAD_MAC); } } if((r = tls_check_mac(d, ct, version, out, *outl, NULL, 0, mac))) ERETURN(r); } } #endif return 0; } #ifdef OPENSSL /* This should go to 2^128, but we're never really going to see more than 2^64, so we cheat*/ static int fmt_seq(UINT4 num, UCHAR *buf) { UINT4 netnum; memset(buf, 0, 8); netnum = htonl(num); memcpy(buf + 4, &netnum, 4); return 0; } static int tls_check_mac(ssl_rec_decoder *d, int ct, int ver, UCHAR *data, UINT4 datalen, UCHAR *iv, UINT4 ivlen, UCHAR *mac) { HMAC_CTX *hm = HMAC_CTX_new(); if(!hm) ERETURN(R_NO_MEMORY); const EVP_MD *md; UINT4 l; UCHAR buf[128]; md = EVP_get_digestbyname(digests[d->cs->dig - 0x40]); HMAC_Init_ex(hm, d->mac_key->data, d->mac_key->len, md, NULL); fmt_seq(d->seq, buf); d->seq++; HMAC_Update(hm, buf, 8); buf[0] = ct; HMAC_Update(hm, buf, 1); buf[0] = MSB(ver); buf[1] = LSB(ver); HMAC_Update(hm, buf, 2); buf[0] = MSB(datalen); buf[1] = LSB(datalen); HMAC_Update(hm, buf, 2); /* for encrypt-then-mac with an explicit IV */ if(ivlen && iv) { HMAC_Update(hm, iv, ivlen); HMAC_Update(hm, data, datalen - ivlen); } else HMAC_Update(hm, data, datalen); HMAC_Final(hm, buf, &l); if(memcmp(mac, buf, l)) ERETURN(SSL_BAD_MAC); HMAC_CTX_free(hm); return 0; } int ssl3_check_mac(ssl_rec_decoder *d, int ct, int ver, UCHAR *data, UINT4 datalen, UCHAR *mac) { EVP_MD_CTX *mc = EVP_MD_CTX_new(); const EVP_MD *md; UINT4 l; UCHAR buf[64], dgst[20]; int pad_ct; pad_ct = (d->cs->dig == DIG_SHA) ? 40 : 48; md = EVP_get_digestbyname(digests[d->cs->dig - 0x40]); EVP_DigestInit(mc, md); EVP_DigestUpdate(mc, d->mac_key->data, d->mac_key->len); memset(buf, 0x36, pad_ct); EVP_DigestUpdate(mc, buf, pad_ct); fmt_seq(d->seq, buf); d->seq++; EVP_DigestUpdate(mc, buf, 8); buf[0] = ct; EVP_DigestUpdate(mc, buf, 1); buf[0] = MSB(datalen); buf[1] = LSB(datalen); EVP_DigestUpdate(mc, buf, 2); EVP_DigestUpdate(mc, data, datalen); EVP_DigestFinal(mc, dgst, &l); EVP_DigestInit(mc, md); EVP_DigestUpdate(mc, d->mac_key->data, d->mac_key->len); memset(buf, 0x5c, pad_ct); EVP_DigestUpdate(mc, buf, pad_ct); EVP_DigestUpdate(mc, dgst, l); EVP_DigestFinal(mc, dgst, &l); if(memcmp(mac, dgst, l)) ERETURN(SSL_BAD_MAC); EVP_MD_CTX_free(mc); return 0; } #endif ssldump-1.9/ssl/ssl_rec.h000066400000000000000000000071201470411077700154660ustar00rootroot00000000000000/** ssl_rec.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: ssl_rec.h,v 1.2 2000/10/17 16:10:02 ekr Exp $ ekr@rtfm.com Wed Aug 18 16:16:23 1999 */ #ifndef _ssl_rec_h #define _ssl_rec_h typedef struct ssl_rec_decoder_ ssl_rec_decoder; int ssl_destroy_rec_decoder PROTO_LIST((ssl_rec_decoder * *dp)); int ssl_create_rec_decoder PROTO_LIST( (ssl_rec_decoder * *dp, ssl_obj *ssl, UCHAR *mk, UCHAR *sk, UCHAR *iv)); int ssl_decode_rec_data PROTO_LIST((ssl_obj * ssl, ssl_rec_decoder *d, int ct, int version, UCHAR *in, int inl, UCHAR *out, int *outl)); int tls13_decode_rec_data PROTO_LIST((ssl_obj * ssl, ssl_rec_decoder *d, int ct, int version, UCHAR *in, int inl, UCHAR *out, int *outl)); int tls13_update_rec_key PROTO_LIST((ssl_rec_decoder * d, UCHAR *newkey, UCHAR *newiv)); int ssl3_check_mac(ssl_rec_decoder *d, int ct, int ver, UCHAR *data, UINT4 datalen, UCHAR *mac); #define IS_AEAD_CIPHER(cs) \ (cs->enc == 0x3b || cs->enc == 0x3c || cs->enc == 0x3d || cs->enc == 0x3e || \ cs->enc == 0x3f) #define IS_CCM_CIPHER(cs) (cs->enc == 0x3e || cs->enc == 0x3f) #endif ssldump-1.9/ssl/sslciphers.h000066400000000000000000000057431470411077700162240ustar00rootroot00000000000000/** sslciphers.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: sslciphers.h,v 1.3 2002/08/17 01:33:17 ekr Exp $ ekr@rtfm.com Tue Mar 30 18:11:55 1999 */ #ifndef _sslciphers_h #define _sslciphers_h typedef struct SSL_CipherSuite_ { int number; int kex; int sig; int enc; int block; int bits; int eff_bits; int dig; int dig_len; int export; } SSL_CipherSuite; #define KEX_RSA 0x10 #define KEX_DH 0x11 #define SIG_RSA 0x20 #define SIG_DSS 0x21 #define SIG_NONE 0x22 #define ENC_DES 0x30 #define ENC_3DES 0x31 #define ENC_RC4 0x32 #define ENC_RC2 0x33 #define ENC_IDEA 0x34 #define ENC_AES128 0x35 #define ENC_AES256 0x36 #define ENC_CAMELLIA128 0x37 #define ENC_CAMELLIA256 0x38 #define ENC_SEED 0x39 #define ENC_NULL 0x3a #define ENC_AES128_GCM 0x3b #define ENC_AES256_GCM 0x3c #define ENC_CHACHA20_POLY1305 0x3d #define ENC_AES128_CCM 0x3e #define ENC_AES128_CCM_8 0x3f #define DIG_MD5 0x40 #define DIG_SHA 0x41 #define DIG_SHA224 0x42 /* Not sure why EKR didn't follow RFC for */ #define DIG_SHA256 0x43 /* these values, but whatever, just adding on */ #define DIG_SHA384 0x44 #define DIG_SHA512 0x45 int ssl_find_cipher PROTO_LIST((int num, SSL_CipherSuite **cs)); #endif ssldump-1.9/ssl/ssldecode.c000066400000000000000000001116161470411077700160020ustar00rootroot00000000000000/** ssldecode.c Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: ssldecode.c,v 1.9 2002/08/17 01:33:17 ekr Exp $ ekr@rtfm.com Thu Apr 1 09:54:53 1999 */ #include "network.h" #include "ssl_h.h" #include "sslprint.h" #include "ssl.enums.h" #ifdef OPENSSL #include #include #include #include #include #include #include #endif #include "ssldecode.h" #include "ssl_rec.h" #include "r_assoc.h" #define PRF(ssl, secret, usage, rnd1, rnd2, out) \ (ssl->version == SSLV3_VERSION) \ ? ssl3_prf(ssl, secret, usage, rnd1, rnd2, out) \ : ((ssl->version == TLSV12_VERSION) \ ? tls12_prf(ssl, secret, usage, rnd1, rnd2, out) \ : tls_prf(ssl, secret, usage, rnd1, rnd2, out)) static char *ssl_password; extern char *digests[]; extern UINT4 SSL_print_flags; struct ssl_decode_ctx_ { #ifdef OPENSSL SSL_CTX *ssl_ctx; SSL *ssl; r_assoc *session_cache; FILE *ssl_key_log_file; #else char dummy; /* Some compilers (Win32) don't like empty structs */ #endif }; struct ssl_decoder_ { ssl_decode_ctx *ctx; Data *session_id; SSL_CipherSuite *cs; Data *client_random; Data *server_random; int ephemeral_rsa; Data *PMS; Data *MS; Data *SHTS; // Server Handshake traffic secret Data *CHTS; // Client Handshake traffic secret Data *STS; // Server traffic Secret Data *CTS; // Client traffic secret Data *handshake_messages; Data *session_hash; ssl_rec_decoder *c_to_s; ssl_rec_decoder *s_to_c; ssl_rec_decoder *c_to_s_n; ssl_rec_decoder *s_to_c_n; }; #ifdef OPENSSL static int tls_P_hash PROTO_LIST( (ssl_obj * ssl, Data *secret, Data *seed, const EVP_MD *md, Data *out)); static int tls12_prf PROTO_LIST((ssl_obj * ssl, Data *secret, char *usage, Data *rnd1, Data *rnd2, Data *out)); static int tls_prf PROTO_LIST((ssl_obj * ssl, Data *secret, char *usage, Data *rnd1, Data *rnd2, Data *out)); static int ssl3_prf PROTO_LIST((ssl_obj * ssl, Data *secret, char *usage, Data *rnd1, Data *rnd2, Data *out)); static int ssl3_generate_export_iv PROTO_LIST((ssl_obj * ssl, Data *rnd1, Data *rnd2, Data *out)); static int ssl_generate_keying_material PROTO_LIST((ssl_obj * ssl, ssl_decoder *d)); static int ssl_generate_session_hash PROTO_LIST((ssl_obj * ssl, ssl_decoder *d)); static int ssl_read_key_log_file PROTO_LIST((ssl_obj * obj, ssl_decoder *d)); #endif static int ssl_create_session_lookup_key PROTO_LIST( (ssl_obj * ssl, UCHAR *id, UINT4 idlen, UCHAR **keyp, UINT4 *keyl)); int ssl_save_session PROTO_LIST((ssl_obj * ssl, ssl_decoder *d)); int ssl_restore_session PROTO_LIST((ssl_obj * ssl, ssl_decoder *d)); /*The password code is not thread safe*/ static int password_cb(char *buf, int num, int rwflag, void *userdata) { if(num < strlen(ssl_password) + 1) return 0; strcpy(buf, ssl_password); return strlen(ssl_password); } int ssl_decode_ctx_create(ssl_decode_ctx **dp, char *keyfile, char *pass, char *keylogfile) { #ifdef OPENSSL ssl_decode_ctx *d = 0; int _status; SSL_library_init(); OpenSSL_add_all_algorithms(); if(!(d = (ssl_decode_ctx *)malloc(sizeof(ssl_decode_ctx)))) ABORT(R_NO_MEMORY); if(!(d->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) ABORT(R_NO_MEMORY); if(keyfile) { if(pass) { ssl_password = pass; SSL_CTX_set_default_passwd_cb(d->ssl_ctx, password_cb); } #if 0 if(SSL_CTX_use_certificate_file(d->ssl_ctx,keyfile,SSL_FILETYPE_PEM)!=1){ fprintf(stderr,"Problem loading certificate file\n"); ABORT(R_INTERNAL); } #endif if(SSL_CTX_use_PrivateKey_file(d->ssl_ctx, keyfile, SSL_FILETYPE_PEM) != 1) { fprintf(stderr, "Problem loading private key\n"); ABORT(R_INTERNAL); } } if(!(d->ssl = SSL_new(d->ssl_ctx))) ABORT(R_NO_MEMORY); if(r_assoc_create(&d->session_cache)) ABORT(R_NO_MEMORY); if(keylogfile) { if(!(d->ssl_key_log_file = fopen(keylogfile, "r"))) { fprintf(stderr, "Failed to open ssl key log file"); ABORT(R_INTERNAL); } } else { d->ssl_key_log_file = NULL; } X509V3_add_standard_extensions(); *dp = d; _status = 0; abort: return _status; #else return 0; #endif } int ssl_decode_ctx_destroy(ssl_decode_ctx **dp) { #ifdef OPENSSL ssl_decode_ctx *d = *dp; if(!d) return 0; if(d->ssl_key_log_file) { fclose(d->ssl_key_log_file); } r_assoc_destroy(&d->session_cache); SSL_CTX_free(d->ssl_ctx); SSL_free(d->ssl); free(d); #endif return 0; } int ssl_decoder_create(ssl_decoder **dp, ssl_decode_ctx *ctx) { int _status; ssl_decoder *d = 0; #ifdef OPENSSL if(!(d = (ssl_decoder *)calloc(1, sizeof(ssl_decoder)))) ABORT(R_NO_MEMORY); d->ctx = ctx; *dp = d; _status = 0; abort: if(_status) ssl_decoder_destroy(&d); return _status; #else return 0; #endif } int ssl_decoder_destroy(ssl_decoder **dp) { #ifdef OPENSSL ssl_decoder *d; if(!dp || !*dp) return 0; d = *dp; r_data_destroy(&d->client_random); r_data_destroy(&d->server_random); r_data_destroy(&d->session_id); r_data_destroy(&d->PMS); r_data_destroy(&d->MS); r_data_destroy(&d->handshake_messages); r_data_destroy(&d->session_hash); ssl_destroy_rec_decoder(&d->c_to_s); ssl_destroy_rec_decoder(&d->c_to_s_n); ssl_destroy_rec_decoder(&d->s_to_c); ssl_destroy_rec_decoder(&d->s_to_c_n); free(d); *dp = 0; #endif return 0; } int ssl_set_client_random(ssl_decoder *d, UCHAR *msg, int len) { #ifdef OPENSSL int r; r_data_destroy(&d->client_random); if((r = r_data_create(&d->client_random, msg, len))) ERETURN(r); #endif return 0; } int ssl_set_server_random(ssl_decoder *d, UCHAR *msg, int len) { #ifdef OPENSSL int r; r_data_destroy(&d->server_random); if((r = r_data_create(&d->server_random, msg, len))) ERETURN(r); #endif return 0; } int ssl_set_client_session_id(ssl_decoder *d, UCHAR *msg, int len) { #ifdef OPENSSL int r; if(len > 0) { r_data_destroy(&d->session_id); if((r = r_data_create(&d->session_id, msg, len))) ERETURN(r); } #endif return 0; } int ssl_process_server_session_id(ssl_obj *ssl, ssl_decoder *d, UCHAR *msg, int len) { #ifdef OPENSSL int r, _status; Data idd; int restored = 0; INIT_DATA(idd, msg, len); if(ssl->version == TLSV13_VERSION) { // No need to save/restore session in tls1.3 since the only way of // decrypting is through log file } else { /* First check to see if the client tried to restore */ if(d->session_id) { /* Now check to see if we restored */ if((r = r_data_compare(&idd, d->session_id))) ABORT(r); /* Now try to look up the session. We may not be able to find it if, for instance, the original session was initiated with something other than static RSA */ if((r = ssl_restore_session(ssl, d))) ABORT(r); restored = 1; } } _status = 0; abort: if(!restored) { /* Copy over the session ID */ r_data_destroy(&d->session_id); r_data_create(&d->session_id, msg, len); } return _status; #else return 0; #endif } int ssl_process_client_session_id(ssl_obj *ssl, ssl_decoder *d, UCHAR *msg, int len) { #ifdef OPENSSL int _status; /* First check if the client set session id */ // todo: check that session_id in decoder and msg are the same (and if not // then take from msg?) if(d->session_id) { /* Remove the master secret */ // todo: better save and destroy only when successfully read key log r_data_destroy(&d->MS); if(d->ctx->ssl_key_log_file && (ssl_read_key_log_file(ssl, d) == 0) && d->MS) { // we found master secret for session in keylog // try to save session _status = ssl_save_session(ssl, d); } else { // just return error _status = -1; } } else { _status = -1; } return _status; #else return 0; #endif } int ssl_process_handshake_finished(ssl_obj *ssl, ssl_decoder *dec, Data *data) { if(ssl->version == TLSV13_VERSION) { if(ssl->direction == DIR_I2R) { // Change from handshake decoder to data traffic decoder dec->c_to_s = dec->c_to_s_n; dec->c_to_s_n = 0; } else { dec->s_to_c = dec->s_to_c_n; dec->s_to_c_n = 0; } } return 0; } int ssl_process_change_cipher_spec(ssl_obj *ssl, ssl_decoder *d, int direction) { #ifdef OPENSSL if(ssl->version != TLSV13_VERSION) { if(direction == DIR_I2R) { d->c_to_s = d->c_to_s_n; d->c_to_s_n = 0; if(d->c_to_s) ssl->process_ciphertext |= direction; } else { d->s_to_c = d->s_to_c_n; d->s_to_c_n = 0; if(d->s_to_c) ssl->process_ciphertext |= direction; } } #endif return 0; } int ssl_decode_record(ssl_obj *ssl, ssl_decoder *dec, int direction, int ct, int version, Data *d) { ssl_rec_decoder *rd; UCHAR *out; int outl; int r, _status; UINT4 state; if(dec) rd = (direction == DIR_I2R) ? dec->c_to_s : dec->s_to_c; else rd = 0; state = (direction == DIR_I2R) ? ssl->i_state : ssl->r_state; if(ssl->version == TLSV13_VERSION && ct != 23) { // Only type 23 is encrypted in tls1.3 ssl->record_encryption = REC_PLAINTEXT; return 0; } else if(!rd) { if(state & SSL_ST_SENT_CHANGE_CIPHER_SPEC) { ssl->record_encryption = REC_CIPHERTEXT; return SSL_NO_DECRYPT; } else { ssl->record_encryption = REC_PLAINTEXT; return 0; } } ssl->record_encryption = REC_CIPHERTEXT; #ifdef OPENSSL if(!(out = (UCHAR *)malloc(d->len))) ABORT(R_NO_MEMORY); if(ssl->version == TLSV13_VERSION) { r = tls13_decode_rec_data(ssl, rd, ct, version, d->data, d->len, out, &outl); } else { r = ssl_decode_rec_data(ssl, rd, ct, version, d->data, d->len, out, &outl); } if(r) { ABORT(r); } memcpy(d->data, out, outl); d->len = outl; ssl->record_encryption = REC_DECRYPTED_CIPHERTEXT; _status = 0; abort: FREE(out); return _status; #else return 0; #endif } int ssl_update_handshake_messages(ssl_obj *ssl, Data *data) { #ifdef OPENSSL Data *hms; UCHAR *d; int l, r; hms = ssl->decoder->handshake_messages; d = data->data - 4; l = data->len + 4; if(hms) { if(!(hms->data = realloc(hms->data, l + hms->len))) ERETURN(R_NO_MEMORY); memcpy(hms->data + hms->len, d, l); hms->len += l; } else { if((r = r_data_create(&hms, d, l))) ERETURN(r); ssl->decoder->handshake_messages = hms; } #endif return 0; } static int ssl_create_session_lookup_key(ssl_obj *ssl, UCHAR *id, UINT4 idlen, UCHAR **keyp, UINT4 *keyl) { UCHAR *key = 0; UINT4 l; int _status; l = idlen + strlen(ssl->server_name) + idlen + 15; /* HOST + PORT + id */ if(!(key = (UCHAR *)malloc(l))) ABORT(R_NO_MEMORY); *keyp = key; memcpy(key, id, idlen); *keyl = idlen; key += idlen; snprintf((char *)key, l, "%s:%d", ssl->server_name, ssl->server_port); *keyl += strlen((char *)key); _status = 0; abort: return _status; } /* Look up the session id in the session cache and generate the appropriate keying material */ int ssl_restore_session(ssl_obj *ssl, ssl_decoder *d) { UCHAR *lookup_key = 0; void *msv; Data *msd; int lookup_key_len; int r, _status; #ifdef OPENSSL if((r = ssl_create_session_lookup_key(ssl, d->session_id->data, d->session_id->len, &lookup_key, (UINT4 *)&lookup_key_len))) ABORT(r); if((r = r_assoc_fetch(d->ctx->session_cache, (char *)lookup_key, lookup_key_len, &msv))) ABORT(r); msd = (Data *)msv; if((r = r_data_create(&d->MS, msd->data, msd->len))) ABORT(r); CRDUMPD("Restored MS", d->MS); switch(ssl->version) { case SSLV3_VERSION: case TLSV1_VERSION: case TLSV11_VERSION: case TLSV12_VERSION: case TLSV13_VERSION: if((r = ssl_generate_keying_material(ssl, d))) ABORT(r); break; default: ABORT(SSL_CANT_DO_CIPHER); } _status = 0; abort: FREE(lookup_key); return _status; #else return 0; #endif } /* Look up the session id in the session cache and generate the appropriate keying material */ int ssl_save_session(ssl_obj *ssl, ssl_decoder *d) { #ifdef OPENSSL UCHAR *lookup_key = 0; Data *msd = 0; int lookup_key_len; int r, _status; if((r = ssl_create_session_lookup_key(ssl, d->session_id->data, d->session_id->len, &lookup_key, (UINT4 *)&lookup_key_len))) ABORT(r); if((r = r_data_create(&msd, d->MS->data, d->MS->len))) ABORT(r); if((r = r_assoc_insert(d->ctx->session_cache, (char *)lookup_key, lookup_key_len, (void *)msd, 0, (int (*)(void *))r_data_zfree, R_ASSOC_NEW | R_ASSOC_REPLACE))) ABORT(r); _status = 0; abort: if(_status) { r_data_zfree(msd); } FREE(lookup_key); return _status; #else return 0; #endif } /* This only works with RSA because the other cipher suites offer PFS. Yuck. */ int ssl_process_client_key_exchange(ssl_obj *ssl, ssl_decoder *d, UCHAR *msg, int len) { #ifdef OPENSSL int r, _status; int i; EVP_PKEY *pk; const BIGNUM *n; /* Remove the master secret if it was there to force keying material regeneration in case we're renegotiating */ r_data_destroy(&d->MS); if(!d->ctx->ssl_key_log_file || ssl_read_key_log_file(ssl, d) || !d->MS) { if(ssl->cs->kex != KEX_RSA) return -1; if(d->ephemeral_rsa) return -1; pk = SSL_get_privatekey(d->ctx->ssl); if(!pk) return -1; if(EVP_PKEY_id(pk) != EVP_PKEY_RSA) return -1; RSA_get0_key(EVP_PKEY_get0_RSA(pk), &n, NULL, NULL); if((r = r_data_alloc(&d->PMS, BN_num_bytes(n)))) ABORT(r); i = RSA_private_decrypt(len, msg, d->PMS->data, EVP_PKEY_get0_RSA(pk), RSA_PKCS1_PADDING); if(i != 48) ABORT(SSL_BAD_PMS); d->PMS->len = 48; CRDUMPD("PMS", d->PMS); } switch(ssl->version) { case SSLV3_VERSION: case TLSV1_VERSION: case TLSV11_VERSION: case TLSV12_VERSION: case TLSV13_VERSION: if((r = ssl_generate_keying_material(ssl, d))) ABORT(r); break; default: ABORT(SSL_CANT_DO_CIPHER); } /* Now store the data in the session cache */ if((r = ssl_save_session(ssl, d))) ABORT(r); _status = 0; abort: return _status; #else return 0; #endif } #ifdef OPENSSL static int tls_P_hash(ssl_obj *ssl, Data *secret, Data *seed, const EVP_MD *md, Data *out) { UCHAR *ptr = out->data; int left = out->len; int tocpy; UCHAR *A; UCHAR _A[128], tmp[128]; unsigned int A_l, tmp_l; HMAC_CTX *hm = HMAC_CTX_new(); CRDUMPD("P_hash secret", secret); CRDUMPD("P_hash seed", seed); A = seed->data; A_l = seed->len; while(left) { HMAC_Init_ex(hm, secret->data, secret->len, md, NULL); HMAC_Update(hm, A, A_l); HMAC_Final(hm, _A, &A_l); A = _A; HMAC_Init_ex(hm, secret->data, secret->len, md, NULL); HMAC_Update(hm, A, A_l); HMAC_Update(hm, seed->data, seed->len); HMAC_Final(hm, tmp, &tmp_l); tocpy = MIN(left, tmp_l); memcpy(ptr, tmp, tocpy); ptr += tocpy; left -= tocpy; } HMAC_CTX_free(hm); CRDUMPD("P_hash out", out); return 0; } static int tls_prf(ssl_obj *ssl, Data *secret, char *usage, Data *rnd1, Data *rnd2, Data *out) { int r, _status; Data *md5_out = 0, *sha_out = 0; Data *seed; UCHAR *ptr; Data *S1 = 0, *S2 = 0; int i, S_l; if((r = r_data_alloc(&md5_out, MAX(out->len, 16)))) ABORT(r); if((r = r_data_alloc(&sha_out, MAX(out->len, 20)))) ABORT(r); if((r = r_data_alloc(&seed, strlen(usage) + rnd1->len + rnd2->len))) ABORT(r); ptr = seed->data; memcpy(ptr, usage, strlen(usage)); ptr += strlen(usage); memcpy(ptr, rnd1->data, rnd1->len); ptr += rnd1->len; memcpy(ptr, rnd2->data, rnd2->len); ptr += rnd2->len; S_l = secret->len / 2 + secret->len % 2; if((r = r_data_alloc(&S1, S_l))) ABORT(r); if((r = r_data_alloc(&S2, S_l))) ABORT(r); memcpy(S1->data, secret->data, S_l); memcpy(S2->data, secret->data + (secret->len - S_l), S_l); if((r = tls_P_hash(ssl, S1, seed, EVP_get_digestbyname("MD5"), md5_out))) ABORT(r); if((r = tls_P_hash(ssl, S2, seed, EVP_get_digestbyname("SHA1"), sha_out))) ABORT(r); for(i = 0; i < out->len; i++) out->data[i] = md5_out->data[i] ^ sha_out->data[i]; CRDUMPD("PRF out", out); _status = 0; abort: r_data_destroy(&md5_out); r_data_destroy(&sha_out); r_data_destroy(&seed); r_data_destroy(&S1); r_data_destroy(&S2); return _status; } static int tls12_prf(ssl_obj *ssl, Data *secret, char *usage, Data *rnd1, Data *rnd2, Data *out) { const EVP_MD *md; int r, _status; Data *sha_out = 0; Data *seed; UCHAR *ptr; int i, dgi; if((r = r_data_alloc(&sha_out, MAX(out->len, 64)))) /* assume max SHA512 */ ABORT(r); if((r = r_data_alloc(&seed, strlen(usage) + rnd1->len + rnd2->len))) ABORT(r); ptr = seed->data; memcpy(ptr, usage, strlen(usage)); ptr += strlen(usage); memcpy(ptr, rnd1->data, rnd1->len); ptr += rnd1->len; memcpy(ptr, rnd2->data, rnd2->len); ptr += rnd2->len; /* Earlier versions of openssl didn't have SHA256 of course... */ dgi = MAX(DIG_SHA256, ssl->cs->dig); dgi -= 0x40; if((md = EVP_get_digestbyname(digests[dgi])) == NULL) { DBG((0, "Cannot get EVP for digest %s, openssl library current?", digests[dgi])); ERETURN(SSL_BAD_MAC); } if((r = tls_P_hash(ssl, secret, seed, md, sha_out))) ABORT(r); for(i = 0; i < out->len; i++) out->data[i] = sha_out->data[i]; CRDUMPD("PRF out", out); _status = 0; abort: r_data_destroy(&sha_out); r_data_destroy(&seed); return _status; } static int ssl3_generate_export_iv(ssl_obj *ssl, Data *r1, Data *r2, Data *out) { MD5_CTX md5; UCHAR tmp[16]; MD5_Init(&md5); MD5_Update(&md5, r1->data, r1->len); MD5_Update(&md5, r2->data, r2->len); MD5_Final(tmp, &md5); memcpy(out->data, tmp, out->len); return 0; } static int ssl3_prf(ssl_obj *ssl, Data *secret, char *usage, Data *r1, Data *r2, Data *out) { MD5_CTX md5; SHA_CTX sha; Data *rnd1, *rnd2; int off; int i = 0, j; UCHAR buf[20]; rnd1 = r1; rnd2 = r2; CRDUMPD("Secret", secret); CRDUMPD("RND1", rnd1); CRDUMPD("RND2", rnd2); MD5_Init(&md5); memset(&sha, 0, sizeof(sha)); SHA1_Init(&sha); for(off = 0; off < out->len; off += 16) { char outbuf[16]; int tocpy; i++; /* A, BB, CCC, ... */ for(j = 0; j < i; j++) { buf[j] = 64 + i; } SHA1_Update(&sha, buf, i); CRDUMP("BUF", buf, i); if(secret) SHA1_Update(&sha, secret->data, secret->len); CRDUMPD("secret", secret); if(!strcmp(usage, "client write key") || !strcmp(usage, "server write key")) { SHA1_Update(&sha, rnd2->data, rnd2->len); CRDUMPD("rnd2", rnd2); SHA1_Update(&sha, rnd1->data, rnd1->len); CRDUMPD("rnd1", rnd1); } else { SHA1_Update(&sha, rnd1->data, rnd1->len); CRDUMPD("rnd1", rnd1); SHA1_Update(&sha, rnd2->data, rnd2->len); CRDUMPD("rnd2", rnd2); } SHA1_Final(buf, &sha); CRDUMP("SHA out", buf, 20); SHA1_Init(&sha); MD5_Update(&md5, secret->data, secret->len); MD5_Update(&md5, buf, 20); MD5_Final((unsigned char *)outbuf, &md5); tocpy = MIN(out->len - off, 16); memcpy(out->data + off, outbuf, tocpy); CRDUMP("MD5 out", (UCHAR *)outbuf, 16); MD5_Init(&md5); } return 0; } static int ssl_generate_keying_material(ssl_obj *ssl, ssl_decoder *d) { Data *key_block = 0, temp; UCHAR _iv_c[8], _iv_s[8]; UCHAR _key_c[16], _key_s[16]; int needed; int r, _status; UCHAR *ptr, *c_wk, *s_wk, *c_mk = NULL, *s_mk = NULL, *c_iv = NULL, *s_iv = NULL; if(!d->MS) { if((r = r_data_alloc(&d->MS, 48))) ABORT(r); if(ssl->extensions->extended_master_secret == 2) { if((r = ssl_generate_session_hash(ssl, d))) ABORT(r); temp.len = 0; if((r = PRF(ssl, d->PMS, "extended master secret", d->session_hash, &temp, d->MS))) ABORT(r); } else if((r = PRF(ssl, d->PMS, "master secret", d->client_random, d->server_random, d->MS))) ABORT(r); CRDUMPD("MS", d->MS); } /* Compute the key block. First figure out how much data we need*/ /* Ideally find a cleaner way to check for AEAD cipher */ needed = !IS_AEAD_CIPHER(ssl->cs) ? ssl->cs->dig_len * 2 : 0; needed += ssl->cs->bits / 4; if(ssl->cs->block > 1) needed += ssl->cs->block * 2; if((r = r_data_alloc(&key_block, needed))) ABORT(r); if((r = PRF(ssl, d->MS, "key expansion", d->server_random, d->client_random, key_block))) ABORT(r); ptr = key_block->data; /* Ideally find a cleaner way to check for AEAD cipher */ if(!IS_AEAD_CIPHER(ssl->cs)) { c_mk = ptr; ptr += ssl->cs->dig_len; s_mk = ptr; ptr += ssl->cs->dig_len; } c_wk = ptr; ptr += ssl->cs->eff_bits / 8; s_wk = ptr; ptr += ssl->cs->eff_bits / 8; if(ssl->cs->block > 1) { c_iv = ptr; ptr += ssl->cs->block; s_iv = ptr; ptr += ssl->cs->block; } if(ssl->cs->export) { Data iv_c, iv_s; Data key_c, key_s; Data k; if(ssl->cs->block > 1) { ATTACH_DATA(iv_c, _iv_c); ATTACH_DATA(iv_s, _iv_s); if(ssl->version == SSLV3_VERSION) { if((r = ssl3_generate_export_iv(ssl, d->client_random, d->server_random, &iv_c))) ABORT(r); if((r = ssl3_generate_export_iv(ssl, d->server_random, d->client_random, &iv_s))) ABORT(r); } else { UCHAR _iv_block[16]; Data iv_block; Data key_null; UCHAR _key_null; INIT_DATA(key_null, &_key_null, 0); /* We only have room for 8 bit IVs, but that's all we should need. This is a sanity check */ if(ssl->cs->block > 8) ABORT(R_INTERNAL); ATTACH_DATA(iv_block, _iv_block); if((r = PRF(ssl, &key_null, "IV block", d->client_random, d->server_random, &iv_block))) ABORT(r); memcpy(_iv_c, iv_block.data, 8); memcpy(_iv_s, iv_block.data + 8, 8); } c_iv = _iv_c; s_iv = _iv_s; } if(ssl->version == SSLV3_VERSION) { MD5_CTX md5; MD5_Init(&md5); MD5_Update(&md5, c_wk, ssl->cs->eff_bits / 8); MD5_Update(&md5, d->client_random->data, d->client_random->len); MD5_Update(&md5, d->server_random->data, d->server_random->len); MD5_Final(_key_c, &md5); c_wk = _key_c; MD5_Init(&md5); MD5_Update(&md5, s_wk, ssl->cs->eff_bits / 8); MD5_Update(&md5, d->server_random->data, d->server_random->len); MD5_Update(&md5, d->client_random->data, d->client_random->len); MD5_Final(_key_s, &md5); s_wk = _key_s; } else { ATTACH_DATA(key_c, _key_c); ATTACH_DATA(key_s, _key_s); INIT_DATA(k, c_wk, ssl->cs->eff_bits / 8); if((r = PRF(ssl, &k, "client write key", d->client_random, d->server_random, &key_c))) ABORT(r); c_wk = _key_c; INIT_DATA(k, s_wk, ssl->cs->eff_bits / 8); if((r = PRF(ssl, &k, "server write key", d->client_random, d->server_random, &key_s))) ABORT(r); s_wk = _key_s; } } if(!IS_AEAD_CIPHER(ssl->cs)) { CRDUMP("Client MAC key", c_mk, ssl->cs->dig_len); CRDUMP("Server MAC key", s_mk, ssl->cs->dig_len); } CRDUMP("Client Write key", c_wk, ssl->cs->bits / 8); CRDUMP("Server Write key", s_wk, ssl->cs->bits / 8); if(ssl->cs->block > 1) { CRDUMP("Client Write IV", c_iv, ssl->cs->block); CRDUMP("Server Write IV", s_iv, ssl->cs->block); } if((r = ssl_create_rec_decoder(&d->c_to_s_n, ssl, c_mk, c_wk, c_iv))) ABORT(r); if((r = ssl_create_rec_decoder(&d->s_to_c_n, ssl, s_mk, s_wk, s_iv))) ABORT(r); _status = 0; abort: if(key_block) { r_data_zfree(key_block); free(key_block); } return _status; } static int hkdf_expand_label(ssl_obj *ssl, ssl_decoder *d, Data *secret, char *label, Data *context, uint16_t length, UCHAR **out) { int r = -1; size_t outlen = length; EVP_PKEY_CTX *pctx; pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL); Data hkdf_label; UCHAR *ptr; // Construct HkdfLabel hkdf_label.data = ptr = malloc(512); *(uint16_t *)ptr = ntohs(length); ptr += 2; *(uint8_t *)ptr++ = 6 + (label ? strlen(label) : 0); memcpy(ptr, "tls13 ", 6); ptr += 6; if(label) { memcpy(ptr, label, strlen(label)); ptr += strlen(label); } *(uint8_t *)ptr++ = context ? context->len : 0; if(context) { memcpy(ptr, context->data, context->len); ptr += context->len; } hkdf_label.len = ptr - hkdf_label.data; CRDUMPD("hkdf_label", &hkdf_label); // Load parameters *out = malloc(length); if(EVP_PKEY_derive_init(pctx) <= 0) { fprintf(stderr, "EVP_PKEY_derive_init failed\n"); } /* Error */ if(EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) <= 0) { fprintf(stderr, "EVP_PKEY_CTX_hkdf_mode failed\n"); goto abort; } if(EVP_PKEY_CTX_set_hkdf_md( pctx, EVP_get_digestbyname(digests[ssl->cs->dig - 0x40])) <= 0) { fprintf(stderr, "EVP_PKEY_CTX_set_hkdf_md failed\n"); goto abort; } if(EVP_PKEY_CTX_set1_hkdf_key(pctx, secret->data, secret->len) <= 0) { fprintf(stderr, "EVP_PKEY_CTX_set_hkdf_md failed\n"); goto abort; } if(EVP_PKEY_CTX_add1_hkdf_info(pctx, hkdf_label.data, hkdf_label.len) <= 0) { fprintf(stderr, "EVP_PKEY_CTX_add1_hkdf_info failed\n"); goto abort; } if(EVP_PKEY_derive(pctx, *out, &outlen) <= 0) { fprintf(stderr, "EVP_PKEY_derive failed\n"); goto abort; } CRDUMP("out_hkdf", *out, outlen); return 0; abort: ERR_print_errors_fp(stderr); return r; } // Will update the keys for the particular direction int ssl_tls13_update_keying_material(ssl_obj *ssl, ssl_decoder *d, int direction) { Data *secret; ssl_rec_decoder *decoder; UCHAR *newsecret; UCHAR *newkey; UCHAR *newiv; if(direction == DIR_I2R) { secret = d->CTS; decoder = d->c_to_s; } else { secret = d->STS; decoder = d->s_to_c; } hkdf_expand_label(ssl, d, secret, "traffic upd", NULL, ssl->cs->dig_len, &newsecret); secret->data = newsecret; hkdf_expand_label(ssl, d, secret, "key", NULL, ssl->cs->eff_bits / 8, &newkey); hkdf_expand_label(ssl, d, secret, "iv", NULL, 12, &newiv); tls13_update_rec_key(decoder, newkey, newiv); return 0; } int ssl_tls13_generate_keying_material(ssl_obj *ssl, ssl_decoder *d) { int r, _status; UCHAR *s_wk_h, *s_iv_h, *c_wk_h, *c_iv_h, *s_wk, *s_iv, *c_wk, *c_iv; if(!(d->ctx->ssl_key_log_file && ssl_read_key_log_file(ssl, d) == 0 && d->SHTS && d->CHTS && d->STS && d->CTS)) { ABORT(-1); } // It is 12 for all ciphers if(hkdf_expand_label(ssl, d, d->SHTS, "key", NULL, ssl->cs->eff_bits / 8, &s_wk_h)) { fprintf(stderr, "s_wk_h hkdf_expand_label failed\n"); ABORT(-1); } if(hkdf_expand_label(ssl, d, d->SHTS, "iv", NULL, 12, &s_iv_h)) { fprintf(stderr, "s_iv_h hkdf_expand_label failed\n"); ABORT(-1); } if(hkdf_expand_label(ssl, d, d->CHTS, "key", NULL, ssl->cs->eff_bits / 8, &c_wk_h)) { fprintf(stderr, "c_wk_h hkdf_expand_label failed\n"); ABORT(-1); } if(hkdf_expand_label(ssl, d, d->CHTS, "iv", NULL, 12, &c_iv_h)) { fprintf(stderr, "c_iv_h hkdf_expand_label failed\n"); ABORT(-1); } if(hkdf_expand_label(ssl, d, d->STS, "key", NULL, ssl->cs->eff_bits / 8, &s_wk)) { fprintf(stderr, "s_wk hkdf_expand_label failed\n"); ABORT(-1); } if(hkdf_expand_label(ssl, d, d->STS, "iv", NULL, 12, &s_iv)) { fprintf(stderr, "s_iv hkdf_expand_label failed\n"); ABORT(-1); } if(hkdf_expand_label(ssl, d, d->CTS, "key", NULL, ssl->cs->eff_bits / 8, &c_wk)) { fprintf(stderr, "c_wk hkdf_expand_label failed\n"); ABORT(-1); } if(hkdf_expand_label(ssl, d, d->CTS, "iv", NULL, 12, &c_iv)) { fprintf(stderr, "c_iv hkdf_expand_label failed\n"); ABORT(-1); } CRDUMP("Server Handshake Write key", s_wk_h, ssl->cs->eff_bits / 8); CRDUMP("Server Handshake IV", s_iv_h, 12); CRDUMP("Client Handshake Write key", c_wk_h, ssl->cs->eff_bits / 8); CRDUMP("Client Handshake IV", c_iv_h, 12); CRDUMP("Server Write key", s_wk, ssl->cs->eff_bits / 8); CRDUMP("Server IV", s_iv, 12); CRDUMP("Client Write key", c_wk, ssl->cs->eff_bits / 8); CRDUMP("Client IV", c_iv, 12); if((r = ssl_create_rec_decoder(&d->c_to_s_n, ssl, NULL, c_wk, c_iv))) ABORT(r); if((r = ssl_create_rec_decoder(&d->s_to_c_n, ssl, NULL, s_wk, s_iv))) ABORT(r); if((r = ssl_create_rec_decoder(&d->c_to_s, ssl, NULL, c_wk_h, c_iv_h))) ABORT(r); if((r = ssl_create_rec_decoder(&d->s_to_c, ssl, NULL, s_wk_h, s_iv_h))) ABORT(r); return 0; abort: return _status; } static int ssl_generate_session_hash(ssl_obj *ssl, ssl_decoder *d) { int r, _status, dgi; unsigned int len; const EVP_MD *md; EVP_MD_CTX *dgictx = EVP_MD_CTX_create(); if((r = r_data_alloc(&d->session_hash, EVP_MAX_MD_SIZE))) ABORT(r); switch(ssl->version) { case TLSV12_VERSION: dgi = MAX(DIG_SHA256, ssl->cs->dig) - 0x40; if((md = EVP_get_digestbyname(digests[dgi])) == NULL) { DBG((0, "Cannot get EVP for digest %s, openssl library current?", digests[dgi])); ERETURN(SSL_BAD_MAC); } EVP_DigestInit(dgictx, md); EVP_DigestUpdate(dgictx, d->handshake_messages->data, d->handshake_messages->len); EVP_DigestFinal(dgictx, d->session_hash->data, (unsigned int *)&d->session_hash->len); break; case SSLV3_VERSION: case TLSV1_VERSION: case TLSV11_VERSION: EVP_DigestInit(dgictx, EVP_get_digestbyname("MD5")); EVP_DigestUpdate(dgictx, d->handshake_messages->data, d->handshake_messages->len); EVP_DigestFinal_ex(dgictx, d->session_hash->data, (unsigned int *)&d->session_hash->len); EVP_DigestInit(dgictx, EVP_get_digestbyname("SHA1")); EVP_DigestUpdate(dgictx, d->handshake_messages->data, d->handshake_messages->len); EVP_DigestFinal(dgictx, d->session_hash->data + d->session_hash->len, &len); d->session_hash->len += len; break; default: ABORT(SSL_CANT_DO_CIPHER); } _status = 0; abort: return _status; } static int read_hex_string(char *str, UCHAR *buf, int n) { unsigned int t; int i; for(i = 0; i < n; i++) { if(sscanf(str + i * 2, "%02x", &t) != 1) return -1; buf[i] = (char)t; } return 0; } static int ssl_read_key_log_file(ssl_obj *ssl, ssl_decoder *d) { int r = -1; int _status, n, i; size_t l = 0; char *line, *d_client_random, *label, *client_random, *secret; if(ssl->version == TLSV13_VERSION && !ssl->cs) // ssl->cs is not set when called from // ssl_process_client_session_id ABORT(r); if(!(d_client_random = malloc((d->client_random->len * 2) + 1))) ABORT(r); for(i = 0; i < d->client_random->len; i++) if(snprintf(d_client_random + (i * 2), 3, "%02x", d->client_random->data[i]) != 2) ABORT(r); while((n = getline(&line, &l, d->ctx->ssl_key_log_file)) != -1) { if(line[n - 1] == '\n') line[n - 1] = '\0'; if(!(label = strtok(line, " "))) continue; if(!(client_random = strtok(NULL, " ")) || strlen(client_random) != 64 || STRNICMP(client_random, d_client_random, 64)) continue; secret = strtok(NULL, " "); if(!(secret) || strlen(secret) != (ssl->version == TLSV13_VERSION ? ssl->cs->dig_len * 2 : 96)) continue; if(!strncmp(label, "CLIENT_RANDOM", 13)) { if((r = r_data_alloc(&d->MS, 48))) ABORT(r); if(read_hex_string(secret, d->MS->data, 48)) ABORT(r); } if(ssl->version != TLSV13_VERSION) continue; if(!strncmp(label, "SERVER_HANDSHAKE_TRAFFIC_SECRET", 31)) { if((r = r_data_alloc(&d->SHTS, ssl->cs->dig_len))) ABORT(r); if(read_hex_string(secret, d->SHTS->data, ssl->cs->dig_len)) ABORT(r); } else if(!strncmp(label, "CLIENT_HANDSHAKE_TRAFFIC_SECRET", 31)) { if((r = r_data_alloc(&d->CHTS, ssl->cs->dig_len))) ABORT(r); if(read_hex_string(secret, d->CHTS->data, ssl->cs->dig_len)) ABORT(r); } else if(!strncmp(label, "SERVER_TRAFFIC_SECRET_0", 23)) { if((r = r_data_alloc(&d->STS, ssl->cs->dig_len))) ABORT(r); if(read_hex_string(secret, d->STS->data, ssl->cs->dig_len)) ABORT(r); } else if(!strncmp(label, "CLIENT_TRAFFIC_SECRET_0", 23)) { if((r = r_data_alloc(&d->CTS, ssl->cs->dig_len))) ABORT(r); if(read_hex_string(secret, d->CTS->data, ssl->cs->dig_len)) ABORT(r); } /* Eventually add support for other labels defined here: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format */ } _status = 0; abort: if(d->ctx->ssl_key_log_file != NULL) fseek(d->ctx->ssl_key_log_file, 0, SEEK_SET); return _status; } #endif ssldump-1.9/ssl/ssldecode.h000066400000000000000000000103721470411077700160040ustar00rootroot00000000000000/** ssldecode.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: ssldecode.h,v 1.3 2001/07/20 23:33:16 ekr Exp $ ekr@rtfm.com Thu Apr 1 15:02:02 1999 */ #ifndef _ssldecode_h #define _ssldecode_h #define CRDUMP(a, b, c) \ P_(P_CR) { \ Data d; \ d.data = b; \ d.len = c; \ exdump(ssl, a, &d); \ LF; \ } #define CRDUMPD(a, b) \ P_(P_CR) { \ exdump(ssl, a, b); \ LF; \ } int ssl_decode_ctx_create PROTO_LIST( (ssl_decode_ctx * *ctx, char *keyfile, char *password, char *keylogfile)); int ssl_decode_ctx_destroy(ssl_decode_ctx **dp); int ssl_decoder_destroy PROTO_LIST((ssl_decoder * *dp)); int ssl_decoder_create PROTO_LIST((ssl_decoder * *dp, ssl_decode_ctx *ctx)); int ssl_set_client_random PROTO_LIST((ssl_decoder * dp, UCHAR *msg, int len)); int ssl_set_server_random PROTO_LIST((ssl_decoder * dp, UCHAR *msg, int len)); int ssl_set_client_session_id PROTO_LIST((ssl_decoder * dp, UCHAR *msg, int len)); int ssl_process_server_session_id PROTO_LIST((ssl_obj * obj, ssl_decoder *dp, UCHAR *msg, int len)); int ssl_process_client_session_id PROTO_LIST((ssl_obj * obj, ssl_decoder *dp, UCHAR *msg, int len)); int ssl_process_client_key_exchange PROTO_LIST((struct ssl_obj_ *, ssl_decoder *d, UCHAR *msg, int len)); int ssl_process_change_cipher_spec PROTO_LIST((ssl_obj * ssl, ssl_decoder *d, int direction)); int ssl_update_handshake_messages PROTO_LIST((ssl_obj * ssl, Data *data)); int ssl_decode_record PROTO_LIST((ssl_obj * ssl, ssl_decoder *dec, int direction, int ct, int version, Data *d)); int ssl_tls13_generate_keying_material PROTO_LIST((ssl_obj * obj, ssl_decoder *dec)); int ssl_process_handshake_finished PROTO_LIST((ssl_obj * ssl, ssl_decoder *dec, Data *data)); int ssl_tls13_update_keying_material PROTO_LIST((ssl_obj * ssl, ssl_decoder *dec, int dir)); #endif ssldump-1.9/ssl/sslprint.c000066400000000000000000000455441470411077700157210ustar00rootroot00000000000000/** sslprint.c Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: sslprint.c,v 1.8 2002/08/17 01:33:17 ekr Exp $ ekr@rtfm.com Tue Jan 12 18:06:39 1999 */ #include #include #include #include "network.h" #include "ssl_h.h" #include "sslprint.h" #include "ssl.enums.h" #include "ssldecode.h" extern decoder ContentType_decoder[]; extern decoder HandshakeType_decoder[]; #define BYTES_NEEDED(x) \ (x <= 255) ? 1 : ((x <= (1 << 16)) ? 2 : (x <= (1 << 24) ? 3 : 4)) int process_beginning_plaintext(ssl_obj *ssl, segment *seg, int direction) { Data d; if(seg->len == 0) return SSL_NO_DATA; d.data = seg->data; d.len = seg->len; /* this looks like SSL data. Ignore it*/ if(d.data[0] == 0x16) return SSL_BAD_CONTENT_TYPE; if(logger) logger->vtbl->data(ssl->logger_obj, d.data, d.len, direction); P_(P_AD) { ssl_print_timestamp(ssl, &seg->p->ts); ssl_print_direction_indicator(ssl, direction); print_data(ssl, &d); LF; } return 0; } int process_v2_hello(ssl_obj *ssl, segment *seg) { int r; int rec_len; int _status; UINT4 cs_len; UINT4 sid_len; UINT4 chall_len; UINT4 ver; Data d; Data chall; UCHAR random[32]; if(seg->len == 0) ABORT(SSL_NO_DATA); d.data = seg->data; d.len = seg->len; /* First check the message length. */ if(d.len < 4) ABORT(SSL_BAD_CONTENT_TYPE); rec_len = ((d.data[0] & 0x7f) << 8) | (d.data[1]); d.data += 2; d.len -= 2; if(d.len != rec_len) /* Whatever this is it isn't valid SSLv2*/ ABORT(SSL_BAD_CONTENT_TYPE); /* If msg_type==1 then we've got a v2 message (or trash)*/ if(*d.data++ != 1) ABORT(SSL_BAD_CONTENT_TYPE); d.len--; SSL_DECODE_UINT16_ABORT(ssl, "Version number", P_DC, &d, &ver); /* We can't handle real v2 clients*/ if(ver <= 2) { explain(ssl, "Version 2 Client.\n"); ABORT(SSL_BAD_DATA); } ssl->cur_json_st = json_object_new_object(); ssl_print_record_num(ssl); ssl_print_timestamp(ssl, &seg->p->ts); ssl_print_direction_indicator(ssl, DIR_I2R); explain(ssl, " SSLv2 compatible client hello\n"); json_object_object_add(ssl->cur_json_st, "msg_type", json_object_new_string("Handshake")); json_object_object_add(ssl->cur_json_st, "handshake_type", json_object_new_string("ClientHello_v2_compat")); INDENT_INCR; P_(P_HL) { explain(ssl, "Version %d.%d ", (ver >> 8) & 0xff, ver & 0xff); LF; } SSL_DECODE_UINT16_ABORT(ssl, "cipher_spec_length", P_DC, &d, &cs_len); SSL_DECODE_UINT16_ABORT(ssl, "session_id_length", P_DC, &d, &sid_len); SSL_DECODE_UINT16_ABORT(ssl, "challenge_length", P_DC, &d, &chall_len); if(cs_len % 3) { fprintf(stderr, "Bad cipher spec length %d\n", cs_len); ABORT(SSL_BAD_DATA); } P_(P_HL) { explain(ssl, "cipher suites\n"); } for(; cs_len; cs_len -= 3) { UINT4 val; SSL_DECODE_UINT24_ABORT(ssl, 0, 0, &d, &val); ssl_print_cipher_suite(ssl, ver, P_HL, val); P_(P_HL) { explain(ssl, "\n"); } } if(sid_len != 0) { fprintf(stderr, "Session ID field should be zero length\n"); ABORT(SSL_BAD_DATA); } if(chall_len < 16 || chall_len > 32) { fprintf(stderr, "Invalid challenge length %d\n", chall_len); ABORT(SSL_BAD_DATA); } SSL_DECODE_OPAQUE_ARRAY_ABORT(ssl, 0, chall_len, 0, &d, &chall); P_(P_DC) { exdump(ssl, "Challenge", &chall); } memset(random, 0, 32); memcpy(random + (32 - chall_len), chall.data, chall_len); ssl_set_client_random(ssl->decoder, random, 32); ssl->i_state = SSL_ST_HANDSHAKE; P_(SSL_PRINT_HEXDUMP) { Data d; INIT_DATA(d, seg->data, seg->len); exdump(ssl, "Packet data", &d); LF; LF; } INDENT_POP; _status = 0; abort: if(ssl->cur_json_st) { if(SSL_print_flags & SSL_PRINT_JSON) printf("%s\n", json_object_to_json_string(ssl->cur_json_st)); json_object_put(ssl->cur_json_st); ssl->cur_json_st = NULL; } return _status; } int ssl_decode_switch(ssl_obj *ssl, decoder *dtable, int value, int dir, segment *seg, Data *data) { while(dtable && dtable->type != -1 && dtable->name != NULL) { if(dtable->type == value) { INDENT_INCR; explain(ssl, "%s", dtable->name); if(dtable->print) { INDENT_INCR; dtable->print(ssl, dir, seg, data); INDENT_POP; } INDENT_POP; return 0; } dtable++; } ERETURN(R_NOT_FOUND); } int ssl_expand_record(ssl_obj *ssl, segment *q, int direction, UCHAR *data, int len) { int r; Data d; UINT4 ct, vermaj, vermin, length; int version; char verstr[8]; char enumstr[20]; struct json_object *jobj; jobj = ssl->cur_json_st; d.data = data; d.len = len; /*This should be mapped to an enum*/ SSL_DECODE_UINT8(ssl, 0, 0, &d, &ct); SSL_DECODE_UINT8(ssl, 0, 0, &d, &vermaj); SSL_DECODE_UINT8(ssl, 0, 0, &d, &vermin); SSL_DECODE_UINT16(ssl, 0, 0, &d, &length); if(d.len != length) { explain(ssl, " Short record: %u bytes available (expecting: %u)\n", length, d.len); return 0; } version = ssl->version ? ssl->version : (vermaj * 256 + vermin); P_(P_RH) { explain(ssl, " V%d.%d(%d)", (version >> 8) & 0xff, version & 0xff, length); json_object_object_add(jobj, "record_len", json_object_new_int(length)); snprintf(verstr, 8, "%d.%d", (version >> 8) & 0xff, version & 0xff); json_object_object_add(jobj, "record_ver", json_object_new_string(verstr)); } r = ssl_decode_record(ssl, ssl->decoder, direction, ct, version, &d); if(r == SSL_BAD_MAC) { explain(ssl, " bad MAC\n"); return 0; } if(r) { if(!(SSL_print_flags & SSL_PRINT_JSON)) if((r = ssl_print_enum(ssl, 0, ContentType_decoder, ct))) { printf(" unknown record type: %d\n", ct); ERETURN(r); } if((r = ssl_get_enum_str(ssl, enumstr, ContentType_decoder, ct))) { strncpy(enumstr, "Unknown", 20); } json_object_object_add(jobj, "msg_type", json_object_new_string(enumstr)); if(!(SSL_print_flags & SSL_PRINT_JSON)) LF; } else { // try to save unencrypted data to logger // we must save record with type "application_data" (this is unencrypted // data) if(ct == 23) { if(logger) { logger->vtbl->data(ssl->logger_obj, d.data, d.len, direction); } if(ssl->version == TLSV13_VERSION) { ct = d.data[--d.len]; // In TLS 1.3 ct is stored in the end for // encrypted records } } if((r = ssl_decode_switch(ssl, ContentType_decoder, ct, direction, q, &d))) { if(!(SSL_print_flags & SSL_PRINT_JSON)) printf(" unknown record type: %d\n", ct); ERETURN(r); } } return 0; } int ssl_decode_uintX(ssl_obj *ssl, char *name, int size, UINT4 p, Data *data, UINT4 *x) { UINT4 v = 0; UINT4 _x; if(!x) x = &_x; if(size > data->len) { fprintf(stderr, "Short read: %d bytes available (expecting %d)\n", data->len, size); ERETURN(R_EOD); } while(size--) { v <<= 8; v |= *(data->data)++; data->len--; } P_(p) { explain(ssl, "%s = %d\n", name, *x); } *x = v; return 0; } int ssl_decode_opaque_array(ssl_obj *ssl, char *name, int size, UINT4 p, Data *data, Data *x) { UINT4 len; char n[1000]; int r; Data _x; if(!x) x = &_x; sprintf(n, "%s (length)", name ? name : ""); if(size < 0) { size *= -1; if((r = ssl_decode_uintX(ssl, n, BYTES_NEEDED(size), P_DC, data, &len))) ERETURN(r); } else { len = size; } if(len > data->len) { fprintf(stderr, "Not enough data. Found %d bytes (expecting %d)\n", data->len, size); ERETURN(R_EOD); } x->data = data->data; x->len = len; data->data += len; data->len -= len; P_(p) { exdump(ssl, name, x); } return 0; } int ssl_lookup_enum(ssl_obj *ssl, decoder *dtable, UINT4 val, char **ptr) { while(dtable && dtable->type != -1) { if(dtable->type == val) { *ptr = dtable->name; return 0; } dtable++; } return R_NOT_FOUND; } int ssl_decode_enum(ssl_obj *ssl, char *name, int size, decoder *dtable, UINT4 p, Data *data, UINT4 *x) { int r; UINT4 _x; if(!x) x = &_x; if((r = ssl_decode_uintX(ssl, name, size, 0, data, x))) ERETURN(r); P_(p) { if(!(SSL_print_flags & SSL_PRINT_JSON)) if((r = ssl_print_enum(ssl, name, dtable, *x))) ERETURN(r); } return 0; } int ssl_print_enum(ssl_obj *ssl, char *name, decoder *dtable, UINT4 value) { if(name) explain(ssl, "%s ", name); INDENT; while(dtable && dtable->type != -1) { if(dtable->type == value) { INDENT_INCR; explain(ssl, "%s", dtable->name); INDENT_POP; return 0; } dtable++; } LF; return R_NOT_FOUND; } int ssl_get_enum_str(ssl_obj *ssl, char *outstr, decoder *dtable, UINT4 value) { while(dtable && dtable->type != -1) { if(dtable->type == value) { strncpy(outstr, dtable->name, 20); return 0; } dtable++; } return R_NOT_FOUND; } int explain(ssl_obj *ssl, char *format, ...) { va_list ap; if(!(SSL_print_flags & SSL_PRINT_JSON)) { va_start(ap, format); P_(P_NR) { if(ssl->record_encryption == REC_DECRYPTED_CIPHERTEXT) printf("\\f(CI"); else printf("\\fC"); } INDENT; vprintf(format, ap); va_end(ap); } return 0; } int exdump(ssl_obj *ssl, char *name, Data *data) { int i; if(!(SSL_print_flags & SSL_PRINT_JSON)) { if(name) { explain(ssl, "%s[%d]=\n", name, data->len); INDENT_INCR; } P_(P_NR) { printf("\\f(CB"); } for(i = 0; i < data->len; i++) { if(!i) INDENT; if((data->len > 8) && i && !(i % 16)) { LF; INDENT; } printf("%.2x ", data->data[i] & 255); } P_(P_NR) { printf("\\fR"); } if(name) INDENT_POP; LF; } return 0; } int exstr(ssl_obj *ssl, char *outstr, Data *data) { int i; char *ptr = outstr; for(i = 0; i < data->len; i++) { sprintf(ptr, "%.2x", data->data[i] & 255); ptr += 2; if(i < data->len - 1) { sprintf(ptr, ":"); ++ptr; } } return 0; } int combodump(ssl_obj *ssl, char *name, Data *data) { UCHAR *ptr = data->data; int len = data->len; if(name) { explain(ssl, "%s[%d]=\n", name, data->len); INDENT_INCR; } while(len) { int i; int bytes = MIN(len, 16); INDENT; P_(P_NR) { if(ssl->record_encryption == REC_DECRYPTED_CIPHERTEXT) printf("\\f[CBI]"); else printf("\\f(CB"); } for(i = 0; i < bytes; i++) printf("%.2x ", ptr[i] & 255); /* Fill */ for(i = 0; i < (16 - bytes); i++) printf(" "); printf(" "); P_(P_NR) { if(ssl->record_encryption == REC_DECRYPTED_CIPHERTEXT) printf("\\f[CI]"); else printf("\\f(C"); } for(i = 0; i < bytes; i++) { if(isprint(ptr[i])) printf("%c", ptr[i]); else printf("."); } LF; len -= bytes; ptr += bytes; } P_(P_NR) { printf("\\fR"); } if(name) INDENT_POP; return 0; } int print_data(ssl_obj *ssl, Data *d) { int i, bit8 = 0; LF; for(i = 0; i < d->len; i++) { if(d->data[i] == 0 || (!isprint(d->data[i]) && !strchr("\r\n\t", d->data[i]))) { bit8 = 1; break; } } if(bit8) { INDENT; printf("---------------------------------------------------------------\n"); P_(P_HO) { exdump(ssl, 0, d); } else { combodump(ssl, 0, d); } INDENT; printf("---------------------------------------------------------------\n"); } else { int nl = 1; INDENT; printf("---------------------------------------------------------------\n"); if(SSL_print_flags & SSL_PRINT_NROFF) { if(ssl->process_ciphertext & ssl->direction) printf("\\f[CI]"); else printf("\\f(C"); } INDENT; for(i = 0; i < d->len; i++) { /* Escape leading . */ if(nl == 1 && (SSL_print_flags & SSL_PRINT_NROFF) && (d->data[i] == '.')) printf("\\&"); nl = 0; putchar(d->data[i]); if(d->data[i] == '\n') { nl = 1; INDENT; } } printf("---------------------------------------------------------------\n"); if(SSL_print_flags & SSL_PRINT_NROFF) { printf("\\f(R"); } } return 0; } int ssl_print_direction_indicator(ssl_obj *ssl, int dir) { struct json_object *jobj; #if 0 if(dir==DIR_I2R){ explain(ssl,"%s(%d) > %s>%d", ssl->client_name,ssl->client_port,ssl->server_name,ssl->server_port); } else{ explain(ssl,"%s(%d) > %s>%d", ssl->client_name,ssl->client_port,ssl->server_name,ssl->server_port); } #else jobj = ssl->cur_json_st; if(dir == DIR_I2R) { explain(ssl, "C>S"); if(jobj) { json_object_object_add(jobj, "src_name", json_object_new_string(ssl->client_name)); json_object_object_add(jobj, "src_ip", json_object_new_string(ssl->client_ip)); json_object_object_add(jobj, "src_port", json_object_new_int(ssl->client_port)); json_object_object_add(jobj, "dst_name", json_object_new_string(ssl->server_name)); json_object_object_add(jobj, "dst_ip", json_object_new_string(ssl->server_ip)); json_object_object_add(jobj, "dst_port", json_object_new_int(ssl->server_port)); } } else { explain(ssl, "S>C"); if(jobj) { json_object_object_add(jobj, "src_name", json_object_new_string(ssl->server_name)); json_object_object_add(jobj, "src_ip", json_object_new_string(ssl->server_ip)); json_object_object_add(jobj, "src_port", json_object_new_int(ssl->server_port)); json_object_object_add(jobj, "dst_name", json_object_new_string(ssl->client_name)); json_object_object_add(jobj, "dst_ip", json_object_new_string(ssl->client_ip)); json_object_object_add(jobj, "dst_port", json_object_new_int(ssl->client_port)); } } #endif return 0; } int ssl_print_timestamp(ssl_obj *ssl, struct timeval *ts) { struct timeval dt; int r; char ts_str[40]; struct json_object *jobj; jobj = ssl->cur_json_st; if(jobj) { snprintf(ts_str, 40, "%lld%c%4.4lld", (long long)ts->tv_sec, '.', (long long)ts->tv_usec / 100); json_object *j_ts_str = json_object_new_string(ts_str); json_object_object_add(jobj, "timestamp", j_ts_str); } if(SSL_print_flags & SSL_PRINT_TIMESTAMP_ABSOLUTE) { if(!(SSL_print_flags & SSL_PRINT_JSON)) explain(ssl, "%lld%c%4.4lld ", (long long)ts->tv_sec, '.', (long long)ts->tv_usec / 100); } else { if((r = timestamp_diff(ts, &ssl->time_start, &dt))) ERETURN(r); if(!(SSL_print_flags & SSL_PRINT_JSON)) explain(ssl, "%lld%c%4.4lld ", (long long)dt.tv_sec, '.', (long long)dt.tv_usec / 100); } if((r = timestamp_diff(ts, &ssl->time_last, &dt))) { ERETURN(r); } if(!(SSL_print_flags & SSL_PRINT_JSON)) explain(ssl, "(%lld%c%4.4lld) ", (long long)dt.tv_sec, '.', (long long)dt.tv_usec / 100); memcpy(&ssl->time_last, ts, sizeof(struct timeval)); return 0; } int ssl_print_record_num(ssl_obj *ssl) { struct json_object *jobj; jobj = ssl->cur_json_st; ssl->record_count++; if(!(SSL_print_flags & SSL_PRINT_JSON)) { if(SSL_print_flags & SSL_PRINT_NROFF) { printf("\\fI%d %d\\fR %s", ssl->conn->conn_number, ssl->record_count, ssl->record_count < 10 ? " " : ""); } else { printf("%d %d %s", ssl->conn->conn_number, ssl->record_count, ssl->record_count < 10 ? " " : ""); } } json_object_object_add(jobj, "connection_number", json_object_new_int(ssl->conn->conn_number)); json_object_object_add(jobj, "record_count", json_object_new_int(ssl->record_count)); return 0; } int ssl_print_cipher_suite(ssl_obj *ssl, int version, int p, UINT4 val) { char *str; char *prefix = version <= 0x300 ? "SSL_" : "TLS_"; int r; P_(p) { if((r = ssl_lookup_enum(ssl, cipher_suite_decoder, val, &str))) { explain(ssl, "Unknown value 0x%x", val); return 0; } /* Now the tricky bit. If the cipher suite begins with TLS_ and the version is SSLv3 then we replace it with SSL_*/ if(!strncmp(str, "TLS_", 4)) { explain(ssl, "%s%s", prefix, str + 4); } else { explain(ssl, "%s", str); } } return 0; } ssldump-1.9/ssl/sslprint.h000066400000000000000000000142451470411077700157200ustar00rootroot00000000000000/** sslprint.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: sslprint.h,v 1.3 2000/11/03 06:38:06 ekr Exp $ ekr@rtfm.com Wed Feb 10 15:34:14 1999 */ #ifndef _sslprint_h #define _sslprint_h #include "ssl_analyze.h" #include "ssl_h.h" int ssl_expand_record PROTO_LIST( (ssl_obj * ssl, segment *q, int direction, UCHAR *data, int len)); int ssl_decode_switch PROTO_LIST((ssl_obj * ssl, decoder *dtable, int value, int dir, segment *seg, Data *data)); int ssl_decode_uintX PROTO_LIST( (ssl_obj * ssl, char *name, int size, UINT4 print, Data *data, UINT4 *x)); int ssl_decode_opaque_array PROTO_LIST( (ssl_obj * ssl, char *name, int size, UINT4 print, Data *data, Data *x)); int ssl_decode_enum PROTO_LIST((ssl_obj * ssl, char *name, int size, decoder *decode, UINT4 p, Data *data, UINT4 *x)); int ssl_lookup_enum PROTO_LIST((ssl_obj * ssl, decoder *dtable, UINT4 val, char **ptr)); int ssl_print_enum PROTO_LIST((ssl_obj * obj, char *name, decoder *decode, UINT4 value)); int ssl_get_enum_str PROTO_LIST((ssl_obj * obj, char *outstr, decoder *decode, UINT4 value)); int print_data PROTO_LIST((ssl_obj * ssl, Data *d)); int process_v2_hello PROTO_LIST((ssl_obj * ssl, segment *seg)); int process_beginning_plaintext PROTO_LIST((ssl_obj * ssl, segment *seg, int direction)); int ssl_print_direction_indicator PROTO_LIST((ssl_obj * ssl, int dir)); int ssl_print_timestamp PROTO_LIST((ssl_obj * ssl, struct timeval *ts)); int ssl_print_record_num PROTO_LIST((ssl_obj * ssl)); int ssl_print_cipher_suite PROTO_LIST((ssl_obj * ssl, int version, int p, UINT4 val)); int explain PROTO_LIST((ssl_obj * ssl, char *format, ...)); int exdump PROTO_LIST((ssl_obj * ssl, char *name, Data *data)); int exstr PROTO_LIST((ssl_obj * ssl, char *name, Data *data)); #define SSL_DECODE_UINT8(a, n, b, c, d) \ if((r = ssl_decode_uintX(a, n, 1, b, c, d))) \ ERETURN(r) #define SSL_DECODE_UINT16(a, n, b, c, d) \ if((r = ssl_decode_uintX(a, n, 2, b, c, d))) \ ERETURN(r) #define SSL_DECODE_UINT24(a, n, b, c, d) \ if((r = ssl_decode_uintX(a, n, 3, b, c, d))) \ ERETURN(r) #define SSL_DECODE_UINT32(a, n, b, c, d) \ if((r = ssl_decode_uintX(a, n, 4, b, c, d))) \ ERETURN(r) #define SSL_DECODE_OPAQUE_ARRAY(a, n, b, c, d, e) \ if((r = ssl_decode_opaque_array(a, n, b, c, d, e))) \ ERETURN(r) #define SSL_DECODE_ENUM(a, b, c, d, e, f, g) \ if((r = ssl_decode_enum(a, b, c, d, e, f, g))) \ ERETURN(r) #define SSL_DECODE_UINT8_ABORT(a, n, b, c, d) \ if((r = ssl_decode_uintX(a, n, 1, b, c, d))) \ ABORT(r) #define SSL_DECODE_UINT16_ABORT(a, n, b, c, d) \ if((r = ssl_decode_uintX(a, n, 2, b, c, d))) \ ABORT(r) #define SSL_DECODE_UINT24_ABORT(a, n, b, c, d) \ if((r = ssl_decode_uintX(a, n, 3, b, c, d))) \ ABORT(r) #define SSL_DECODE_UINT32_ABORT(a, n, b, c, d) \ if((r = ssl_decode_uintX(a, n, 4, b, c, d))) \ ABORT(r) #define SSL_DECODE_OPAQUE_ARRAY_ABORT(a, n, b, c, d, e) \ if((r = ssl_decode_opaque_array(a, n, b, c, d, e))) \ ABORT(r) #define SSL_DECODE_ENUM_ABORT(a, b, c, d, e, f, g) \ if((r = ssl_decode_enum(a, b, c, d, e, f, g))) \ ABORT(r) #define P_(p) if((p == SSL_PRINT_ALL) || (p & SSL_print_flags)) #define INDENT \ if(!(NET_print_flags & NET_PRINT_JSON)) \ do { \ int i; \ for(i = 0; i < (ssl->indent_depth + ssl->indent_name_len); i++) \ printf("%s", SSL_print_flags &SSL_PRINT_NROFF ? " " : " "); \ } while(0) #define INDENT_INCR ssl->indent_depth += 2 #define INDENT_POP ssl->indent_depth -= 2 #define INDENT_NAME(x) ssl->indent_name_len += strlen(x) #define INDENT_NAME_POP ssl->indent_name_len = 0 #define LINE_LEFT (80-(ssl->indent_name_len + ssl->indent_depth) #define LF \ if(!(NET_print_flags & NET_PRINT_JSON)) \ printf("\n") #endif ssldump-1.9/ssl/sslxprint.c000066400000000000000000000147261470411077700161070ustar00rootroot00000000000000/** sslxprint.c Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: sslxprint.c,v 1.3 2000/11/03 06:38:06 ekr Exp $ ekr@rtfm.com Thu Mar 25 21:17:16 1999 */ #include #include "network.h" #include "ssl_h.h" #include "sslprint.h" #include "ssl.enums.h" #ifdef OPENSSL #include #include #include #endif #define BUFSIZE 1024 static int sslx__print_dn PROTO_LIST((ssl_obj * ssl, char *x)); #ifdef OPENSSL static int sslx__print_serial PROTO_LIST((ssl_obj * ssl, ASN1_INTEGER *a)); #endif int sslx_print_certificate(ssl_obj *ssl, Data *data, int pf) { #ifdef OPENSSL X509 *x = 0; ASN1_INTEGER *a; #endif UCHAR *d; int _status; struct json_object *cert_obj; #ifdef OPENSSL P_(P_ASN) { char buf[BUFSIZE]; int ext; char *b64_cert; char *serial_str = NULL; Data data_tmp; struct json_object *jobj; jobj = ssl->cur_json_st; cert_obj = json_object_new_object(); d = data->data; if(!(b64_cert = (char *)calloc( 1, sizeof(char) * ((((data->len) + 3 - 1) / 3) * 4 + 1)))) ABORT(R_NO_MEMORY); EVP_EncodeBlock((unsigned char *)b64_cert, d, data->len); json_object_object_add(cert_obj, "cert_der", json_object_new_string(b64_cert)); free(b64_cert); if(!(x = d2i_X509(0, (const unsigned char **)&d, data->len))) { explain(ssl, "Bad certificate"); ABORT(R_BAD_DATA); } X509_NAME_oneline(X509_get_subject_name(x), buf, BUFSIZE); explain(ssl, "Subject\n"); INDENT_INCR; json_object_object_add(cert_obj, "cert_subject", json_object_new_string(buf)); sslx__print_dn(ssl, buf); INDENT_POP; X509_NAME_oneline(X509_get_issuer_name(x), buf, BUFSIZE); explain(ssl, "Issuer\n"); INDENT_INCR; json_object_object_add(cert_obj, "cert_issuer", json_object_new_string(buf)); sslx__print_dn(ssl, buf); INDENT_POP; a = X509_get_serialNumber(x); explain(ssl, "Serial "); if(!(serial_str = (char *)calloc(1, sizeof(char) * (a->length * 3)))) ABORT(R_NO_MEMORY); INIT_DATA(data_tmp, a->data, a->length); exstr(ssl, serial_str, &data_tmp); json_object_object_add(cert_obj, "cert_serial", json_object_new_string(serial_str)); free(serial_str); sslx__print_serial(ssl, a); ext = X509_get_ext_count(x); if(ext > 0) { int i, j; UCHAR buf[1024]; explain(ssl, "Extensions\n"); INDENT_INCR; for(i = 0; i < ext; i++) { X509_EXTENSION *ex; ASN1_OBJECT *obj; ex = X509_get_ext(x, i); obj = X509_EXTENSION_get_object(ex); i2t_ASN1_OBJECT((char *)buf, sizeof(buf), obj); explain(ssl, "Extension: %s\n", buf); j = X509_EXTENSION_get_critical(ex); if(j) { INDENT; explain(ssl, "Critical\n"); } if(SSL_print_flags & SSL_PRINT_NROFF) { if(ssl->process_ciphertext & ssl->direction) printf("\\f(CI"); else printf("\\fC"); INDENT_INCR; INDENT; if(!X509V3_EXT_print_fp(stdout, ex, 0, 0)) { printf("Hex value"); } INDENT_POP; explain(ssl, "\n"); } } INDENT_POP; } else { #endif P_(pf) { exdump(ssl, "certificate", data); } #ifdef OPENSSL } struct json_object *certs_array; json_object_object_get_ex(jobj, "cert_chain", &certs_array); json_object_array_add(certs_array, cert_obj); } #endif _status = 0; abort: #ifdef OPENSSL if(x) X509_free(x); #endif if(_status && cert_obj) json_object_put(cert_obj); return _status; } int sslx_print_dn(ssl_obj *ssl, Data *data, int pf) { UCHAR buf[BUFSIZE]; int _status; UCHAR *d = data->data; #ifdef OPENSSL X509_NAME *n = 0; #endif P_(pf){ #ifdef OPENSSL P_(P_ASN){if(!(n = d2i_X509_NAME(0, (const unsigned char **)&d, data->len))) ABORT(R_BAD_DATA); X509_NAME_oneline(n, (char *)buf, BUFSIZE); sslx__print_dn(ssl, (char *)buf); } else { #endif exdump(ssl, 0, data); #ifdef OPENSSL } #endif } _status = 0; abort : #ifdef OPENSSL if(n) X509_NAME_free(n); #endif return _status; } static int sslx__print_dn(ssl_obj *ssl, char *x) { char *slash; if(*x == '/') x++; while(x) { if((slash = strchr(x, '/'))) { *slash = 0; } explain(ssl, "%s\n", x); x = slash ? slash + 1 : 0; }; return 0; } #ifdef OPENSSL static int sslx__print_serial(ssl_obj *ssl, ASN1_INTEGER *a) { Data d; if(a->length == 0) printf("0"); INIT_DATA(d, a->data, a->length); exdump(ssl, 0, &d); return 0; } #endif ssldump-1.9/ssl/sslxprint.h000066400000000000000000000042151470411077700161040ustar00rootroot00000000000000/** sslxprint.h Copyright (C) 1999-2000 RTFM, Inc. All Rights Reserved This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla and licensed by RTFM, Inc. 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. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Eric Rescorla for RTFM, Inc. 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. $Id: sslxprint.h,v 1.2 2000/10/17 16:10:02 ekr Exp $ ekr@rtfm.com Thu Mar 25 21:23:34 1999 */ #ifndef _sslxprint_h #define _sslxprint_h int sslx_print_certificate PROTO_LIST((ssl_obj * ssl, Data *data, int pf)); int sslx_print_dn PROTO_LIST((ssl_obj * ssl, Data *data, int pf)); #endif ssldump-1.9/ssldump.1000066400000000000000000000471521470411077700146440ustar00rootroot00000000000000.\" This file contains sections of the tcpdump man page, to which the .\" following copyright applies --EKR .\" Copyright (c) 1987, 1988, 1989, 1990, 1991, 1992, 1994, 1995, 1996, 1997 .\" The Regents of the University of California. All rights reserved. .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that: (1) source code distributions .\" retain the above copyright notice and this paragraph in its entirety, (2) .\" distributions including binary code include the above copyright notice and .\" this paragraph in its entirety in the documentation or other materials .\" provided with the distribution, and (3) all advertising materials mentioning .\" features or use of this software display the following acknowledgement: .\" ``This product includes software developed by the University of California, .\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of .\" the University nor the names of its contributors may be used to endorse .\" or promote products derived from this software without specific prior .\" written permission. .\" 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. .\" .\" Copyright (C) 1999-2000 RTFM, Inc. .\" All Rights Reserved .\" .\" This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla .\" and licensed by RTFM, Inc. .\" .\" 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. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" .\" This product includes software developed by Eric Rescorla for .\" RTFM, Inc. .\" .\" 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be .\" used to endorse or promote products derived from this .\" software without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. .TH SSLDUMP 1 "14th August 2023 - version 1.8" .SH NAME ssldump \- dump SSL traffic on a network .SH SYNOPSIS .na .B ssldump [ .B \-aAdeFHjnNPqtTvxXyz ] [ .B \-i .I interface ] .br .ti +8 [ .B \-k .I keyfile ] [ .B \-l .I sslkeylogfile ] [ .B \-p .I password ] [ .B \-r .I dumpfile ] [ .B \-w .I outputpcap ] .br .ti +8 [ .B \-S .RI [\| crypto \||\| d \||\| ht \||\| H \||\| nroff \|] ] [ .I expression ] .br .ad .SH DESCRIPTION .LP \fIssldump\fP is an SSL/TLS network protocol analyzer. It identifies TCP connections on the chosen network interface and attempts to interpret them as SSL/TLS traffic. When it identifies SSL/TLS traffic, it decodes the records and displays them in a textual form to stdout. If provided with the appropriate keying material, it will also decrypt the connections and display the application data traffic. It supports various version of SSL/TLS up to TLS version 1.3. It also includes support for JSON output or JA3 support. .LP \fIssldump\fP has been originally tested on FreeBSD, Linux, Solaris, and HP/UX. \fIssldump\fP has mainly a new build process and it's mainly tested on different Linux flavors. Since it's based on PCAP, it should work on most platforms. However, unlike tcpdump, \fIssldump\fP needs to be able to see both sides of the data transmission so you may have trouble using it with network taps such as SunOS nit that don't permit you to see transmitted data. .B Under SunOS with nit or bpf: To run .I ssldump you must have read access to .I /dev/nit or .IR /dev/bpf* . .B Under Solaris with dlpi: You must have read access to the network pseudo device, e.g. .IR /dev/le . .B Under HP-UX with dlpi: You must be root or it must be installed setuid to root. .B Under IRIX with snoop: You must be root or it must be installed setuid to root. .B Under Linux: You must be root or it must be installed setuid to root. .B Under Ultrix and Digital UNIX: Once the super-user has enabled promiscuous-mode operation using .IR pfconfig (8), any user may run .I ssldump .B Under BSD: You must have read access to .IR /dev/bpf* . .SH OPTIONS .TP .B \-a Print bare TCP ACKs (useful for observing Nagle behavior). .TP .B \-A Print all record fields (by default \fIssldump\fP chooses the most interesting fields). .TP .B \-d Display the application data traffic. This usually means decrypting it, but when -d is used \fIssldump\fP will also decode application data traffic \fIbefore\fP the SSL session initiates. This allows you to see HTTPS CONNECT behavior as well as SMTP STARTTLS. As a side effect, since \fIssldump\fP can't tell whether plaintext is traffic before the initiation of an SSL connection or just a regular TCP connection, this allows you to use \fIssldump\fP to sniff any TCP connection. \fIssldump\fP will automatically detect ASCII data and display it directly to the screen. non-ASCII data is displayed as hex dumps. See also -X. .TP .B \-e Print absolute timestamps instead of relative timestamps. .TP .B \-F Specify the number of packets after which a connection pool cleaning is performed (in packets, default: 100). .TP .B \-H Print the full SSL packet header. .TP .BI \-i " interface" Use \fIinterface\fP as the network interface on which to sniff SSL/TLS traffic. .TP .B \-j Switch output format to JSON. Only stdout is affected by this toggle. .TP .BI \-k " keyfile" Use \fIkeyfile\fP as the location of the SSL keyfile (OpenSSL format) Previous versions of \fIssldump\fP automatically looked in ./server.pem. Now you must specify your keyfile every time. .TP .BI \-l " sslkeylogfile" Use \fIsslkeylogfile\fP as the location of the SSLKEYLOGFILE (https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format). .TP .B \-n Don't try to resolve host names from IP addresses. .TP .B \-N Attempt to parse ASN.1 when it appears, such as in certificates and DNs. .TP .BI \-p " password" Use \fIpassword\fP as the SSL keyfile password. .TP .B \-P Don't put the interface into promiscuous mode. .TP .B \-q Don't decode any record fields beyond a single summary line. (quiet mode). .TP .BI \-r " file" Read data from \fIfile\fP instead of from the network. The old -f option still works but is deprecated and will probably be removed with the next version. .TP .BI \-S " [ " crypto " | " d " | " ht " | " H " ]" Specify SSL flags to \fIssldump\fP. These flags include: .RS .TP .I crypto Print cryptographic information. .TP .I d Print fields as decoded. .TP .I ht Print the handshake type. .TP .I H Print handshake type and highlights. .RE .TP .B \-t Specify the TTL for inactive connections referenced in the connection pool (in seconds, default: 100). .TP .B \-T Print the TCP headers. .TP .B \-v Display version and copyright information. .TP .BI \-w " outputpcap" Use \fIoutputpcap\fP as the destination for decrypted packets. .TP .B \-x Print each record in hex, as well as decoding it. .TP .B \-X When the -d option is used, binary data is automatically printed in two columns with a hex dump on the left and the printable characters on the right. -X suppresses the display of the printable characters, thus making it easier to cut and paste the hex data into some other program. .TP .B \-y Decorate the output for processing with nroff/troff. Not very useful for the average user. .TP .B \-z Add timestamp in front of TCP packet description (-T) .TP \fIexpression\fP .RS Selects what packets \fIssldump\fP will examine. Technically speaking, \fIssldump\fP supports the full expression syntax from PCAP and tcpdump. In fact, the description here is cribbed from the tcpdump man page. However, since \fIssldump\fP needs to examine full TCP streams, most of the tcpdump expressions will select traffic mixes that \fIssldump\fP will simply ignore. Only the expressions which don't result in incomplete TCP streams are listed here. .LP The \fIexpression\fP consists of one or more .IR primitives . Primitives usually consist of an .I id (name or number) preceded by one or more qualifiers. There are three different kinds of qualifier: .IP \fItype\fP qualifiers say what kind of thing the id name or number refers to. Possible types are .BR host , .B net and .BR port . E.g., `host foo', `net 128.3', `port 20'. If there is no type qualifier, .B host is assumed. .IP \fIdir\fP qualifiers specify a particular transfer direction to and/or from .I id. Possible directions are .BR src , .BR dst , .B "src or dst" and .B "src and" .BR dst . E.g., `src foo', `dst net 128.3', `src or dst port ftp-data'. If there is no dir qualifier, .B "src or dst" is assumed. For `null' link layers (i.e. point to point protocols such as slip) the .B inbound and .B outbound qualifiers can be used to specify a desired direction. .LP More complex filter expressions are built up by using the words .BR and , .B or and .B not to combine primitives. E.g., `host foo and not port ftp and not port ftp-data'. To save typing, identical qualifier lists can be omitted. E.g., `tcp dst port ftp or ftp-data or domain' is exactly the same as `tcp dst port ftp or tcp dst port ftp-data or tcp dst port domain'. .LP Allowable primitives are: .IP "\fBdst host \fIhost\fR" True if the IPv4/v6 destination field of the packet is \fIhost\fP, which may be either an address or a name. .IP "\fBsrc host \fIhost\fR" True if the IPv4/v6 source field of the packet is \fIhost\fP. .IP "\fBhost \fIhost\fP True if either the IPv4/v6 source or destination of the packet is \fIhost\fP. Any of the above host expressions can be prepended with the keywords, \fBip\fP, \fBarp\fP, \fBrarp\fP, or \fBip6\fP as in: .in +.5i .nf \fBip host \fIhost\fR .fi .in -.5i which is equivalent to: .in +.5i .nf \fBether proto \fI\\ip\fB and host \fIhost\fR .fi .in -.5i If \fIhost\fR is a name with multiple IP addresses, each address will be checked for a match. .IP "\fBether dst \fIehost\fP True if the ethernet destination address is \fIehost\fP. \fIEhost\fP may be either a name from /etc/ethers or a number (see .IR ethers (3N) for numeric format). .IP "\fBether src \fIehost\fP True if the ethernet source address is \fIehost\fP. .IP "\fBether host \fIehost\fP True if either the ethernet source or destination address is \fIehost\fP. .IP "\fBgateway\fP \fIhost\fP True if the packet used \fIhost\fP as a gateway. I.e., the ethernet source or destination address was \fIhost\fP but neither the IP source nor the IP destination was \fIhost\fP. \fIHost\fP must be a name and must be found in both /etc/hosts and /etc/ethers. (An equivalent expression is .in +.5i .nf \fBether host \fIehost \fBand not host \fIhost\fR .fi .in -.5i which can be used with either names or numbers for \fIhost / ehost\fP.) This syntax does not work in IPv6-enabled configuration at this moment. .IP "\fBdst net \fInet\fR" True if the IPv4/v6 destination address of the packet has a network number of \fInet\fP. \fINet\fP may be either a name from /etc/networks or a network number (see \fInetworks(4)\fP for details). .IP "\fBsrc net \fInet\fR" True if the IPv4/v6 source address of the packet has a network number of \fInet\fP. .IP "\fBnet \fInet\fR" True if either the IPv4/v6 source or destination address of the packet has a network number of \fInet\fP. .IP "\fBnet \fInet\fR \fBmask \fImask\fR" True if the IP address matches \fInet\fR with the specific netmask. May be qualified with \fBsrc\fR or \fBdst\fR. Note that this syntax is not valid for IPv6 \fInet\fR. .IP "\fBnet \fInet\fR/\fIlen\fR" True if the IPv4/v6 address matches \fInet\fR a netmask \fIlen\fR bits wide. May be qualified with \fBsrc\fR or \fBdst\fR. .IP "\fBdst port \fIport\fR" True if the packet is ip/tcp, ip/udp, ip6/tcp or ip6/udp and has a destination port value of \fIport\fP. The \fIport\fP can be a number or a name used in /etc/services (see .IR tcp (4P) and .IR udp (4P)). If a name is used, both the port number and protocol are checked. If a number or ambiguous name is used, only the port number is checked (e.g., \fBdst port 513\fR will print both tcp/login traffic and udp/who traffic, and \fBport domain\fR will print both tcp/domain and udp/domain traffic). .IP "\fBsrc port \fIport\fR" True if the packet has a source port value of \fIport\fP. .IP "\fBport \fIport\fR" True if either the source or destination port of the packet is \fIport\fP. Any of the above port expressions can be prepended with the keywords, \fBtcp\fP or \fBudp\fP, as in: .in +.5i .nf \fBtcp src port \fIport\fR .fi .in -.5i which matches only tcp packets whose source port is \fIport\fP. .LP Primitives may be combined using: .IP A parenthesized group of primitives and operators (parentheses are special to the Shell and must be escaped). .IP Negation (`\fB!\fP' or `\fBnot\fP'). .IP Concatenation (`\fB&&\fP' or `\fBand\fP'). .IP Alternation (`\fB||\fP' or `\fBor\fP'). .LP Negation has highest precedence. Alternation and concatenation have equal precedence and associate left to right. Note that explicit \fBand\fR tokens, not juxtaposition, are now required for concatenation. .LP If an identifier is given without a keyword, the most recent keyword is assumed. For example, .in +.5i .nf \fBnot host vs and ace\fR .fi .in -.5i is short for .in +.5i .nf \fBnot host vs and host ace\fR .fi .in -.5i which should not be confused with .in +.5i .nf \fBnot ( host vs or ace )\fR .fi .in -.5i .LP Expression arguments can be passed to \fIssldump\fP as either a single argument or as multiple arguments, whichever is more convenient. Generally, if the expression contains Shell metacharacters, it is easier to pass it as a single, quoted argument. Multiple arguments are concatenated with spaces before being parsed. .SH EXAMPLES .LP To listen to traffic on interface \fIle0\fP port \fI443\fP: .RS .nf \fBssldump -i le0 port 443\fP .fi .RE .LP To listen to traffic to the server \fIromeo\fP on port \fI443\fP: .RS .nf \fBssldump -i le0 port 443 and host romeo\fP: .fi .RE .LP To switch output format to JSON: .RS .nf \fBssldump -ANH -j -i le0 port 443 and host romeo\fP .fi .RE .LP To decrypt traffic to host \fIromeo\fR \fIserver.pem\fR and the password \fIfoobar\fR: .RS .nf \fBssldump -Ad -k ~/server.pem -p foobar -i le0 host romeo .fi .RE .SH OUTPUT FORMAT .LP All output is printed to standard out. .LP \fIssldump\fP prints an indication of every new TCP connection using a line like the following .nf .LP \fBNew TCP connection #2: iromeo.rtfm.com(2302) <-> sr1.rtfm.com(4433)\fP .LP .fi The host which send the first SYN is printed on the left and the host which responded is printed on the right. Ordinarily, this means that the SSL client will be printed on the left with the SSL server on the right. In this case we have a connection from \fIiromeo.rtfm.com\fR (port \fI2303\fR) to \fIsr1.rtfm.com\fR (port \fI4433\fR). To allow the user to disentangle traffic from different connections, each connection is numbered. This is connection \fI2\fR. .LP The printout of each SSL record begins with a record line. This line contains the connection and record number, a timestamp, and the record type, as in the following: .LP .nf \fB2 3 0.2001 (0.0749) S>C Handshake Certificate\fR .fi .LP This is record \fI3\fR on connection \fI2\fR. The first timestamp is the time since the beginning of the connection. The second is the time since the previous record. Both are in seconds. .LP The next field in the record line is the direction that the record was going. \fIC>S\fR indicates records transmitted from client to server and \fIS>C\fR indicates records transmitted from server to client. \fIssldump\fP assumes that the host to transmit the first SYN is the SSL client (this is nearly always correct). .LP The next field is the record type, one of \fIHandshake\fR, \fIIAlert\fR, \fIChangeCipherSpec\fR, or \fIapplication_data\fR. Finally, \fIssldump\fP may print record-specific data on the rest of the line. For \fIHandshake\fR records, it prints the handshake message. Thus, this record is a \fICertificate\fR message. .LP \fIssldump\fP chooses certain record types for further decoding. These are the ones that have proven to be most useful for debugging: .LP .nf \fIClientHello\fR \- version, offered cipher suites, session id if provided) \fIServerHello\fR \- version, session_id, chosen cipher suite, compression method \fIAlert\fR \- type and level (if obtainable) .fi .LP Fuller decoding of the various records can be obtained by using the .B \-A , .B \-d , .B \-k and .B \-p flags. .LP .SH SIGNALS .LP When it receives SIGUSR1, .B ssldump prints the list of currently tracked connection on stderr. .LP With SIGUSR2, .B ssldump purges its internal connection tracking data structures. .LP .SH DECRYPTION .LP \fIssldump\fP can decrypt traffic between two hosts if the following two conditions are met: .RS .nf 1. \fIssldump\fP has the keys. 2. Static RSA was used. .fi .RE In any other case, once encryption starts, \fIssldump\fP will only be able to determine the record type. Consider the following section of a trace. .LP .nf \fB1 5 0.4129 (0.1983) C>S Handshake ClientKeyExchange 1 6 0.4129 (0.0000) C>S ChangeCipherSpec 1 7 0.4129 (0.0000) C>S Handshake 1 8 0.5585 (0.1456) S>C ChangeCipherSpec 1 9 0.6135 (0.0550) S>C Handshake 1 10 2.3121 (1.6986) C>S application_data 1 11 2.5336 (0.2214) C>S application_data 1 12 2.5545 (0.0209) S>C application_data 1 13 2.5592 (0.0046) S>C application_data 1 14 2.5592 (0.0000) S>C Alert\fP .fi .LP Note that the \fIClientKeyExchange\fR message type is printed but the rest of the \fIHandshake\fR messages do not have types. These are the \fIFinished\fR messages, but because they are encrypted \fIssldump\fP only knows that they are of type \fIHandshake\fR. Similarly, had the \fIAlert\fR in record 14 happened during the handshake, it's type and level would have been printed. However, since it is encrypted we can only tell that it is an alert. .LP .SH BUGS .LP Please send bug reports to https://github.com/adulau/ssldump .LP The TCP reassembler is not perfect. No attempt is made to reassemble IP fragments and the 3-way handshake and close handshake are imperfectly implemented. In practice, this turns out not to be much of a problem. .LP Support is provided for only for Ethernet and loopback interfaces because that's all that I have. If you have another kind of network you will need to modify pcap_cb in base/pcap-snoop.c. If you have direct experience with \fIssldump\fP on other networks, please send me patches. .LP \fIssldump\fP doesn't implement session caching and therefore can't decrypt resumed sessions. .LP .SH SEE ALSO .LP .BR tcpdump (1) .LP .SH AUTHOR .LP \fIssldump\fP was originally written by Eric Rescorla . Maintained by a bunch of volunteers, see https://github.com/adulau/ssldump/blob/master/CREDITS - Copyright (C) 2015-2023 the aforementioned volunteers ssldump-1.9/ssldump.md000066400000000000000000000375201470411077700151020ustar00rootroot00000000000000# ssldump(1) - dump SSL traffic on a network 14 August 2023 - version 1.8 ``` .na ssldump [ -aAdeFHjnNPqtTvxXyz ] [ -i interface ] .ti +8 [ -k keyfile ] [ -l sslkeylogfile ] [ -p password ] [ -r dumpfile ] [ -w outputpcap ] .ti +8 [ -S [ crypto | d | ht | H | nroff ] ] [ expression ] ``` # Description _ssldump_ is an SSL/TLS network protocol analyzer. It identifies TCP connections on the chosen network interface and attempts to interpret them as SSL/TLS traffic. When it identifies SSL/TLS traffic, it decodes the records and displays them in a textual form to stdout. If provided with the appropriate keying material, it will also decrypt the connections and display the application data traffic. It supports various version of SSL/TLS up to TLS version 1.3. It also includes support for JSON output or JA3 support. _ssldump_ has been originally tested on FreeBSD, Linux, Solaris, and HP/UX. _ssldump_ has mainly a new build process and it's mainly tested on different Linux flavors. Since it's based on PCAP, it should work on most platforms. However, unlike tcpdump, _ssldump_ needs to be able to see both sides of the data transmission so you may have trouble using it with network taps such as SunOS nit that don't permit you to see transmitted data. **Under SunOS with nit or bpf:** To run _ssldump_ you must have read access to _/dev/nit_ or _/dev/bpf*_. **Under Solaris with dlpi:** You must have read access to the network pseudo device, e.g. _/dev/le_. **Under HP-UX with dlpi:** You must be root or it must be installed setuid to root. **Under IRIX with snoop:** You must be root or it must be installed setuid to root. **Under Linux:** You must be root or it must be installed setuid to root. **Under Ultrix and Digital UNIX:** Once the super-user has enabled promiscuous-mode operation using _pfconfig_(8), any user may run _ssldump_ **Under BSD:** You must have read access to _/dev/bpf*_. # Options * **-a** Print bare TCP ACKs (useful for observing Nagle behavior). * **-A** Print all record fields (by default _ssldump_ chooses the most interesting fields). * **-d** Display the application data traffic. This usually means decrypting it, but when -d is used _ssldump_ will also decode application data traffic _before_ the SSL session initiates. This allows you to see HTTPS CONNECT behavior as well as SMTP STARTTLS. As a side effect, since _ssldump_ can't tell whether plaintext is traffic before the initiation of an SSL connection or just a regular TCP connection, this allows you to use _ssldump_ to sniff any TCP connection. _ssldump_ will automatically detect ASCII data and display it directly to the screen. non-ASCII data is displayed as hex dumps. See also -X. * **-e** Print absolute timestamps instead of relative timestamps. * **-F** Specify the number of packets after which a connection pool cleaning is performed (in packets, default: 100). * **-H** Print the full SSL packet header. * **-i** _interface_ Use _interface_ as the network interface on which to sniff SSL/TLS traffic. * **-j** Switch output format to JSON. Only stdout is affected by this toggle. * **-k** _keyfile_ Use _keyfile_ as the location of the SSL keyfile (OpenSSL format) Previous versions of _ssldump_ automatically looked in ./server.pem. Now you must specify your keyfile every time. * **-l** _sslkeylogfile_ Use _sslkeylogfile_ as the location of the SSLKEYLOGFILE (https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format). * **-n** Don't try to resolve host names from IP addresses. * **-N** Attempt to parse ASN.1 when it appears, such as in certificates and DNs. * **-p** _password_ Use _password_ as the SSL keyfile password. * **-P** Don't put the interface into promiscuous mode. * **-q** Don't decode any record fields beyond a single summary line. (quiet mode). * **-r** _file_ Read data from _file_ instead of from the network. The old -f option still works but is deprecated and will probably be removed with the next version. * **-S** _[_ **crypto** _|_ **d** _|_ **ht** _|_ **H** _]_ Specify SSL flags to _ssldump_. These flags include: * _crypto_ Print cryptographic information. * _d_ Print fields as decoded. * _ht_ Print the handshake type. * _H_ Print handshake type and highlights. * **-t** Specify the TTL for inactive connections referenced in the connection pool (in seconds, default: 100). * **-T** Print the TCP headers. * **-v** Display version and copyright information. * **-w** _outputpcap_ Use _outputpcap_ as the destination for decrypted packets. * **-x** Print each record in hex, as well as decoding it. * **-X** When the -d option is used, binary data is automatically printed in two columns with a hex dump on the left and the printable characters on the right. -X suppresses the display of the printable characters, thus making it easier to cut and paste the hex data into some other program. * **-y** Decorate the output for processing with nroff/troff. Not very useful for the average user. * **-z** Add timestamp in front of TCP packet description (-T) * _expression_ Selects what packets _ssldump_ will examine. Technically speaking, _ssldump_ supports the full expression syntax from PCAP and tcpdump. In fact, the description here is cribbed from the tcpdump man page. However, since _ssldump_ needs to examine full TCP streams, most of the tcpdump expressions will select traffic mixes that _ssldump_ will simply ignore. Only the expressions which don't result in incomplete TCP streams are listed here. The _expression_ consists of one or more _primitives_. Primitives usually consist of an _id_ (name or number) preceded by one or more qualifiers. There are three different kinds of qualifier: * _type_ qualifiers say what kind of thing the id name or number refers to. Possible types are **host**, **net** and **port**. E.g., \`host foo', \`net 128.3', \`port 20'. If there is no type qualifier, **host** is assumed. * _dir_ qualifiers specify a particular transfer direction to and/or from _id._ Possible directions are **src**, **dst**, **src or dst** and **src and** **dst**. E.g., \`src foo', \`dst net 128.3', \`src or dst port ftp-data'. If there is no dir qualifier, **src or dst** is assumed. For \`null' link layers (i.e. point to point protocols such as slip) the **inbound** and **outbound** qualifiers can be used to specify a desired direction. More complex filter expressions are built up by using the words **and**, **or** and **not** to combine primitives. E.g., \`host foo and not port ftp and not port ftp-data'. To save typing, identical qualifier lists can be omitted. E.g., \`tcp dst port ftp or ftp-data or domain' is exactly the same as \`tcp dst port ftp or tcp dst port ftp-data or tcp dst port domain'. Allowable primitives are: * **dst host host** True if the IPv4/v6 destination field of the packet is _host_, which may be either an address or a name. * **src host host** True if the IPv4/v6 source field of the packet is _host_. * True if either the IPv4/v6 source or destination of the packet is _host_. Any of the above host expressions can be prepended with the keywords, **ip**, **arp**, **rarp**, or **ip6** as in: ip host host which is equivalent to: ether proto \ip and host host If _host_ is a name with multiple IP addresses, each address will be checked for a match. * True if the ethernet destination address is _ehost_. _Ehost_ may be either a name from /etc/ethers or a number (see _ethers_(3N) for numeric format). * True if the ethernet source address is _ehost_. * True if either the ethernet source or destination address is _ehost_. * True if the packet used _host_ as a gateway. I.e., the ethernet source or destination address was _host_ but neither the IP source nor the IP destination was _host_. _Host_ must be a name and must be found in both /etc/hosts and /etc/ethers. (An equivalent expression is ether host ehost and not host host which can be used with either names or numbers for _host / ehost_.) This syntax does not work in IPv6-enabled configuration at this moment. * **dst net net** True if the IPv4/v6 destination address of the packet has a network number of _net_. _Net_ may be either a name from /etc/networks or a network number (see _networks(4)_ for details). * **src net net** True if the IPv4/v6 source address of the packet has a network number of _net_. * **net net** True if either the IPv4/v6 source or destination address of the packet has a network number of _net_. * **net net** **mask mask** True if the IP address matches _net_ with the specific netmask. May be qualified with **src** or **dst**. Note that this syntax is not valid for IPv6 _net_. * **net _net**/len_ True if the IPv4/v6 address matches _net_ a netmask _len_ bits wide. May be qualified with **src** or **dst**. * **dst port port** True if the packet is ip/tcp, ip/udp, ip6/tcp or ip6/udp and has a destination port value of _port_. The _port_ can be a number or a name used in /etc/services (see _tcp_(4P) and _udp_(4P)). If a name is used, both the port number and protocol are checked. If a number or ambiguous name is used, only the port number is checked (e.g., **dst port 513** will print both tcp/login traffic and udp/who traffic, and **port domain** will print both tcp/domain and udp/domain traffic). * **src port port** True if the packet has a source port value of _port_. * **port port** True if either the source or destination port of the packet is _port_. Any of the above port expressions can be prepended with the keywords, **tcp** or **udp**, as in: tcp src port port which matches only tcp packets whose source port is _port_. Primitives may be combined using: * A parenthesized group of primitives and operators (parentheses are special to the Shell and must be escaped). * Negation (\`**!**' or \`**not**'). * Concatenation (\`**&&**' or \`**and**'). * Alternation (\`**||**' or \`**or**'). Negation has highest precedence. Alternation and concatenation have equal precedence and associate left to right. Note that explicit **and** tokens, not juxtaposition, are now required for concatenation. If an identifier is given without a keyword, the most recent keyword is assumed. For example, not host vs and ace is short for not host vs and host ace which should not be confused with not ( host vs or ace ) Expression arguments can be passed to _ssldump_ as either a single argument or as multiple arguments, whichever is more convenient. Generally, if the expression contains Shell metacharacters, it is easier to pass it as a single, quoted argument. Multiple arguments are concatenated with spaces before being parsed. # Examples To listen to traffic on interface _le0_ port _443_: ssldump -i le0 port 443 To listen to traffic to the server _romeo_ on port _443_: ssldump -i le0 port 443 and host romeo: To switch output format to JSON: ssldump -ANH -j -i le0 port 443 and host romeo To decrypt traffic to host _romeo_ _server.pem_ and the password _foobar_: ssldump -Ad -k ~/server.pem -p foobar -i le0 host romeo # Output Format All output is printed to standard out. _ssldump_ prints an indication of every new TCP connection using a line like the following New TCP connection #2: iromeo.rtfm.com(2302) <-> sr1.rtfm.com(4433) The host which send the first SYN is printed on the left and the host which responded is printed on the right. Ordinarily, this means that the SSL client will be printed on the left with the SSL server on the right. In this case we have a connection from _iromeo.rtfm.com_ (port _2303_) to _sr1.rtfm.com_ (port _4433_). To allow the user to disentangle traffic from different connections, each connection is numbered. This is connection _2_. The printout of each SSL record begins with a record line. This line contains the connection and record number, a timestamp, and the record type, as in the following: 2 3 0.2001 (0.0749) S>C Handshake Certificate This is record _3_ on connection _2_. The first timestamp is the time since the beginning of the connection. The second is the time since the previous record. Both are in seconds. The next field in the record line is the direction that the record was going. _C>S_ indicates records transmitted from client to server and _S>C_ indicates records transmitted from server to client. _ssldump_ assumes that the host to transmit the first SYN is the SSL client (this is nearly always correct). The next field is the record type, one of _Handshake_, _IAlert_, _ChangeCipherSpec_, or _application\_data_. Finally, _ssldump_ may print record-specific data on the rest of the line. For _Handshake_ records, it prints the handshake message. Thus, this record is a _Certificate_ message. _ssldump_ chooses certain record types for further decoding. These are the ones that have proven to be most useful for debugging: ClientHello - version, offered cipher suites, session id if provided) ServerHello - version, session_id, chosen cipher suite, compression method Alert - type and level (if obtainable) Fuller decoding of the various records can be obtained by using the **-A** , **-d** , **-k** and **-p** flags. # Signals When it receives SIGUSR1, _ssldump_ prints the list of currently tracked connection on stderr. With SIGUSR2, _ssldump_ purges its internal connection tracking data structures. # Decryption _ssldump_ can decrypt traffic between two hosts if the following two conditions are met: 1. ssldump has the keys. 2. Static RSA was used. In any other case, once encryption starts, _ssldump_ will only be able to determine the record type. Consider the following section of a trace. 1 5 0.4129 (0.1983) C>S Handshake ClientKeyExchange 1 6 0.4129 (0.0000) C>S ChangeCipherSpec 1 7 0.4129 (0.0000) C>S Handshake 1 8 0.5585 (0.1456) S>C ChangeCipherSpec 1 9 0.6135 (0.0550) S>C Handshake 1 10 2.3121 (1.6986) C>S application_data 1 11 2.5336 (0.2214) C>S application_data 1 12 2.5545 (0.0209) S>C application_data 1 13 2.5592 (0.0046) S>C application_data 1 14 2.5592 (0.0000) S>C Alert Note that the _ClientKeyExchange_ message type is printed but the rest of the _Handshake_ messages do not have types. These are the _Finished_ messages, but because they are encrypted _ssldump_ only knows that they are of type _Handshake_. Similarly, had the _Alert_ in record 14 happened during the handshake, it's type and level would have been printed. However, since it is encrypted we can only tell that it is an alert. # Bugs Please send bug reports to https://github.com/adulau/ssldump The TCP reassembler is not perfect. No attempt is made to reassemble IP fragments and the 3-way handshake and close handshake are imperfectly implemented. In practice, this turns out not to be much of a problem. Support is provided for only for Ethernet and loopback interfaces because that's all that I have. If you have another kind of network you will need to modify pcap_cb in base/pcap-snoop.c. If you have direct experience with _ssldump_ on other networks, please send me patches. _ssldump_ doesn't implement session caching and therefore can't decrypt resumed sessions. # See Also **tcpdump**(1) # Author _ssldump_ was originally written by Eric Rescorla <[ekr@rtfm.com](mailto:ekr@rtfm.com)>. Maintained by a bunch of volunteers, see https://github.com/adulau/ssldump/blob/master/CREDITS - Copyright (C) 2015-2023 the aforementioned volunteers ssldump-1.9/win32/000077500000000000000000000000001470411077700140245ustar00rootroot00000000000000ssldump-1.9/win32/Ssldump.html000066400000000000000000000467211470411077700163530ustar00rootroot00000000000000



       ssldump - dump SSL traffic on a network


SYNOPSIS

       ssldump [ -vtaTnsAxXhHVNdq ] [ -r dumpfile ] 
       [ -i interface ] [ -k keyfile ] [ -p password ] [ expression ]


DESCRIPTION

       ssldump is an SSL/TLS network protocol analyzer. It  iden-
       tifies TCP connections on the chosen network interface and
       attempts to interpret them as  SSL/TLS  traffic.  When  it
       identifies  SSL/TLS  traffic,  it  decodes the records and
       displays them in a textual form  to  stdout.  If  provided
       with the appropriate keying material, it will also decrypt
       the connections and display the application data  traffic.

       ssldump  has  been  tested on FreeBSD, Linux, Solaris, and
       HP/UX.  Since it's based on PCAP, it should work  on  most
       platforms.  However,  unlike  tcpdump, ssldump needs to be
       able to see both sides of the data transmission so you may
       have  trouble using it with network taps such as SunOS nit
       that don't permit you  to  see  transmitted  data.   Under
       SunOS  with  nit or bpf: To run tcpdump you must have read
       access to /dev/nit or /dev/bpf*.  Under Solaris with dlpi:
       You  must  have  read access to the network pseudo device,
       e.g.  /dev/le.  Under HP-UX with dlpi: You must be root or
       it  must  be  installed  setuid  to root.  Under IRIX with
       snoop: You must be root or it must be installed setuid  to
       root.   Under  Linux:  You  must  be  root  or  it must be
       installed setuid to root.  Under Ultrix and Digital  UNIX:
       Once the super-user has enabled promiscuous-mode operation
       using pfconfig(8), any user may run ssldump Under BSD: You
       must have read access to /dev/bpf*.


OPTIONS

       -a     Print bare TCP ACKs (useful for observing Nagle behav-
              ior)

       -A     Print all record fields (by default ssldump chooses
              the most interesting fields)

       -d     Display  the application data traffic. This usually
              means decrypting it, but when -d  is  used  ssldump
              will  also decode application data traffic _before_
              the SSL session initiates.  This allows you to  see
              HTTPS CONNECT behavior as well as SMTP STARTTLS. As
              a side effect, since  ssldump  can't  tell  whether
              plaintext  is  traffic  before the initiation of an
              SSL connection or just a  regular  TCP  connection,
              this  allows  you  to  use ssldump to sniff any TCP
              connection.   ssldump  will  automatically   detect
              ASCII  data  and display it directly to the screen.

       -e     Print   absolute  timestamps  instead  of  relative
              timestamps

       -r     Read data from file instead of  from  the  network.
              The old -f option still works but is deprecated and
              will probably be removed with the next version.
              
       -H
              Print the full SSL packet header.

       -k     Use  keyfile  as  the  location  of the SSL keyfile
              (OpenSSL format)  ssldump  automatically  looks  in
              ./server.pem.

       -n     Don't try to resolve host names from IP addresses

       -N     Attempt  to parse ASN.1 when it appears, such as in
              certificates and DNs.

       -p     Use password as the SSL keyfile password default is
              "password".

       -q     Don't decode any record fields beyond a single sum-
              mary line. (quiet mode).

       -x     Print each record in hex, as well as decoding it.

       -X     When the -d option is used, binary data is automat-
              ically  printed  in  two columns with a hex dump on
              the left and the printable characters on the right.
              -X  suppresses the display of the printable charac-
              ters, thus making it easier to cut  and  paste  the
              hext data into some other program.  -y Decorate the
              output for processing with troff. Not  very  useful
              for the average user.


        expression
              Selects  what packets ssldump will examine. Techni-
              cally speaking, ssldump supports the  full  expres-
              sion  syntax  from  PCAP and tcpdump.  In fact, the
              description here is cribbed from  the  tcpdump  man
              page.  However, since ssldump needs to examine full
              TCP streams, most of the tcpdump  expressions  will
              select  traffic  mixes  that  ssldump  will  simply
              ignore. Only the expressions which don't result  in
              incomplete TCP streams are listed here.

              The  expression consists of one or more primitives.
              Primitives usually consist of an id (name  or  num-
              ber) preceded by one or more qualifiers.  There are
              three different kinds of qualifier:

                     are host, net and port.  E.g.,  `host  foo',
                     `net 128.3', `port 20'.  If there is no type
                     qualifier, host is assumed.

              dir    qualifiers  specify  a  particular  transfer
                     direction   to  and/or  from  id.   Possible
                     directions are src, dst, src or dst and  src
                     and  dst.  E.g., `src foo', `dst net 128.3',
                     `src or dst port ftp-data'.  If there is  no
                     dir  qualifier,  src or dst is assumed.  For
                     `null' link layers (i.e. point to point pro-
                     tocols  such  as  slip) the inbound and out-
                     bound qualifiers can be used  to  specify  a
                     desired direction.

              More  complex  filter  expressions  are built up by
              using the words and, or and not to  combine  primi-
              tives.   E.g.,  `host  foo and not port ftp and not
              port ftp-data'.  To save typing,  identical  quali-
              fier lists can be omitted.  E.g., `tcp dst port ftp
              or ftp-data or domain' is exactly the same as  `tcp
              dst  port  ftp  or tcp dst port ftp-data or tcp dst
              port domain'.

              Allowable primitives are:

              dst host host
                     True if the IPv4/v6 destination field of the
                     packet  is  host,  which  may  be  either an
                     address or a name.

              src host host
                     True if the  IPv4/v6  source  field  of  the
                     packet is host.

              host host
                     True  if either the IPv4/v6 source or desti-
                     nation of the packet is host.   Any  of  the
                     above host expressions can be prepended with
                     the keywords, ip, arp, rarp, or ip6 as in:
                          ip host host
                     which is equivalent to:
                          ether proto \ip and host host
                     If  host  is  a  name   with   multiple   IP
                     addresses,  each address will be checked for
                     a match.

              ether dst ehost
                     True if the ethernet destination address  is
                     ehost.   Ehost  may  be  either  a name from
                     /etc/ethers or a number (see ethers(3N)  for
                     numeric format).
                     True  if  the  ethernet  source  address  is
                     ehost.

              ether host ehost
                     True if either the ethernet source or desti-
                     nation address is ehost.

              gateway host
                     True  if  the packet used host as a gateway.
                     I.e., the  ethernet  source  or  destination
                     address  was  host but neither the IP source
                     nor the IP destination was host.  Host  must
                     be   a  name  and  must  be  found  in  both
                     /etc/hosts and /etc/ethers.  (An  equivalent
                     expression is
                          ether host ehost and not host host
                     which  can be used with either names or num-
                     bers for host / ehost.)   This  syntax  does
                     not  work  in  IPv6-enabled configuration at
                     this moment.

              dst net net
                     True if the IPv4/v6 destination  address  of
                     the  packet has a network number of net. Net
                     may be either a name from /etc/networks or a
                     network    number   (see   networks(4)   for
                     details).

              src net net
                     True if the IPv4/v6 source  address  of  the
                     packet has a network number of net.

              net net
                     True  if either the IPv4/v6 source or desti-
                     nation address of the packet has  a  network
                     number of net.

              net net mask mask
                     True  if the IP address matches net with the
                     specific netmask.  May be qualified with src
                     or  dst.  Note that this syntax is not valid
                     for IPv6 net.

              net net/len
                     True if the IPv4/v6 address  matches  net  a
                     netmask  len  bits  wide.   May be qualified
                     with src or dst.

              dst port port
                     True  if  the  packet  is  ip/tcp,   ip/udp,
                     ip6/tcp  or  ip6/udp  and  has a destination
                     port value of port.  The port can be a  num-
                     both   the  port  number  and  protocol  are
                     checked.  If a number or ambiguous  name  is
                     used, only the port number is checked (e.g.,
                     dst port 513 will print both tcp/login traf-
                     fic  and  udp/who  traffic,  and port domain
                     will print both  tcp/domain  and  udp/domain
                     traffic).

              src port port
                     True  if  the packet has a source port value
                     of port.

              port port
                     True if either  the  source  or  destination
                     port  of  the  packet  is  port.  Any of the
                     above port expressions can be prepended with
                     the keywords, tcp or udp, as in:
                          tcp src port port
                     which  matches only tcp packets whose source
                     port is port.

              Primitives may be combined using:

                     A  parenthesized  group  of  primitives  and
                     operators  (parentheses  are  special to the
                     Shell and must be escaped).

                     Negation (`!' or `not').

                     Concatenation (`&&' or `and').

                     Alternation (`||' or `or').

              Negation has highest precedence.   Alternation  and
              concatenation  have  equal precedence and associate
              left to right.  Note that explicit and tokens,  not
              juxtaposition,  are now required for concatenation.

              If an identifier is given without  a  keyword,  the
              most recent keyword is assumed.  For example,
                   not host vs and ace
              is short for
                   not host vs and host ace
              which should not be confused with
                   not ( host vs or ace )

              Expression  arguments  can  be passed to ssldump as
              either a single argument or as multiple  arguments,
              whichever  is  more  convenient.  Generally, if the
              expression contains  Shell  metacharacters,  it  is
              easier  to  pass  it  as a single, quoted argument.
              Multiple arguments  are  concatenated  with  spaces

       To listen to traffic on interface le0 port 443
              ssldump -i le0 port 443

       To listen to traffic to the server romeo on port 443.
              ssldump -i le0 port 443 and host romeo

       To  decrypt  traffic  to  to host romeo server.pem and the
       password foobar
              ssldump -Ad -k ~/server.pem -p foobar -i le0 host romeo


OUTPUT FORMAT

       All output is printed to standard out.

       ssldump prints an indication of every new  TCP  connection
       using a line like the following

       New TCP connection #2: iromeo.rtfm.com(2302) <-> sr1.rtfm.com(4433)

       The  host  which send the first SYN is printed on the left
       and the host which responded  is  printed  on  the  right.
       Ordinarily, this means that the SSL client will be printed
       on the left with the SSL server on the right. In this case
       we  have  a connection from iromeo.rtfm.com (port 2303) to
       sr1.rtfm.com (port 4433). To allow the user to disentangle
       traffic  from  different  connections,  each connection is
       numbered. This is connection 2.

       The printout of each SSL record begins with a record line.
       This  line  contains  the  connection and record number, a
       timestamp, and the record type, as in the following:

       2 3  0.2001 (0.0749)  S>C  Handshake      Certificate

       This is record 3 on connection 2. The first  timestamp  is
       the time since the beginning of the connection. The second
       is the time since the previous record. Both  are  in  sec-
       onds.

       The  next  field  in the record line is the direction that
       the record was going. C>S  indicates  records  transmitted
       from  client to server and S>C indicates records transmit-
       ted from server to client.  ssldump assumes that the  host
       to  transmit  the  first  SYN  is  the SSL client (this is
       nearly always correct).

       The next field is  the  record  type,  one  of  Handshake,
       IAlert,  ChangeCipherSpec,  or  application_data. Finally,
       ssldump may print record-specific data on the rest of  the
       line.  For Handshake records, it prints the handshake mes-
       sage. Thus, this record is a Certificate message.

       ssldump chooses certain record types for further decoding.

       ClientHello - version, offered cipher suites, session id
                            if provided)
       ServerHello - version, session_id, chosen cipher suite,
                      compression method
       Alert - type and level (if obtainable)

       Fuller decoding of the various records can be obtained  by
       using the -A , -d , -k and -p flags.



DECRYPTION

       ssldump  can decrypt traffic between two hosts if the fol-
       lowing two conditions are met:
              1. ssldump has the keys.
              2. Static RSA was used.
       In any other case, once encryption  starts,  ssldump  will
       only  be  able  to determine the record type. Consider the
       following section of a trace.

       1 5  0.4129 (0.1983)  C>S  Handshake      ClientKeyExchange
       1 6  0.4129 (0.0000)  C>S  ChangeCipherSpec
       1 7  0.4129 (0.0000)  C>S  Handshake
       1 8  0.5585 (0.1456)  S>C  ChangeCipherSpec
       1 9  0.6135 (0.0550)  S>C  Handshake
       1 10 2.3121 (1.6986)  C>S  application_data
       1 11 2.5336 (0.2214)  C>S  application_data
       1 12 2.5545 (0.0209)  S>C  application_data
       1 13 2.5592 (0.0046)  S>C  application_data
       1 14 2.5592 (0.0000)  S>C  Alert

       Note that the ClientKeyExchange message  type  is  printed
       but  the rest of the Handshake messages do not have types.
       These are the Finished  messages,  but  because  they  are
       encrypted  ssldump  only knows that they are of type Hand-
       shake.  Similarly, had the Alert  in  record  14  happened
       during  the handshake, it's type and level would have been
       printed. However, since it is encrypted we can  only  tell
       that it is an alert.



BUGS

       Please send bug reports to ssldump@rtfm.com.

       The  TCP reassembler is not perfect. No attempt is made to
       reassemble IP fragments and the 3-way handshake and  close
       handshake  are  imperfectly implemented. In practice, this
       turns out not to be much of a problem.

       Support is provided for only  for  Ethernet  and  loopback
       interfaces  because  that's  all  that I have. If you have
       another kind of network you will need to modify pcap_cb in
       base/pcap-snoop.c. If you have direct experience with ssldump
       on other networks, please send me patches.

       ssldump doesn't implement session  caching  and  therefore
       can't decrypt resumed sessions.



Man(1) output converted with man2html
ssldump-1.9/win32/vcwin32.mak000066400000000000000000000235361470411077700160220ustar00rootroot00000000000000# Copyright (C) 1999-2000 RTFM, Inc. # All Rights Reserved # This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla # and licensed by RTFM, Inc. # 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. # 3. All advertising materials mentioning features or use of this software # must display the following acknowledgement: # # This product includes software developed by Eric Rescorla for # RTFM, Inc. # 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be # used to endorse or promote products derived from this # software without specific prior written permission. # THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``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 REGENTS 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 SUCH DAMAGE. !IF "$(CFG)" == "" CFG=release !MESSAGE No configuration specified. Defaulting to release. !ENDIF !IF "$(CFG)" != "release" && "$(CFG)" != "debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "vcwin32.mak" CFG="debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "release" !MESSAGE "debug" !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF # Directories, relative to this one ROOT=. ANALYZE_SRCDIR=$(ROOT)\base COMMONDIR=$(ROOT)\common COMMON_LIB_SRCDIR=$(COMMONDIR)\lib ANALYZE_NULL_SRCDIR=$(ROOT)\null ANALYZE_SSL_SRCDIR=$(ROOT)\ssl WIN32_DIR=$(ROOT)\win32 OBJ_DIR=$(ROOT)\out32 WINPCAP_DEV_DIR=$(WIN32_DIR)\WPdpack WINPCAP_SRC_DIR=$(WIN32_DIR)\winpcap WINPCAP_INCLUDES=-I$(WINPCAP_DEV_DIR)\include -I$(WINPCAP_DEV_DIR)\include\net \ -I$(WINPCAP_SRC_DIR)\wpcap\libpcap\win32\include # # OpenSSL-specific stuff # !IF "$(OPENSSL)" == "" OPENSSL=no !MESSAGE OpenSSL support defaulting to "no". !ENDIF !IF "$(OPENSSL)" == "yes" # # Customize the next 3 macros match your openssl development setup # OPENSSL_DIR=$(ROOT)\..\openssl\openssl-0.9.6g OPENSSL_RELEASE=$(OPENSSL_DIR)\out32 OPENSSL_DEBUG=$(OPENSSL_DIR)\out32.dbg OPENSSL_DEFINES=/D OPENSSL OPENSSL_RELEASE_LIBS=$(OPENSSL_RELEASE)\libeay32.lib $(OPENSSL_RELEASE)\ssleay32.lib OPENSSL_DEBUG_LIBS=$(OPENSSL_DEBUG)\libeay32.lib $(OPENSSL_DEBUG)\ssleay32.lib OPENSSL_INCLUDES=-I$(OPENSSL_DIR)\inc32 !ELSE # no OpenSSL OPENSSL_DEFINES= OPENSSL_DIR= OPENSSL_RELEASE= OPENSSL_RELEASE_LIBS= OPENSSL_DEBUG= OPENSSL_DEBUG_LIBS= OPENSSL_INCLUDES= !ENDIF PLATFORM=VC-WIN32 CC=cl.exe LINK=link.exe # # Getting the C run-time flag correct is critical and difficult, sadly # The same C run-time should be used by all the object code that comprises # the process. This means all DLL's and static libs we link to must use the # same C run-time, and we must match it with our flag. # # the wpcap.dll is linked to the static C run-time lib, so we will also # C_RUNTIME_FLAG=/MT COMMON_INCLUDES=-I$(ANALYZE_SRCDIR) -I$(COMMONDIR)\include -I$(COMMON_LIB_SRCDIR) -I$(ANALYZE_NULL_SRCDIR) \ -I$(ANALYZE_SSL_SRCDIR) -I$(WIN32_DIR) $(WINPCAP_INCLUDES) $(OPENSSL_INCLUDES) COMMON_DEFINES=/D STDC /D WIN32 /D _CONSOLE \ $(OPENSSL_DEFINES) /D STDC_HEADERS /D SIZEOF_UNSIGNED_SHORT=2 /D SIZEOF_UNSIGNED_LONG=4 \ /D RETSIGTYPE=void /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 COMMON_CFLAGS=/nologo /W3 $(COMMON_INCLUDES) $(COMMON_DEFINES) /Fp"$(OBJ_DIR)\ssldump.pch" /YX /Fd"$(OBJ_DIR)\\" /FD /c COMMON_LIBS=gdi32.lib Wsock32.lib $(WINPCAP_DEV_DIR)\lib\wpcap.lib COMMON_LFLAGS=/nologo /subsystem:console /machine:I386 /opt:ref /incremental:no # Set build-specific (i.e., release vs. debug) options !IF "$(CFG)" == "release" BUILD_SPECIFIC_INCLUDES= BUILD_SPECIFIC_DEFINES=/D NDEBUG BUILD_SPECIFIC_CFLAGS=$(C_RUNTIME_FLAG) /O2 $(BUILD_SPECIFIC_INCLUDES) $(BUILD_SPECIFIC_DEFINES) BUILD_SPECIFIC_LIBS=$(OPENSSL_RELEASE_LIBS) BUILD_SPECIFIC_LFLAGS= !ELSE # =="debug" BUILD_SPECIFIC_INCLUDES= BUILD_SPECIFIC_DEFINES=/D _DEBUG BUILD_SPECIFIC_CFLAGS=$(C_RUNTIME_FLAG)d /ZI /Od /GZ $(BUILD_SPECIFIC_INCLUDES) $(BUILD_SPECIFIC_DEFINES) BUILD_SPECIFIC_LIBS=$(OPENSSL_DEBUG_LIBS) BUILD_SPECIFIC_LFLAGS= !ENDIF CFLAGS=$(COMMON_CFLAGS) $(BUILD_SPECIFIC_CFLAGS) LFLAGS=$(COMMON_LFLAGS) $(BUILD_SPECIFIC_LFLAGS) $(COMMON_LIBS) $(BUILD_SPECIFIC_LIBS) ALL : $(OBJ_DIR) "$(OBJ_DIR)\ssldump.exe" "$(OBJ_DIR)" : if not exist "$(OBJ_DIR)/$(NULL)" mkdir "$(OBJ_DIR)" CLEAN : -@erase "$(OBJ_DIR)\debug.obj" -@erase "$(OBJ_DIR)\r_assoc.obj" -@erase "$(OBJ_DIR)\r_data.obj" -@erase "$(OBJ_DIR)\r_errors.obj" -@erase "$(OBJ_DIR)\r_list.obj" -@erase "$(OBJ_DIR)\r_replace.obj" -@erase "$(OBJ_DIR)\r_time.obj" -@erase "$(OBJ_DIR)\network.obj" -@erase "$(OBJ_DIR)\pcap-snoop.obj" -@erase "$(OBJ_DIR)\proto_mod.obj" -@erase "$(OBJ_DIR)\tcpconn.obj" -@erase "$(OBJ_DIR)\tcppack.obj" -@erase "$(OBJ_DIR)\null_analyze.obj" -@erase "$(OBJ_DIR)\ciphersuites.obj" -@erase "$(OBJ_DIR)\ssl.enums.obj" -@erase "$(OBJ_DIR)\ssl_analyze.obj" -@erase "$(OBJ_DIR)\ssl_rec.obj" -@erase "$(OBJ_DIR)\ssldecode.obj" -@erase "$(OBJ_DIR)\sslprint.obj" -@erase "$(OBJ_DIR)\sslxprint.obj" -@erase "$(OBJ_DIR)\ssldump.exe" LINK_OBJS= \ "$(OBJ_DIR)\debug.obj" \ "$(OBJ_DIR)\r_assoc.obj" \ "$(OBJ_DIR)\r_data.obj" \ "$(OBJ_DIR)\r_errors.obj" \ "$(OBJ_DIR)\r_list.obj" \ "$(OBJ_DIR)\r_replace.obj" \ "$(OBJ_DIR)\r_time.obj" \ "$(OBJ_DIR)\network.obj" \ "$(OBJ_DIR)\pcap-snoop.obj" \ "$(OBJ_DIR)\proto_mod.obj" \ "$(OBJ_DIR)\tcpconn.obj" \ "$(OBJ_DIR)\tcppack.obj" \ "$(OBJ_DIR)\null_analyze.obj" \ "$(OBJ_DIR)\ciphersuites.obj" \ "$(OBJ_DIR)\ssl.enums.obj" \ "$(OBJ_DIR)\ssl_analyze.obj" \ "$(OBJ_DIR)\ssl_rec.obj" \ "$(OBJ_DIR)\ssldecode.obj" \ "$(OBJ_DIR)\sslprint.obj" \ "$(OBJ_DIR)\sslxprint.obj" "$(OBJ_DIR)\ssldump.exe": "$(OBJ_DIR)" $(LINK_OBJS) $(LINK) @<< /OUT:$@ $(LFLAGS) $(LINK_OBJS) << # # FILE DEPENDENCIES # # file dependencies state, for each file that is built, # which file(s) it depends upon # $(OBJ_DIR)\debug.obj: $(COMMON_LIB_SRCDIR)\debug.h $(OBJ_DIR)\debug.obj: $(COMMON_LIB_SRCDIR)\debug.c $(CC) $(CFLAGS) /Fo$@ $(COMMON_LIB_SRCDIR)\debug.c $(OBJ_DIR)\r_assoc.obj: $(COMMON_LIB_SRCDIR)\r_assoc.c $(CC) $(CFLAGS) /Fo$@ $(COMMON_LIB_SRCDIR)\r_assoc.c $(OBJ_DIR)\r_data.obj: $(COMMON_LIB_SRCDIR)\r_data.h $(OBJ_DIR)\r_data.obj: $(COMMON_LIB_SRCDIR)\r_data.c $(CC) $(CFLAGS) /Fo$@ $(COMMON_LIB_SRCDIR)\r_data.c $(OBJ_DIR)\r_errors.obj: $(COMMON_LIB_SRCDIR)\r_errors.c $(CC) $(CFLAGS) /Fo$@ $(COMMON_LIB_SRCDIR)\r_errors.c $(OBJ_DIR)\r_list.obj: $(COMMON_LIB_SRCDIR)\r_list.c $(CC) $(CFLAGS) /Fo$@ $(COMMON_LIB_SRCDIR)\r_list.c $(OBJ_DIR)\r_replace.obj: $(COMMON_LIB_SRCDIR)\r_replace.c $(CC) $(CFLAGS) /Fo$@ $(COMMON_LIB_SRCDIR)\r_replace.c $(OBJ_DIR)\r_time.obj: $(COMMON_LIB_SRCDIR)\r_time.c $(CC) $(CFLAGS) /Fo$@ $(COMMON_LIB_SRCDIR)\r_time.c $(OBJ_DIR)\network.obj: $(ANALYZE_SRCDIR)\network.h $(OBJ_DIR)\network.obj: $(ANALYZE_SRCDIR)\network.c $(CC) $(CFLAGS) /Fo$@ $(ANALYZE_SRCDIR)\network.c $(OBJ_DIR)\pcap-snoop.obj: $(ANALYZE_SRCDIR)\pcap-snoop.c $(CC) $(CFLAGS) /Fo$@ $(ANALYZE_SRCDIR)\pcap-snoop.c $(OBJ_DIR)\proto_mod.obj: $(ANALYZE_SRCDIR)\proto_mod.h $(OBJ_DIR)\proto_mod.obj: $(ANALYZE_SRCDIR)\proto_mod.c $(CC) $(CFLAGS) /Fo$@ $(ANALYZE_SRCDIR)\proto_mod.c $(OBJ_DIR)\tcpconn.obj: $(ANALYZE_SRCDIR)\tcpconn.h $(OBJ_DIR)\tcpconn.obj: $(ANALYZE_SRCDIR)\tcpconn.c $(CC) $(CFLAGS) /Fo$@ $(ANALYZE_SRCDIR)\tcpconn.c $(OBJ_DIR)\tcppack.obj: $(ANALYZE_SRCDIR)\tcppack.h $(OBJ_DIR)\tcppack.obj: $(ANALYZE_SRCDIR)\tcppack.c $(CC) $(CFLAGS) /Fo$@ $(ANALYZE_SRCDIR)\tcppack.c $(OBJ_DIR)\null_analyze.obj: $(ANALYZE_NULL_SRCDIR)\null_analyze.h $(OBJ_DIR)\null_analyze.obj: $(ANALYZE_NULL_SRCDIR)\null_analyze.c $(CC) $(CFLAGS) /Fo$@ $(ANALYZE_NULL_SRCDIR)\null_analyze.c $(OBJ_DIR)\ciphersuites.obj: $(ANALYZE_SSL_SRCDIR)\ciphersuites.c $(CC) $(CFLAGS) /Fo$@ $(ANALYZE_SSL_SRCDIR)\ciphersuites.c $(OBJ_DIR)\ssl.enums.obj: $(ANALYZE_SSL_SRCDIR)\ssl.enums.h $(OBJ_DIR)\ssl.enums.obj: $(ANALYZE_SSL_SRCDIR)\ssl.enums.c $(CC) $(CFLAGS) /Fo$@ $(ANALYZE_SSL_SRCDIR)\ssl.enums.c $(OBJ_DIR)\ssl_analyze.obj: $(ANALYZE_SSL_SRCDIR)\ssl_analyze.h $(OBJ_DIR)\ssl_analyze.obj: $(ANALYZE_SSL_SRCDIR)\ssl_analyze.c $(CC) $(CFLAGS) /Fo$@ $(ANALYZE_SSL_SRCDIR)\ssl_analyze.c $(OBJ_DIR)\ssl_rec.obj: $(ANALYZE_SSL_SRCDIR)\ssl_rec.c $(CC) $(CFLAGS) /Fo$@ $(ANALYZE_SSL_SRCDIR)\ssl_rec.c $(OBJ_DIR)\ssldecode.obj: $(ANALYZE_SSL_SRCDIR)\ssldecode.h $(OBJ_DIR)\ssldecode.obj: $(ANALYZE_SSL_SRCDIR)\ssldecode.c $(CC) $(CFLAGS) /Fo$@ $(ANALYZE_SSL_SRCDIR)\ssldecode.c $(OBJ_DIR)\sslprint.obj: $(ANALYZE_SSL_SRCDIR)\sslprint.h $(OBJ_DIR)\sslprint.obj: $(ANALYZE_SSL_SRCDIR)\sslprint.c $(CC) $(CFLAGS) /Fo$@ $(ANALYZE_SSL_SRCDIR)\sslprint.c $(OBJ_DIR)\sslxprint.obj: $(ANALYZE_SSL_SRCDIR)\sslxprint.h $(OBJ_DIR)\sslxprint.obj: $(ANALYZE_SSL_SRCDIR)\sslxprint.c $(CC) $(CFLAGS) /Fo$@ $(ANALYZE_SSL_SRCDIR)\sslxprint.c