Compare commits

..

10 Commits

Author SHA1 Message Date
Alex Eyers-Taylor
ea8c73428d Java: Make non-returning methods use local to global. 2025-06-12 18:39:32 +01:00
Kasper Svendsen
a80fbf09a8 Overlay annotation script shouldn't manage overlay[local] and overlay[global] 2025-05-27 08:30:14 +02:00
Kasper Svendsen
5b487266f1 Mark ActivateModels subclasses overlay[local?] 2025-05-27 08:30:14 +02:00
Kasper Svendsen
e89079ce76 Virtual dispatch must be local 2025-05-27 08:30:13 +02:00
Kasper Svendsen
b98300bc79 DataFlowImplCommon: Mark LambdaFlow as overlay global 2025-05-27 08:30:13 +02:00
Kasper Svendsen
9ada903922 Member: Allow methods with empty bodies for overlay 2025-05-27 08:30:12 +02:00
Kasper Svendsen
f8373c1f19 Define entity discard predicates for Java 2025-05-27 08:30:11 +02:00
Philip Ginsbach
6454521957 set compileForOverlayEval true for java 2025-05-27 08:30:11 +02:00
Philip Ginsbach
9712e25fec update python and csharp via config/sync-files.py 2025-05-27 08:30:10 +02:00
Philip Ginsbach
8d9281e9d1 annotate .qll files in java and shared via script 2025-05-27 08:30:10 +02:00
4718 changed files with 64641 additions and 273507 deletions

View File

@@ -6,18 +6,18 @@ on:
ripunzip-version:
description: "what reference to checktout from google/runzip"
required: false
default: v2.0.2
default: v1.2.1
openssl-version:
description: "what reference to checkout from openssl/openssl for Linux"
required: false
default: openssl-3.5.0
default: openssl-3.3.0
jobs:
build:
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04, macos-13, windows-2022]
os: [ubuntu-22.04, macos-13, windows-2019]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4

View File

@@ -16,6 +16,7 @@ on:
- "shared/**/*.qll"
- "!**/experimental/**"
- "!ql/**"
- "!rust/**"
- ".github/workflows/check-change-note.yml"
jobs:

34
.github/workflows/codegen.yml vendored Normal file
View File

@@ -0,0 +1,34 @@
name: Codegen
on:
pull_request:
paths:
- "misc/bazel/**"
- "misc/codegen/**"
- "*.bazel*"
- .github/workflows/codegen.yml
- .pre-commit-config.yaml
branches:
- main
- rc/*
- codeql-cli-*
permissions:
contents: read
jobs:
codegen:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version-file: 'misc/codegen/.python-version'
- uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507
name: Check that python code is properly formatted
with:
extra_args: autopep8 --all-files
- name: Run codegen tests
shell: bash
run: |
bazel test //misc/codegen/...

View File

@@ -36,7 +36,7 @@ jobs:
unit-tests:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
os: [ubuntu-latest, windows-2019]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
@@ -66,6 +66,6 @@ jobs:
# Update existing stubs in the repo with the freshly generated ones
mv "$STUBS_PATH/output/stubs/_frameworks" ql/test/resources/stubs/
git status
codeql test run --threads=0 --search-path "${{ github.workspace }}" --check-databases --check-diff-informed --check-undefined-labels --check-repeated-labels --check-redefined-labels --consistency-queries ql/consistency-queries -- ql/test/library-tests/dataflow/flowsources/aspremote
codeql test run --threads=0 --search-path "${{ github.workspace }}" --check-databases --check-undefined-labels --check-repeated-labels --check-redefined-labels --consistency-queries ql/consistency-queries -- ql/test/library-tests/dataflow/flowsources/aspremote
env:
GITHUB_TOKEN: ${{ github.token }}

View File

@@ -1,35 +0,0 @@
name: Python tooling
on:
pull_request:
paths:
- "misc/bazel/**"
- "misc/codegen/**"
- "misc/scripts/models-as-data/bulk_generate_mad.py"
- "*.bazel*"
- .github/workflows/codegen.yml
- .pre-commit-config.yaml
branches:
- main
- rc/*
- codeql-cli-*
permissions:
contents: read
jobs:
check-python-tooling:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507
name: Check that python code is properly formatted
with:
extra_args: black --all-files
- name: Run codegen tests
shell: bash
run: |
bazel test //misc/codegen/...

View File

@@ -53,7 +53,7 @@ jobs:
- name: Create database
run: |
"${CODEQL}" database create \
--search-path "${{ github.workspace }}" \
--search-path "${{ github.workspace }}"
--threads 4 \
--language ql --source-root "${{ github.workspace }}/repo" \
"${{ runner.temp }}/database"

View File

@@ -35,6 +35,6 @@ jobs:
key: ruby-qltest
- name: Run QL tests
run: |
codeql test run --dynamic-join-order-mode=all --threads=0 --ram 50000 --search-path "${{ github.workspace }}" --check-databases --check-diff-informed --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
codeql test run --dynamic-join-order-mode=all --threads=0 --ram 50000 --search-path "${{ github.workspace }}" --check-databases --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
env:
GITHUB_TOKEN: ${{ github.token }}

View File

@@ -68,6 +68,6 @@ jobs:
key: ruby-qltest
- name: Run QL tests
run: |
codeql test run --threads=0 --ram 50000 --search-path "${{ github.workspace }}" --check-databases --check-diff-informed --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
codeql test run --threads=0 --ram 50000 --search-path "${{ github.workspace }}" --check-databases --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
env:
GITHUB_TOKEN: ${{ github.token }}

View File

@@ -32,7 +32,7 @@ jobs:
if: github.repository_owner == 'github'
strategy:
matrix:
runner: [ubuntu-latest, macos-15-xlarge]
runner: [ubuntu-latest, macos-13-xlarge]
fail-fast: false
runs-on: ${{ matrix.runner }}
steps:

View File

@@ -31,4 +31,4 @@ jobs:
- name: Fail if there are any errors with existing change notes
run: |
codeql pack release --groups actions,cpp,csharp,go,java,javascript,python,ruby,shared,swift -examples,-test,-experimental
codeql pack release --groups cpp,csharp,java,javascript,python,ruby,-examples,-test,-experimental

View File

@@ -1,7 +1,5 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
default_language_version:
python: python3.12
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
@@ -9,18 +7,18 @@ repos:
- id: trailing-whitespace
exclude: /test/.*$(?<!\.qlref)|.*\.patch$|.*\.qll?$
- id: end-of-file-fixer
exclude: Cargo.lock$|/test/.*$(?<!\.qlref)|.*\.patch$|.*\.qll?$
exclude: /test/.*$(?<!\.qlref)|.*\.patch$|.*\.qll?$
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: v17.0.6
hooks:
- id: clang-format
- repo: https://github.com/psf/black
rev: 25.1.0
- repo: https://github.com/pre-commit/mirrors-autopep8
rev: v2.0.4
hooks:
- id: black
files: ^(misc/codegen/.*|misc/scripts/models-as-data/.*)\.py$
- id: autopep8
files: ^misc/codegen/.*\.py
- repo: local
hooks:

View File

@@ -16,7 +16,7 @@
/java/ql/test-kotlin2/ @github/codeql-kotlin
# Experimental CodeQL cryptography
**/experimental/**/quantum/ @github/ps-codeql
**/experimental/quantum/ @github/ps-codeql
/shared/quantum/ @github/ps-codeql
# CodeQL tools and associated docs

960
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -11,3 +11,8 @@ members = [
"rust/autobuild",
]
exclude = ["mad-generation-build"]
[patch.crates-io]
# patch for build script bug preventing bazel build
# see https://github.com/rust-lang/rustc_apfloat/pull/17
rustc_apfloat = { git = "https://github.com/redsun82/rustc_apfloat.git", rev = "32968f16ef1b082243f9bf43a3fbd65c381b3e27" }

View File

@@ -37,7 +37,7 @@ bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True
# the versions there are canonical, the versions here are used for CI in github/codeql, as well as for the vendoring of dependencies.
RUST_EDITION = "2024"
RUST_VERSION = "1.86.0"
RUST_VERSION = "1.85.0"
rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
rust.toolchain(
@@ -71,11 +71,11 @@ use_repo(
tree_sitter_extractors_deps = use_extension("//misc/bazel/3rdparty:tree_sitter_extractors_extension.bzl", "r")
use_repo(
tree_sitter_extractors_deps,
"vendor_ts__anyhow-1.0.98",
"vendor_ts__anyhow-1.0.97",
"vendor_ts__argfile-0.2.1",
"vendor_ts__chalk-ir-0.103.0",
"vendor_ts__chrono-0.4.41",
"vendor_ts__clap-4.5.40",
"vendor_ts__chalk-ir-0.100.0",
"vendor_ts__chrono-0.4.40",
"vendor_ts__clap-4.5.35",
"vendor_ts__dunce-1.0.5",
"vendor_ts__either-1.15.0",
"vendor_ts__encoding-0.2.33",
@@ -87,33 +87,33 @@ use_repo(
"vendor_ts__lazy_static-1.5.0",
"vendor_ts__mustache-0.9.0",
"vendor_ts__num-traits-0.2.19",
"vendor_ts__num_cpus-1.17.0",
"vendor_ts__proc-macro2-1.0.95",
"vendor_ts__num_cpus-1.16.0",
"vendor_ts__proc-macro2-1.0.94",
"vendor_ts__quote-1.0.40",
"vendor_ts__ra_ap_base_db-0.0.288",
"vendor_ts__ra_ap_cfg-0.0.288",
"vendor_ts__ra_ap_hir-0.0.288",
"vendor_ts__ra_ap_hir_def-0.0.288",
"vendor_ts__ra_ap_hir_expand-0.0.288",
"vendor_ts__ra_ap_hir_ty-0.0.288",
"vendor_ts__ra_ap_ide_db-0.0.288",
"vendor_ts__ra_ap_intern-0.0.288",
"vendor_ts__ra_ap_load-cargo-0.0.288",
"vendor_ts__ra_ap_parser-0.0.288",
"vendor_ts__ra_ap_paths-0.0.288",
"vendor_ts__ra_ap_project_model-0.0.288",
"vendor_ts__ra_ap_span-0.0.288",
"vendor_ts__ra_ap_stdx-0.0.288",
"vendor_ts__ra_ap_syntax-0.0.288",
"vendor_ts__ra_ap_vfs-0.0.288",
"vendor_ts__rand-0.9.1",
"vendor_ts__ra_ap_base_db-0.0.273",
"vendor_ts__ra_ap_cfg-0.0.273",
"vendor_ts__ra_ap_hir-0.0.273",
"vendor_ts__ra_ap_hir_def-0.0.273",
"vendor_ts__ra_ap_hir_expand-0.0.273",
"vendor_ts__ra_ap_hir_ty-0.0.273",
"vendor_ts__ra_ap_ide_db-0.0.273",
"vendor_ts__ra_ap_intern-0.0.273",
"vendor_ts__ra_ap_load-cargo-0.0.273",
"vendor_ts__ra_ap_parser-0.0.273",
"vendor_ts__ra_ap_paths-0.0.273",
"vendor_ts__ra_ap_project_model-0.0.273",
"vendor_ts__ra_ap_span-0.0.273",
"vendor_ts__ra_ap_stdx-0.0.273",
"vendor_ts__ra_ap_syntax-0.0.273",
"vendor_ts__ra_ap_vfs-0.0.273",
"vendor_ts__rand-0.9.0",
"vendor_ts__rayon-1.10.0",
"vendor_ts__regex-1.11.1",
"vendor_ts__serde-1.0.219",
"vendor_ts__serde_json-1.0.140",
"vendor_ts__serde_with-3.13.0",
"vendor_ts__syn-2.0.103",
"vendor_ts__toml-0.8.23",
"vendor_ts__serde_with-3.12.0",
"vendor_ts__syn-2.0.100",
"vendor_ts__toml-0.8.20",
"vendor_ts__tracing-0.1.41",
"vendor_ts__tracing-flame-0.2.0",
"vendor_ts__tracing-subscriber-0.3.19",
@@ -124,7 +124,6 @@ use_repo(
"vendor_ts__tree-sitter-ruby-0.23.1",
"vendor_ts__triomphe-0.1.14",
"vendor_ts__ungrammar-1.16.1",
"vendor_ts__zstd-0.13.3",
)
http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
@@ -239,24 +238,24 @@ go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
go_deps.from_file(go_mod = "//go/extractor:go.mod")
use_repo(go_deps, "org_golang_x_mod", "org_golang_x_tools")
lfs_archive = use_repo_rule("//misc/bazel:lfs.bzl", "lfs_archive")
lfs_files = use_repo_rule("//misc/bazel:lfs.bzl", "lfs_files")
lfs_archive(
lfs_files(
name = "ripunzip-linux",
src = "//misc/ripunzip:ripunzip-Linux.zip",
build_file = "//misc/ripunzip:BUILD.ripunzip.bazel",
srcs = ["//misc/ripunzip:ripunzip-linux"],
executable = True,
)
lfs_archive(
lfs_files(
name = "ripunzip-windows",
src = "//misc/ripunzip:ripunzip-Windows.zip",
build_file = "//misc/ripunzip:BUILD.ripunzip.bazel",
srcs = ["//misc/ripunzip:ripunzip-windows.exe"],
executable = True,
)
lfs_archive(
lfs_files(
name = "ripunzip-macos",
src = "//misc/ripunzip:ripunzip-macOS.zip",
build_file = "//misc/ripunzip:BUILD.ripunzip.bazel",
srcs = ["//misc/ripunzip:ripunzip-macos"],
executable = True,
)
register_toolchains(

View File

@@ -2,7 +2,7 @@ import runs_on
import pytest
from query_suites import *
well_known_query_suites = ['actions-code-quality.qls', 'actions-code-quality-extended.qls', 'actions-security-and-quality.qls', 'actions-security-extended.qls', 'actions-code-scanning.qls']
well_known_query_suites = ['actions-code-quality.qls', 'actions-security-and-quality.qls', 'actions-security-extended.qls', 'actions-code-scanning.qls']
@runs_on.posix
@pytest.mark.parametrize("query_suite", well_known_query_suites)

View File

@@ -1,19 +1,3 @@
## 0.4.12
### Minor Analysis Improvements
* Fixed performance issues in the parsing of Bash scripts in workflow files,
which led to out-of-disk errors when analysing certain workflow files with
complex interpolations of shell commands or quoted strings.
## 0.4.11
No user-facing changes.
## 0.4.10
No user-facing changes.
## 0.4.9
No user-facing changes.

View File

@@ -1,3 +0,0 @@
## 0.4.10
No user-facing changes.

View File

@@ -1,3 +0,0 @@
## 0.4.11
No user-facing changes.

View File

@@ -1,7 +0,0 @@
## 0.4.12
### Minor Analysis Improvements
* Fixed performance issues in the parsing of Bash scripts in workflow files,
which led to out-of-disk errors when analysing certain workflow files with
complex interpolations of shell commands or quoted strings.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.4.12
lastReleaseVersion: 0.4.9

View File

@@ -50,8 +50,8 @@ class Expression extends AstNode instanceof ExpressionImpl {
string getNormalizedExpression() { result = normalizeExpr(expression) }
}
/** An `env` in workflow, job or step. */
class Env extends AstNode instanceof EnvImpl {
/** A common class for `env` in workflow, job or step. */
abstract class Env extends AstNode instanceof EnvImpl {
/** Gets an environment variable value given its name. */
ScalarValueImpl getEnvVarValue(string name) { result = super.getEnvVarValue(name) }

View File

@@ -8,64 +8,35 @@ class BashShellScript extends ShellScript {
)
}
/**
* Gets the line at 0-based index `lineIndex` within this shell script,
* assuming newlines as separators.
*/
private string lineProducer(int lineIndex) {
result = this.getRawScript().regexpReplaceAll("\\\\\\s*\n", "").splitAt("\n", lineIndex)
private string lineProducer(int i) {
result = this.getRawScript().regexpReplaceAll("\\\\\\s*\n", "").splitAt("\n", i)
}
private predicate cmdSubstitutionReplacement(string command, string id, int lineIndex) {
this.commandInSubstitution(lineIndex, command, id)
or
this.commandInBackticks(lineIndex, command, id)
}
/**
* Holds if there is a command substitution `$(command)` in
* the line at `lineIndex` in the shell script,
* and `id` is a unique identifier for this command.
*/
private predicate commandInSubstitution(int lineIndex, string command, string id) {
exists(int occurrenceIndex, int occurrenceOffset |
command =
// Look for the command inside a $(...) command substitution
this.lineProducer(lineIndex)
.regexpFind("\\$\\((?:[^()]+|\\((?:[^()]+|\\([^()]*\\))*\\))*\\)", occurrenceIndex,
occurrenceOffset)
// trim starting $( - TODO do this in first regex
.regexpReplaceAll("^\\$\\(", "")
// trim ending ) - TODO do this in first regex
.regexpReplaceAll("\\)$", "") and
id = "cmdsubs:" + lineIndex + ":" + occurrenceIndex + ":" + occurrenceOffset
private predicate cmdSubstitutionReplacement(string cmdSubs, string id, int k) {
exists(string line | line = this.lineProducer(k) |
exists(int i, int j |
cmdSubs =
// $() cmd substitution
line.regexpFind("\\$\\((?:[^()]+|\\((?:[^()]+|\\([^()]*\\))*\\))*\\)", i, j)
.regexpReplaceAll("^\\$\\(", "")
.regexpReplaceAll("\\)$", "") and
id = "cmdsubs:" + k + ":" + i + ":" + j
)
or
exists(int i, int j |
// `...` cmd substitution
cmdSubs =
line.regexpFind("\\`[^\\`]+\\`", i, j)
.regexpReplaceAll("^\\`", "")
.regexpReplaceAll("\\`$", "") and
id = "cmd:" + k + ":" + i + ":" + j
)
)
}
/**
* Holds if `command` is a command in backticks `` `...` `` in
* the line at `lineIndex` in the shell script,
* and `id` is a unique identifier for this command.
*/
private predicate commandInBackticks(int lineIndex, string command, string id) {
exists(int occurrenceIndex, int occurrenceOffset |
command =
this.lineProducer(lineIndex)
.regexpFind("\\`[^\\`]+\\`", occurrenceIndex, occurrenceOffset)
// trim leading backtick - TODO do this in first regex
.regexpReplaceAll("^\\`", "")
// trim trailing backtick - TODO do this in first regex
.regexpReplaceAll("\\`$", "") and
id = "cmd:" + lineIndex + ":" + occurrenceIndex + ":" + occurrenceOffset
)
}
private predicate rankedCmdSubstitutionReplacements(int i, string command, string commandId) {
// rank commands by their unique IDs
commandId = rank[i](string c, string id | this.cmdSubstitutionReplacement(c, id, _) | id) and
// since we cannot output (command, ID) tuples from the rank operation,
// we need to work out the specific command associated with the resulting ID
this.cmdSubstitutionReplacement(command, commandId, _)
private predicate rankedCmdSubstitutionReplacements(int i, string old, string new) {
old = rank[i](string old2 | this.cmdSubstitutionReplacement(old2, _, _) | old2) and
this.cmdSubstitutionReplacement(old, new, _)
}
private predicate doReplaceCmdSubstitutions(int line, int round, string old, string new) {
@@ -93,56 +64,31 @@ class BashShellScript extends ShellScript {
this.cmdSubstitutionReplacement(result, _, i)
}
/**
* Holds if `quotedStr` is a string in double quotes in
* the line at `lineIndex` in the shell script,
* and `id` is a unique identifier for this quoted string.
*/
private predicate doubleQuotedString(int lineIndex, string quotedStr, string id) {
exists(int occurrenceIndex, int occurrenceOffset |
// double quoted string
quotedStr =
this.cmdSubstitutedLineProducer(lineIndex)
.regexpFind("\"((?:[^\"\\\\]|\\\\.)*)\"", occurrenceIndex, occurrenceOffset) and
id =
"qstr:" + lineIndex + ":" + occurrenceIndex + ":" + occurrenceOffset + ":" +
quotedStr.length() + ":" + quotedStr.regexpReplaceAll("[^a-zA-Z0-9]", "")
)
}
/**
* Holds if `quotedStr` is a string in single quotes in
* the line at `lineIndex` in the shell script,
* and `id` is a unique identifier for this quoted string.
*/
private predicate singleQuotedString(int lineIndex, string quotedStr, string id) {
exists(int occurrenceIndex, int occurrenceOffset |
// single quoted string
quotedStr =
this.cmdSubstitutedLineProducer(lineIndex)
.regexpFind("'((?:\\\\.|[^'\\\\])*)'", occurrenceIndex, occurrenceOffset) and
id =
"qstr:" + lineIndex + ":" + occurrenceIndex + ":" + occurrenceOffset + ":" +
quotedStr.length() + ":" + quotedStr.regexpReplaceAll("[^a-zA-Z0-9]", "")
)
}
private predicate quotedStringReplacement(string quotedStr, string id) {
exists(int lineIndex |
this.doubleQuotedString(lineIndex, quotedStr, id)
exists(string line, int k | line = this.cmdSubstitutedLineProducer(k) |
exists(int i, int j |
// double quoted string
quotedStr = line.regexpFind("\"((?:[^\"\\\\]|\\\\.)*)\"", i, j) and
id =
"qstr:" + k + ":" + i + ":" + j + ":" + quotedStr.length() + ":" +
quotedStr.regexpReplaceAll("[^a-zA-Z0-9]", "")
)
or
this.singleQuotedString(lineIndex, quotedStr, id)
exists(int i, int j |
// single quoted string
quotedStr = line.regexpFind("'((?:\\\\.|[^'\\\\])*)'", i, j) and
id =
"qstr:" + k + ":" + i + ":" + j + ":" + quotedStr.length() + ":" +
quotedStr.regexpReplaceAll("[^a-zA-Z0-9]", "")
)
) and
// Only do this for strings that might otherwise disrupt subsequent parsing
quotedStr.regexpMatch("[\"'].*[$\n\r'\"" + Bash::separator() + "].*[\"']")
}
private predicate rankedQuotedStringReplacements(int i, string quotedString, string quotedStringId) {
// rank quoted strings by their nearly-unique IDs
quotedStringId = rank[i](string s, string id | this.quotedStringReplacement(s, id) | id) and
// since we cannot output (string, ID) tuples from the rank operation,
// we need to work out the specific string associated with the resulting ID
this.quotedStringReplacement(quotedString, quotedStringId)
private predicate rankedQuotedStringReplacements(int i, string old, string new) {
old = rank[i](string old2 | this.quotedStringReplacement(old2, _) | old2) and
this.quotedStringReplacement(old, new)
}
private predicate doReplaceQuotedStrings(int line, int round, string old, string new) {

View File

@@ -214,10 +214,6 @@ private module OutputClobberingConfig implements DataFlow::ConfigSig {
)
)
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
}
/** Tracks flow of unsafe user input that is used to construct and evaluate an environment variable. */

View File

@@ -16,10 +16,6 @@ private module RequestForgeryConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
predicate isSink(DataFlow::Node sink) { sink instanceof RequestForgerySink }
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
}
/** Tracks flow of unsafe user input that is used to construct and evaluate a system command. */

View File

@@ -15,10 +15,6 @@ private module SecretExfiltrationConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
predicate isSink(DataFlow::Node sink) { sink instanceof SecretExfiltrationSink }
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
}
/** Tracks flow of unsafe user input that is used in a context where it may lead to a secret exfiltration. */

View File

@@ -1,5 +1,5 @@
name: codeql/actions-all
version: 0.4.13-dev
version: 0.4.10-dev
library: true
warnOnImplicitThis: true
dependencies:

View File

@@ -1,17 +1,3 @@
## 0.6.4
No user-facing changes.
## 0.6.3
No user-facing changes.
## 0.6.2
### Minor Analysis Improvements
* The query `actions/missing-workflow-permissions` is now aware of the minimal permissions needed for the actions `deploy-pages`, `delete-package-versions`, `ai-inference`. This should lead to better alert messages and better fix suggestions.
## 0.6.1
No user-facing changes.

View File

@@ -24,10 +24,6 @@ private module MyConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) {
sink instanceof CodeInjectionSink and not madSink(sink, "code-injection")
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
}
module MyFlow = TaintTracking::Global<MyConfig>;

View File

@@ -34,10 +34,6 @@ private module MyConfig implements DataFlow::ConfigSig {
isSink(node) and
set instanceof DataFlow::FieldContent
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
}
module MyFlow = TaintTracking::Global<MyConfig>;

View File

@@ -25,10 +25,6 @@ private module MyConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) {
exists(CompositeAction c | c.getAnOutputExpr() = sink.asExpr())
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
}
module MyFlow = TaintTracking::Global<MyConfig>;

View File

@@ -24,10 +24,6 @@ private module MyConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) {
sink instanceof CodeInjectionSink and not madSink(sink, "code-injection")
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
}
module MyFlow = TaintTracking::Global<MyConfig>;

View File

@@ -34,10 +34,6 @@ private module MyConfig implements DataFlow::ConfigSig {
isSink(node) and
set instanceof DataFlow::FieldContent
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
}
module MyFlow = TaintTracking::Global<MyConfig>;

View File

@@ -25,10 +25,6 @@ private module MyConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) {
exists(ReusableWorkflow w | w.getAnOutputExpr() = sink.asExpr())
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
}
module MyFlow = TaintTracking::Global<MyConfig>;

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The query `actions/missing-workflow-permissions` is now aware of the minimal permissions needed for the actions `deploy-pages`, `delete-package-versions`, `ai-inference`. This should lead to better alert messages and better fix suggestions.

View File

@@ -1,5 +0,0 @@
## 0.6.2
### Minor Analysis Improvements
* The query `actions/missing-workflow-permissions` is now aware of the minimal permissions needed for the actions `deploy-pages`, `delete-package-versions`, `ai-inference`. This should lead to better alert messages and better fix suggestions.

View File

@@ -1,3 +0,0 @@
## 0.6.3
No user-facing changes.

View File

@@ -1,3 +0,0 @@
## 0.6.4
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.6.4
lastReleaseVersion: 0.6.1

View File

@@ -1,3 +0,0 @@
- queries: .
- apply: code-quality-extended-selectors.yml
from: codeql/suite-helpers

View File

@@ -1,5 +1,5 @@
name: codeql/actions-queries
version: 0.6.5-dev
version: 0.6.2-dev
library: false
warnOnImplicitThis: true
groups: [actions, queries]

View File

@@ -1,81 +0,0 @@
name: Workflow with complex interpolation
on:
workflow_dispatch:
inputs:
choice-a:
required: true
type: choice
description: choice-a
default: a1
options:
- a1
- a2
- a3
string-b:
required: false
type: string
description: string-b
string-c:
required: false
type: string
description: string-c
list-d:
required: true
type: string
default: d1 d2
description: list-d whitespace separated
list-e:
required: false
type: string
description: list-e whitespace separated
choice-f:
required: true
type: choice
description: choice-f
options:
- false
- true
env:
DRY_TEST: false
B: ${{ github.event.inputs.string-b }}
jobs:
job:
runs-on: ubuntu-latest
steps:
- name: Produce values
id: produce-values
run: |
echo "region=region" >> $GITHUB_OUTPUT
echo "zone=zone" >> $GITHUB_OUTPUT
- name: Step with complex interpolation
id: complex
env:
CHOICE_A: ${{ github.event.inputs.choice-a }}
STRING_B: ${{ github.event.inputs.string-b }}
STRING_C: ${{ github.event.inputs.string-c }}
LIST_D: ${{ github.event.inputs.list-d }}
LIST_E: ${{ github.event.inputs.list-e }}
CHOICE_F: ${{ github.event.inputs.choice-f }}
REGION: ${{ steps.produce-values.outputs.region }}
ZONE: ${{ steps.produce-values.outputs.zone }}
DRY_TEST_JSON: ${{ fromJSON(env.DRY_TEST) }}
FUNCTION_NAME: my-function
USER_EMAIL: 'example@example.com'
TYPE: type
RANGE: '0-100'
run: |
comma_separated_list_d=$(echo "${LIST_D}" | sed "s/ /\",\"/g")
comma_separated_list_e=$(echo "${LIST_E}" | sed "s/ /\",\"/g")
c1=$(echo "${STRING_C}" | cut -d "-" -f 1)
c2=$(echo "${STRING_C}" | cut -d "-" -f 2)
# Similar commands that use JSON payloads with string interpolation.
response=$(aws lambda invoke --invocation-type RequestResponse --function-name "${FUNCTION_NAME}" --region "${REGION}" --cli-read-timeout 0 --cli-binary-format raw-in-base64-out --payload '{"appName":"my-app","chA":"'"${CHOICE_A}"'","c1":"'"${c1}"'","c2":"'"${c2}"'","a":"${CHOICE_A}","bValue":"${B}","zone":"${ZONE}","userEmail":"'"${USER_EMAIL}"'","region":"${REGION}","range":"${RANGE}","type":"${TYPE}","b":"${STRING_B}","listD":"","listE":"","dryTest":'"${DRY_TEST_JSON}"',"f":"${CHOICE_F}"}' ./config.json --log-type Tail)
response=$(aws lambda invoke --invocation-type RequestResponse --function-name "${FUNCTION_NAME}" --region "${REGION}" --cli-read-timeout 0 --cli-binary-format raw-in-base64-out --payload '{"appName":"my-app","chA":"'"${CHOICE_A}"'","c1":"'"${c1}"'","c2":"'"${c2}"'","a":"${CHOICE_A}","bValue":"${B}","zone":"${ZONE}","userEmail":"'"${USER_EMAIL}"'","region":"${REGION}","range":"${RANGE}","type":"${TYPE}","b":"${STRING_B}","listD":["'"${comma_separated_list_d}"'"],"listE":"","dryTest":'"${DRY_TEST_JSON}"',"f":"${CHOICE_F}"}' ./config.json --log-type Tail)
response=$(aws lambda invoke --invocation-type RequestResponse --function-name "${FUNCTION_NAME}" --region "${REGION}" --cli-read-timeout 0 --cli-binary-format raw-in-base64-out --payload '{"appName":"my-app","chA":"'"${CHOICE_A}"'","c1":"'"${c1}"'","c2":"'"${c2}"'","a":"${CHOICE_A}","bValue":"${B}","zone":"${ZONE}","userEmail":"'"${USER_EMAIL}"'","region":"${REGION}","range":"${RANGE}","type":"${TYPE}","b":"${STRING_B}","listD":["'"${comma_separated_list_d}"'"],"listE":"","dryTest":'"${DRY_TEST_JSON}"',"f":"${CHOICE_F}"}' ./config.json --log-type Tail)
response=$(aws lambda invoke --invocation-type RequestResponse --function-name "${FUNCTION_NAME}" --region "${REGION}" --cli-read-timeout 0 --cli-binary-format raw-in-base64-out --payload '{"appName":"my-app","chA":"'"${CHOICE_A}"'","c1":"'"${c1}"'","c2":"'"${c2}"'","a":"${CHOICE_A}","bValue":"${B}","zone":"${ZONE}","userEmail":"'"${USER_EMAIL}"'","region":"${REGION}","range":"${RANGE}","type":"${TYPE}","b":"${STRING_B}","listD":["'"${comma_separated_list_d}"'"],"listE":"","dryTest":'"${DRY_TEST_JSON}"',"f":"${CHOICE_F}"}' ./config.json --log-type Tail)
response=$(aws lambda invoke --invocation-type RequestResponse --function-name "${FUNCTION_NAME}" --region "${REGION}" --cli-read-timeout 0 --cli-binary-format raw-in-base64-out --payload '{"appName":"my-app","chA":"'"${CHOICE_A}"'","c1":"'"${c1}"'","c2":"'"${c2}"'","a":"${CHOICE_A}","bValue":"${B}","zone":"${ZONE}","userEmail":"'"${USER_EMAIL}"'","region":"${REGION}","range":"${RANGE}","type":"${TYPE}","b":"${STRING_B}","listD":"","listE":["'"${comma_separated_list_e}"'"],"dryTest":'"${DRY_TEST_JSON}"',"f":"${CHOICE_F}"}' ./config.json --log-type Tail)
shell: bash

View File

@@ -1,274 +0,0 @@
# This script is used to annotate .qll files without any existing overlay annotations
# with overlay[local?] and overlay[caller?] annotations. Maintenance of overlay annotations
# in annotated files will be handled by QL-for-QL queries.
# It will walk the directory tree and annotate most .qll files, skipping only
# some specific cases (e.g., empty files, files that configure dataflow for queries).
# The script takes a list of languages and processes the corresponding directories.
# If the optional --check argument is provided, the script checks for missing annotations,
# but does not modify any files.
# Usage: python3 add-overlay-annotations.py [--check] <language1> <language2> ...
# The script will modify the files in place and print the changes made.
# The script is designed to be run from the root of the repository.
#!/usr/bin/python3
import sys
import os
import re
from difflib import context_diff
OVERLAY_PATTERN = re.compile(r'overlay\[[a-zA-Z?_-]+\]')
def has_overlay_annotations(lines):
'''
Check whether the given lines contain any overlay[...] annotations.
'''
return any(OVERLAY_PATTERN.search(line) for line in lines)
def is_line_comment(line):
return line.startswith("//") or (line.startswith("/*") and line.endswith("*/"))
def find_file_level_module_declaration(lines):
'''
Returns the index of the existing file-level module declaration if one
exists. Returns None otherwise.
'''
comment = False
for i, line in enumerate(lines):
trimmed = line.strip()
if is_line_comment(trimmed):
continue
elif trimmed.startswith("/*"):
comment = True
elif comment and trimmed.endswith("*/"):
comment = False
elif not comment and trimmed.endswith("module;"):
return i
return None
def is_file_module_qldoc(i, lines):
'''
Assuming a qldoc ended on line i, determine if it belongs to the implicit
file-level module. If it is followed by another qldoc or imports, then it
does and if it is followed by any other non-empty, non-comment lines, then
we assume that is a declaration of some kind and the qldoc is attached to
that declaration.
'''
comment = False
for line in lines[i+1:]:
trimmed = line.strip()
if trimmed.startswith("import ") or trimmed.startswith("private import ") or trimmed.startswith("/**"):
return True
elif is_line_comment(trimmed) or not trimmed:
continue
elif trimmed.startswith("/*"):
comment = True
elif comment and trimmed.endswith("*/"):
comment = False
elif not comment and trimmed:
return False
return True
def find_file_module_qldoc_declaration(lines):
'''
Returns the index of last line of the implicit file module qldoc if one
exists. Returns None otherwise.
'''
qldoc = False
comment = False
for i, line in enumerate(lines):
trimmed = line.strip()
if trimmed.startswith("//"):
continue
elif (qldoc or trimmed.startswith("/**")) and trimmed.endswith("*/"):
# a qldoc just ended; determine if it belongs to the implicit file module
if is_file_module_qldoc(i, lines):
return i
else:
return None
elif trimmed.startswith("/**"):
qldoc = True
elif trimmed.startswith("/*"):
comment = True
elif comment and trimmed.endswith("*/"):
comment = False
elif (not qldoc and not comment) and trimmed:
return None
return None
def only_comments(lines):
'''
Returns true if the lines contain only comments and empty lines.
'''
comment = False
for line in lines:
trimmed = line.strip()
if not trimmed or is_line_comment(trimmed):
continue
elif trimmed.startswith("/*"):
comment = True
elif comment and trimmed.endswith("*/"):
comment = False
elif comment:
continue
elif trimmed:
return False
return True
def insert_toplevel_maybe_local_annotation(filename, lines):
'''
Find a suitable place to insert an overlay[local?] annotation at the top of the file.
Returns a pair consisting of description and the modified lines or None if no overlay
annotation is necessary (e.g., for files that only contain comments).
'''
if only_comments(lines):
return None
i = find_file_level_module_declaration(lines)
if not i == None:
out_lines = lines[:i]
out_lines.append("overlay[local?]\n")
out_lines.extend(lines[i:])
return (f"Annotating \"{filename}\" via existing file-level module statement", out_lines)
i = find_file_module_qldoc_declaration(lines)
if not i == None:
out_lines = lines[:i+1]
out_lines.append("overlay[local?]\n")
out_lines.append("module;\n")
out_lines.extend(lines[i+1:])
return (f"Annotating \"{filename}\" which has a file-level module qldoc", out_lines)
out_lines = ["overlay[local?]\n", "module;\n", "\n"] + lines
return (f"Annotating \"{filename}\" without file-level module qldoc", out_lines)
def insert_overlay_caller_annotations(lines):
'''
Mark pragma[inline] predicates as overlay[caller?] if they are not declared private.
'''
out_lines = []
for i, line in enumerate(lines):
trimmed = line.strip()
if trimmed == "pragma[inline]":
if i + 1 < len(lines) and not "private" in lines[i+1]:
whitespace = line[0: line.find(trimmed)]
out_lines.append(f"{whitespace}overlay[caller?]\n")
out_lines.append(line)
return out_lines
def annotate_as_appropriate(filename, lines):
'''
Insert new overlay[...] annotations according to heuristics in files without existing
overlay annotations.
Returns None if no annotations are needed. Otherwise, returns a pair consisting of a
string describing the action taken and the modified content as a list of lines.
'''
if has_overlay_annotations(lines):
return None
# These simple heuristics filter out those .qll files that we no _not_ want to annotate
# as overlay[local?]. It is not clear that these heuristics are exactly what we want,
# but they seem to work well enough for now (as determined by speed and accuracy numbers).
if (filename.endswith("Test.qll") or
((filename.endswith("Query.qll") or filename.endswith("Config.qll")) and
any("implements DataFlow::ConfigSig" in line for line in lines))):
return None
elif not any(line for line in lines if line.strip()):
return None
lines = insert_overlay_caller_annotations(lines)
return insert_toplevel_maybe_local_annotation(filename, lines)
def process_single_file(write, filename):
'''
Process a single file, annotating it as appropriate.
If write is set, the changes are written back to the file.
Returns True if the file requires changes.
'''
with open(filename) as f:
old = [line for line in f]
annotate_result = annotate_as_appropriate(filename, old)
if annotate_result is None:
return False
if not write:
return True
new = annotate_result[1]
diff = context_diff(old, new, fromfile=filename, tofile=filename)
diff = [line for line in diff]
if diff:
print(annotate_result[0])
for line in diff:
print(line.rstrip())
with open(filename, "w") as out_file:
for line in new:
out_file.write(line)
return True
if len(sys.argv) > 1 and sys.argv[1] == "--check":
check = True
langs = sys.argv[2:]
else:
check = False
langs = sys.argv[1:]
dirs = []
for lang in langs:
if lang in ["cpp", "go", "csharp", "java", "javascript", "python", "ruby", "rust", "swift"]:
dirs.append(f"{lang}/ql/lib")
else:
raise Exception(f"Unknown language \"{lang}\".")
if dirs:
dirs.append("shared")
missingAnnotations = []
for roots in dirs:
for dirpath, dirnames, filenames in os.walk(roots):
for filename in filenames:
if filename.endswith(".qll") and not dirpath.endswith("tutorial"):
path = os.path.join(dirpath, filename)
res = process_single_file(not check, path)
if check and res:
missingAnnotations.append(path)
if len(missingAnnotations) > 0:
print("The following files have no overlay annotations:")
for path in missingAnnotations[:10]:
print("- " + path)
if len(missingAnnotations) > 10:
print("and " + str(len(missingAnnotations) - 10) + " additional files.")
print()
print("Please manually add overlay annotations or use the config/add-overlay-annotations.py script to automatically add sensible default overlay annotations.")
exit(1)

View File

@@ -0,0 +1,175 @@
# This script is used to annotate .qll files with overlay[local?] annotations.
# It will walk the directory tree and annotate most .qll files, skipping only
# some specific cases (e.g., empty files, files that configure dataflow for queries).
# It will also add overlay[caller] annotations to predicates that are pragma[inline]
# and either not private or in a hardcoded list of predicates.
# The script takes a list of languages and processes the corresponding directories.
# Usage: python3 annotate-overlay-local.py <language1> <language2> ...
# The script will modify the files in place and print the changes made.
# The script is designed to be run from the root of the repository.
#!/usr/bin/python3
import sys
import os
from difflib import *
# These are the only two predicates that are pragma[inline], private, and must be
# overlay[caller] in order to successfully compile our internal java queries.
hardcoded_overlay_caller_preds = [
"fwdFlowInCand", "fwdFlowInCandTypeFlowDisabled"]
def filter_out_annotations(filename):
'''
Read the file and strip all existing overlay[...] annotations from the contents.
Return the file modified file content as a list of lines.
'''
overlays = ["local?", "caller"]
annotations = [f"overlay[{t}]" for t in overlays]
with open(filename, 'r') as file_in:
lines = [l for l in file_in if not l.strip() in annotations]
for ann in annotations:
if any(line for line in lines if ann in line):
raise Exception(f"Failed to filter out {ann} from {filename}.")
return lines
def insert_toplevel_maybe_local_anntotation(filename, lines):
'''
Find a suitable place to insert an overlay[local?] annotation at the top of the file.
Return a pair: (string describing action taken, modified content as list of lines).
'''
out_lines = []
status = 0
for line in lines:
if status == 0 and line.rstrip().endswith("module;"):
out_lines.append("overlay[local?]\n")
status = 1
out_lines.append(line)
if status == 1:
return (f"Annotating \"{filename}\" via existing file-level module statement", out_lines)
out_lines = []
empty_line_buffer = []
status = 0
for line in lines:
trimmed = line.strip()
if not trimmed:
empty_line_buffer.append(line)
continue
if status <= 1 and trimmed.endswith("*/"):
status = 2
elif status == 0 and trimmed.startswith("/**"):
status = 1
elif status == 0 and not trimmed.startswith("/*"):
out_lines.append("overlay[local?]\n")
out_lines.append("module;\n")
out_lines.append("\n")
status = 3
elif status == 2 and (trimmed.startswith("import ") or trimmed.startswith("private import ")):
out_lines.append("overlay[local?]\n")
out_lines.append("module;\n")
status = 3
elif status == 2 and (trimmed.startswith("class ") or trimmed.startswith("predicate ")
or trimmed.startswith("module ") or trimmed.startswith("signature ")):
out_lines = ["overlay[local?]\n", "module;\n", "\n"] + out_lines
status = 3
elif status == 2 and trimmed.startswith("/*"):
out_lines.append("overlay[local?]\n")
out_lines.append("module;\n")
status = 3
elif status == 2:
status = 4
if empty_line_buffer:
out_lines += empty_line_buffer
empty_line_buffer = []
out_lines.append(line)
if status == 3:
out_lines += empty_line_buffer
if status == 3:
return (f"Annotating \"{filename}\" after file-level module qldoc", out_lines)
raise Exception(f"Failed to annotate \"{filename}\" as overlay[local?].")
def insert_overlay_caller_annotations(lines):
'''
Mark pragma[inline] predicates as overlay[caller] if they are not declared private
or if they are private but are in the list of hardcoded_overlay_caller_preds.
'''
out_lines = []
for i, line in enumerate(lines):
trimmed = line.strip()
if trimmed == "pragma[inline]":
if (not "private" in lines[i+1] or
any(pred in lines[i+1] for pred in hardcoded_overlay_caller_preds)):
whitespace = line[0: line.find(trimmed)]
out_lines.append(f"{whitespace}overlay[caller]\n")
out_lines.append(line)
return out_lines
def annotate_as_appropriate(filename):
'''
Read file and strip all existing overlay[...] annotations from the contents;
then insert new overlay[...] annotations according to heuristics.
Return a pair: (string describing action taken, modified content as list of lines).
'''
lines = filter_out_annotations(filename)
lines = insert_overlay_caller_annotations(lines)
# These simple heuristics filter out those .qll files that we no _not_ want to annotate
# as overlay[local?]. It is not clear that these heuristics are exactly what we want,
# but they seem to work well enough for now (as determined by speed and accuracy numbers).
if (filename.endswith("Test.qll") or
((filename.endswith("Query.qll") or filename.endswith("Config.qll")) and
any("implements DataFlow::ConfigSig" in line for line in lines))):
return (f"Keeping \"{filename}\" global because it configures dataflow for a query", lines)
elif not any(line for line in lines if line.strip()):
return (f"Keeping \"{filename}\" global because it is empty", lines)
return insert_toplevel_maybe_local_anntotation(filename, lines)
def process_single_file(filename):
'''
Process a single file, annotating it as appropriate and writing the changes back to the file.
'''
annotate_result = annotate_as_appropriate(filename)
old = [line for line in open(filename)]
new = annotate_result[1]
if old != new:
diff = context_diff(old, new, fromfile=filename, tofile=filename)
diff = [line for line in diff]
if diff:
print(annotate_result[0])
for line in diff:
print(line.rstrip())
with open(filename, "w") as out_file:
for line in new:
out_file.write(line)
dirs = []
for lang in sys.argv[1:]:
if lang in ["cpp", "go", "csharp", "java", "javascript", "python", "ruby", "rust", "swift"]:
dirs.append(f"{lang}/ql/lib")
else:
raise Exception(f"Unknown language \"{lang}\".")
if dirs:
dirs.append("shared")
for roots in dirs:
for dirpath, dirnames, filenames in os.walk(roots):
for filename in filenames:
if filename.endswith(".qll") and not dirpath.endswith("tutorial"):
process_single_file(os.path.join(dirpath, filename))

View File

@@ -11,7 +11,6 @@
"/*- Diagnostic messages -*/",
"/*- Diagnostic messages: severity -*/",
"/*- Source location prefix -*/",
"/*- Database metadata -*/",
"/*- Lines of code -*/",
"/*- Configuration files with key value pairs -*/",
"/*- YAML -*/",
@@ -32,4 +31,4 @@
"/*- Python dbscheme -*/",
"/*- Empty location -*/"
]
}
}

View File

@@ -8,9 +8,9 @@ needs_an_re = re.compile(r'^(?!Unary)[AEIOU]') # Name requiring "an" instead of
start_qldoc_re = re.compile(r'^\s*/\*\*') # Start of a QLDoc comment
end_qldoc_re = re.compile(r'\*/\s*$') # End of a QLDoc comment
blank_qldoc_line_re = re.compile(r'^\s*\*\s*$') # A line in a QLDoc comment with only the '*'
instruction_class_re = re.compile(r'^class (?P<name>[A-Za-z0-9]+)Instruction\s') # Declaration of an `Instruction` class
opcode_base_class_re = re.compile(r'^abstract class (?P<name>[A-Za-z0-9]+)Opcode\s') # Declaration of an `Opcode` base class
opcode_class_re = re.compile(r'^ class (?P<name>[A-Za-z0-9]+)\s') # Declaration of an `Opcode` class
instruction_class_re = re.compile(r'^class (?P<name>[A-aa-z0-9]+)Instruction\s') # Declaration of an `Instruction` class
opcode_base_class_re = re.compile(r'^abstract class (?P<name>[A-aa-z0-9]+)Opcode\s') # Declaration of an `Opcode` base class
opcode_class_re = re.compile(r'^ class (?P<name>[A-aa-z0-9]+)\s') # Declaration of an `Opcode` class
script_dir = path.realpath(path.dirname(__file__))
instruction_path = path.realpath(path.join(script_dir, '../cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll'))

View File

@@ -1,31 +0,0 @@
language: cpp
strategy: dca
destination: cpp/ql/lib/ext/generated
targets:
- name: zlib
with-sinks: false
with-sources: false
- name: brotli
with-sinks: false
with-sources: false
- name: libidn2
with-sinks: false
with-sources: false
- name: libssh2
with-sinks: false
with-sources: false
- name: sqlite
with-sinks: false
with-sources: false
- name: openssl
with-sinks: false
with-sources: false
- name: nghttp2
with-sinks: false
with-sources: false
- name: libuv
with-sinks: false
with-sources: false
- name: curl
with-sinks: false
with-sources: false

View File

@@ -1,7 +0,0 @@
class LambdaExpr extends @lambdaexpr {
string toString() { none() }
}
from LambdaExpr lambda, string default_capture, boolean has_explicit_return_type
where lambdas(lambda, default_capture, has_explicit_return_type, _)
select lambda, default_capture, has_explicit_return_type

View File

@@ -1,3 +0,0 @@
description: capture whether a lambda has an explicitly specified parameter list.
compatibility: full
lambdas.rel: run lambdas.qlo

View File

@@ -11,7 +11,7 @@ int getKind(int kind) {
if kind = 14
then result = 6 // Represent MSFT #import as #include
else
if kind = 15 or kind = 16
if kind = 15 or kind = 6
then result = 3 // Represent #elifdef and #elifndef as #elif
else result = kind
}

View File

@@ -1,14 +0,0 @@
class BuiltinType extends @builtintype {
string toString() { none() }
}
from BuiltinType type, string name, int kind, int kind_new, int size, int sign, int alignment
where
builtintypes(type, name, kind, size, sign, alignment) and
if
type instanceof @complex_fp16 or
type instanceof @complex_std_bfloat16 or
type instanceof @complex_std_float16
then kind_new = 2
else kind_new = kind
select type, name, kind_new, size, sign, alignment

View File

@@ -1,3 +0,0 @@
description: Introduce new complex 16-bit floating-point types
compatibility: backwards
builtintypes.rel: run builtintypes.qlo

View File

@@ -1,3 +0,0 @@
description: Add a predicate `getAnAttribute` to `Namespace`
compatibility: full
namespaceattributes.rel: delete

View File

@@ -1,13 +0,0 @@
class Stmt extends @stmt {
string toString() { none() }
}
class Location extends @location_stmt {
string toString() { none() }
}
from Stmt id, int kind, Location loc, int new_kind
where
stmts(id, kind, loc) and
if kind = 40 then new_kind = 4 else new_kind = kind
select id, new_kind, loc

View File

@@ -1,3 +0,0 @@
description: Support `__leave` statement
compatibility: full
stmts.rel: run stmts.qlo

View File

@@ -1,9 +0,0 @@
class BuiltinType extends @builtintype {
string toString() { none() }
}
from BuiltinType id, string name, int kind, int new_kind, int size, int sign, int alignment
where
builtintypes(id, name, kind, size, sign, alignment) and
if kind = 62 then new_kind = 1 else new_kind = kind
select id, name, new_kind, size, sign, alignment

View File

@@ -1,3 +0,0 @@
description: Support __mfp8 type
compatibility: backwards
builtintypes.rel: run builtintypes.qlo

View File

@@ -1,9 +0,0 @@
class BuiltinType extends @builtintype {
string toString() { none() }
}
from BuiltinType id, string name, int kind, int new_kind, int size, int sign, int alignment
where
builtintypes(id, name, kind, size, sign, alignment) and
if kind = 63 then /* @errortype */ new_kind = 1 else new_kind = kind
select id, name, new_kind, size, sign, alignment

View File

@@ -1,9 +0,0 @@
class Type extends @type {
string toString() { none() }
}
from Type type, string name, int kind, int new_kind, Type type_id
where
derivedtypes(type, name, kind, type_id) and
if kind = 11 then /* @gnu_vector */ new_kind = 5 else new_kind = kind
select type, name, new_kind, type_id

View File

@@ -1,5 +0,0 @@
description: Arm scalable vector type support
compatibility: backwards
builtintypes.rel: run builtintypes.qlo
derivedtypes.rel: run derivedtypes.qlo
tupleelements.rel: delete

View File

@@ -2,7 +2,7 @@ import runs_on
import pytest
from query_suites import *
well_known_query_suites = ['cpp-code-quality.qls', 'cpp-code-quality-extended.qls', 'cpp-security-and-quality.qls', 'cpp-security-extended.qls', 'cpp-code-scanning.qls']
well_known_query_suites = ['cpp-code-quality.qls', 'cpp-security-and-quality.qls', 'cpp-security-extended.qls', 'cpp-code-scanning.qls']
@runs_on.posix
@pytest.mark.parametrize("query_suite", well_known_query_suites)

View File

@@ -1,50 +1,3 @@
## 5.2.0
### Deprecated APIs
* The `ThrowingFunction` class (`semmle.code.cpp.models.interfaces.Throwing`) has been deprecated. Please use the `AlwaysSehThrowingFunction` class instead.
### New Features
* Added a predicate `getAnAttribute` to `Namespace` to retrieve a namespace attribute.
* The Microsoft-specific `__leave` statement is now supported.
* A new class `LeaveStmt` extending `JumpStmt` was added to represent `__leave` statements.
* Added a predicate `hasParameterList` to `LambdaExpression` to capture whether a lambda has an explicitly specified parameter list.
### Bug Fixes
* `resolveTypedefs` now properly resolves typedefs for `ArrayType`s.
## 5.1.0
### New Features
* Added a predicate `getReferencedMember` to `UsingDeclarationEntry`, which yields a member depending on a type template parameter.
## 5.0.0
### Breaking Changes
* Deleted the deprecated `userInputArgument` predicate and its convenience accessor from the `Security.qll`.
* Deleted the deprecated `userInputReturned` predicate and its convenience accessor from the `Security.qll`.
* Deleted the deprecated `userInputReturn` predicate from the `Security.qll`.
* Deleted the deprecated `isUserInput` predicate and its convenience accessor from the `Security.qll`.
* Deleted the deprecated `userInputArgument` predicate from the `SecurityOptions.qll`.
* Deleted the deprecated `userInputReturned` predicate from the `SecurityOptions.qll`.
### New Features
* Added local flow source models for `ReadFile`, `ReadFileEx`, `MapViewOfFile`, `MapViewOfFile2`, `MapViewOfFile3`, `MapViewOfFile3FromApp`, `MapViewOfFileEx`, `MapViewOfFileFromApp`, `MapViewOfFileNuma2`, and `NtReadFile`.
* Added the `pCmdLine` arguments of `WinMain` and `wWinMain` as local flow sources.
* Added source models for `GetCommandLineA`, `GetCommandLineW`, `GetEnvironmentStringsA`, `GetEnvironmentStringsW`, `GetEnvironmentVariableA`, and `GetEnvironmentVariableW`.
* Added summary models for `CommandLineToArgvA` and `CommandLineToArgvW`.
* Added support for `wmain` as part of the ArgvSource model.
### Bug Fixes
* Fixed a problem where `asExpr()` on `DataFlow::Node` would never return `ArrayAggregateLiteral`s.
* Fixed a problem where `asExpr()` on `DataFlow::Node` would never return `ClassAggregateLiteral`s.
## 4.3.1
### Bug Fixes

View File

@@ -0,0 +1,4 @@
---
category: fix
---
* Fixed a problem where `asExpr()` on `DataFlow::Node` would never return `ClassAggregateLiteral`s.

View File

@@ -0,0 +1,4 @@
---
category: fix
---
* Fixed a problem where `asExpr()` on `DataFlow::Node` would never return `ArrayAggregateLiteral`s.

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* Added support for `wmain` as part of the ArgvSource model.

View File

@@ -0,0 +1,9 @@
---
category: breaking
---
* Deleted the deprecated `userInputArgument` predicate and its convenience accessor from the `Security.qll`.
* Deleted the deprecated `userInputReturned` predicate and its convenience accessor from the `Security.qll`.
* Deleted the deprecated `userInputReturn` predicate from the `Security.qll`.
* Deleted the deprecated `isUserInput` predicate and its convenience accessor from the `Security.qll`.
* Deleted the deprecated `userInputArgument` predicate from the `SecurityOptions.qll`.
* Deleted the deprecated `userInputReturned` predicate from the `SecurityOptions.qll`.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Added `sql-injection` sink models for the Oracle Call Interface (OCI) database library functions `OCIStmtPrepare` and `OCIStmtPrepare2`.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Added support for `__fp16 _Complex` and `__bf16 _Complex` types

View File

@@ -1,23 +0,0 @@
## 5.0.0
### Breaking Changes
* Deleted the deprecated `userInputArgument` predicate and its convenience accessor from the `Security.qll`.
* Deleted the deprecated `userInputReturned` predicate and its convenience accessor from the `Security.qll`.
* Deleted the deprecated `userInputReturn` predicate from the `Security.qll`.
* Deleted the deprecated `isUserInput` predicate and its convenience accessor from the `Security.qll`.
* Deleted the deprecated `userInputArgument` predicate from the `SecurityOptions.qll`.
* Deleted the deprecated `userInputReturned` predicate from the `SecurityOptions.qll`.
### New Features
* Added local flow source models for `ReadFile`, `ReadFileEx`, `MapViewOfFile`, `MapViewOfFile2`, `MapViewOfFile3`, `MapViewOfFile3FromApp`, `MapViewOfFileEx`, `MapViewOfFileFromApp`, `MapViewOfFileNuma2`, and `NtReadFile`.
* Added the `pCmdLine` arguments of `WinMain` and `wWinMain` as local flow sources.
* Added source models for `GetCommandLineA`, `GetCommandLineW`, `GetEnvironmentStringsA`, `GetEnvironmentStringsW`, `GetEnvironmentVariableA`, and `GetEnvironmentVariableW`.
* Added summary models for `CommandLineToArgvA` and `CommandLineToArgvW`.
* Added support for `wmain` as part of the ArgvSource model.
### Bug Fixes
* Fixed a problem where `asExpr()` on `DataFlow::Node` would never return `ArrayAggregateLiteral`s.
* Fixed a problem where `asExpr()` on `DataFlow::Node` would never return `ClassAggregateLiteral`s.

View File

@@ -1,5 +0,0 @@
## 5.1.0
### New Features
* Added a predicate `getReferencedMember` to `UsingDeclarationEntry`, which yields a member depending on a type template parameter.

View File

@@ -1,16 +0,0 @@
## 5.2.0
### Deprecated APIs
* The `ThrowingFunction` class (`semmle.code.cpp.models.interfaces.Throwing`) has been deprecated. Please use the `AlwaysSehThrowingFunction` class instead.
### New Features
* Added a predicate `getAnAttribute` to `Namespace` to retrieve a namespace attribute.
* The Microsoft-specific `__leave` statement is now supported.
* A new class `LeaveStmt` extending `JumpStmt` was added to represent `__leave` statements.
* Added a predicate `hasParameterList` to `LambdaExpression` to capture whether a lambda has an explicitly specified parameter list.
### Bug Fixes
* `resolveTypedefs` now properly resolves typedefs for `ArrayType`s.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 5.2.0
lastReleaseVersion: 4.3.1

View File

@@ -13,9 +13,7 @@ module CryptoInput implements InputSig<Language::Location> {
LocatableElement dfn_to_element(DataFlow::Node node) {
result = node.asExpr() or
result = node.asParameter() or
result = node.asVariable() or
result = node.asDefiningArgument()
// TODO: do we need asIndirectExpr()?
result = node.asVariable()
}
string locationToFileBaseNameAndLineNumberString(Location location) {
@@ -56,7 +54,7 @@ module ArtifactFlowConfig implements DataFlow::ConfigSig {
module ArtifactFlow = DataFlow::Global<ArtifactFlowConfig>;
/**
* An artifact output to node input configuration
* Artifact output to node input configuration
*/
abstract class AdditionalFlowInputStep extends DataFlow::Node {
abstract DataFlow::Node getOutput();
@@ -91,8 +89,9 @@ module GenericDataSourceFlowConfig implements DataFlow::ConfigSig {
module GenericDataSourceFlow = TaintTracking::Global<GenericDataSourceFlowConfig>;
private class ConstantDataSource extends Crypto::GenericConstantSourceInstance instanceof OpenSslGenericSourceCandidateLiteral
{
private class ConstantDataSource extends Crypto::GenericConstantSourceInstance instanceof Literal {
ConstantDataSource() { this instanceof OpenSSLGenericSourceCandidateLiteral }
override DataFlow::Node getOutputNode() { result.asExpr() = this }
override predicate flowsTo(Crypto::FlowAwareElement other) {

View File

@@ -12,15 +12,13 @@ private import PaddingAlgorithmInstance
* overlap with the known algorithm constants.
* Padding consumers (specific padding consumers) are excluded from the set of sinks.
*/
module KnownOpenSslAlgorithmToAlgorithmValueConsumerConfig implements DataFlow::ConfigSig {
module KnownOpenSSLAlgorithmToAlgorithmValueConsumerConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source.asExpr() instanceof KnownOpenSslAlgorithmExpr and
// No need to flow direct operations to AVCs
not source.asExpr() instanceof OpenSslDirectAlgorithmOperationCall
source.asExpr() instanceof KnownOpenSSLAlgorithmConstant
}
predicate isSink(DataFlow::Node sink) {
exists(OpenSslAlgorithmValueConsumer c |
exists(OpenSSLAlgorithmValueConsumer c |
c.getInputNode() = sink and
// exclude padding algorithm consumers, since
// these consumers take in different constant values
@@ -45,11 +43,11 @@ module KnownOpenSslAlgorithmToAlgorithmValueConsumerConfig implements DataFlow::
}
}
module KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow =
DataFlow::Global<KnownOpenSslAlgorithmToAlgorithmValueConsumerConfig>;
module KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow =
DataFlow::Global<KnownOpenSSLAlgorithmToAlgorithmValueConsumerConfig>;
module RsaPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source.asExpr() instanceof OpenSslPaddingLiteral }
module RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source.asExpr() instanceof OpenSSLPaddingLiteral }
predicate isSink(DataFlow::Node sink) {
exists(PaddingAlgorithmValueConsumer c | c.getInputNode() = sink)
@@ -60,11 +58,11 @@ module RsaPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig implements DataF
}
}
module RsaPaddingAlgorithmToPaddingAlgorithmValueConsumerFlow =
DataFlow::Global<RsaPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig>;
module RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerFlow =
DataFlow::Global<RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig>;
class OpenSslAlgorithmAdditionalFlowStep extends AdditionalFlowInputStep {
OpenSslAlgorithmAdditionalFlowStep() { exists(AlgorithmPassthroughCall c | c.getInNode() = this) }
class OpenSSLAlgorithmAdditionalFlowStep extends AdditionalFlowInputStep {
OpenSSLAlgorithmAdditionalFlowStep() { exists(AlgorithmPassthroughCall c | c.getInNode() = this) }
override DataFlow::Node getOutput() {
exists(AlgorithmPassthroughCall c | c.getInNode() = this and c.getOutNode() = result)
@@ -114,11 +112,11 @@ class CopyAndDupAlgorithmPassthroughCall extends AlgorithmPassthroughCall {
override DataFlow::Node getOutNode() { result = outNode }
}
class NidToPointerPassthroughCall extends AlgorithmPassthroughCall {
class NIDToPointerPassthroughCall extends AlgorithmPassthroughCall {
DataFlow::Node inNode;
DataFlow::Node outNode;
NidToPointerPassthroughCall() {
NIDToPointerPassthroughCall() {
this.getTarget().getName() in ["OBJ_nid2obj", "OBJ_nid2ln", "OBJ_nid2sn"] and
inNode.asExpr() = this.getArgument(0) and
outNode.asExpr() = this
@@ -150,11 +148,11 @@ class PointerToPointerPassthroughCall extends AlgorithmPassthroughCall {
override DataFlow::Node getOutNode() { result = outNode }
}
class PointerToNidPassthroughCall extends AlgorithmPassthroughCall {
class PointerToNIDPassthroughCall extends AlgorithmPassthroughCall {
DataFlow::Node inNode;
DataFlow::Node outNode;
PointerToNidPassthroughCall() {
PointerToNIDPassthroughCall() {
this.getTarget().getName() in ["OBJ_obj2nid", "OBJ_ln2nid", "OBJ_sn2nid", "OBJ_txt2nid"] and
(
inNode.asIndirectExpr() = this.getArgument(0)

View File

@@ -5,77 +5,73 @@ private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmCon
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
private import AlgToAVCFlow
private import codeql.quantum.experimental.Standardization::Types::KeyOpAlg as KeyOpAlg
/**
* Given a `KnownOpenSslBlockModeAlgorithmExpr`, converts this to a block family type.
* Given a `KnownOpenSSLBlockModeAlgorithmConstant`, converts this to a block family type.
* Does not bind if there is no mapping (no mapping to 'unknown' or 'other').
*/
predicate knownOpenSslConstantToBlockModeFamilyType(
KnownOpenSslBlockModeAlgorithmExpr e, KeyOpAlg::ModeOfOperationType type
predicate knownOpenSSLConstantToBlockModeFamilyType(
KnownOpenSSLBlockModeAlgorithmConstant e, Crypto::TBlockCipherModeOfOperationType type
) {
exists(string name |
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
name = e.getNormalizedName() and
(
name = "CBC" and type instanceof KeyOpAlg::CBC
name.matches("CBC") and type instanceof Crypto::CBC
or
name = "CFB%" and type instanceof KeyOpAlg::CFB
name.matches("CFB%") and type instanceof Crypto::CFB
or
name = "CTR" and type instanceof KeyOpAlg::CTR
name.matches("CTR") and type instanceof Crypto::CTR
or
name = "GCM" and type instanceof KeyOpAlg::GCM
name.matches("GCM") and type instanceof Crypto::GCM
or
name = "OFB" and type instanceof KeyOpAlg::OFB
name.matches("OFB") and type instanceof Crypto::OFB
or
name = "XTS" and type instanceof KeyOpAlg::XTS
name.matches("XTS") and type instanceof Crypto::XTS
or
name = "CCM" and type instanceof KeyOpAlg::CCM
name.matches("CCM") and type instanceof Crypto::CCM
or
name = "CCM" and type instanceof KeyOpAlg::CCM
name.matches("GCM") and type instanceof Crypto::GCM
or
name = "ECB" and type instanceof KeyOpAlg::ECB
name.matches("CCM") and type instanceof Crypto::CCM
or
name.matches("ECB") and type instanceof Crypto::ECB
)
)
}
class KnownOpenSslBlockModeConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
Crypto::ModeOfOperationAlgorithmInstance instanceof KnownOpenSslBlockModeAlgorithmExpr
class KnownOpenSSLBlockModeConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
Crypto::ModeOfOperationAlgorithmInstance instanceof KnownOpenSSLBlockModeAlgorithmConstant
{
OpenSslAlgorithmValueConsumer getterCall;
OpenSSLAlgorithmValueConsumer getterCall;
KnownOpenSslBlockModeConstantAlgorithmInstance() {
KnownOpenSSLBlockModeConstantAlgorithmInstance() {
// Two possibilities:
// 1) The source is a literal and flows to a getter, then we know we have an instance
// 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that
// 2) The source is a KnownOpenSSLAlgorithm is call, and we know we have an instance immediately from that
// Possibility 1:
this instanceof OpenSslAlgorithmLiteral and
this instanceof Literal and
exists(DataFlow::Node src, DataFlow::Node sink |
// Sink is an argument to a CipherGetterCall
sink = getterCall.getInputNode() and
sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and
// Source is `this`
src.asExpr() = this and
// This traces to a getter
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
)
or
// Possibility 2:
this instanceof OpenSslAlgorithmCall and
getterCall = this
this instanceof DirectAlgorithmValueConsumer and getterCall = this
}
override KeyOpAlg::ModeOfOperationType getModeType() {
knownOpenSslConstantToBlockModeFamilyType(this, result)
override Crypto::TBlockCipherModeOfOperationType getModeType() {
knownOpenSSLConstantToBlockModeFamilyType(this, result)
or
not knownOpenSslConstantToBlockModeFamilyType(this, _) and result = KeyOpAlg::OtherMode()
not knownOpenSSLConstantToBlockModeFamilyType(this, _) and result = Crypto::OtherMode()
}
// NOTE: I'm not going to attempt to parse out the mode specific part, so returning
// the same as the raw name for now.
override string getRawModeAlgorithmName() {
result = this.(Literal).getValue().toString()
or
result = this.(Call).getTarget().getName()
}
override string getRawModeAlgorithmName() { result = this.(Literal).getValue().toString() }
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
}

View File

@@ -10,14 +10,14 @@ private import AlgToAVCFlow
private import BlockAlgorithmInstance
/**
* Given a `KnownOpenSslCipherAlgorithmExpr`, converts this to a cipher family type.
* Given a `KnownOpenSSLCipherAlgorithmConstant`, converts this to a cipher family type.
* Does not bind if there is no mapping (no mapping to 'unknown' or 'other').
*/
predicate knownOpenSslConstantToCipherFamilyType(
KnownOpenSslCipherAlgorithmExpr e, Crypto::KeyOpAlg::TAlgorithm type
predicate knownOpenSSLConstantToCipherFamilyType(
KnownOpenSSLCipherAlgorithmConstant e, Crypto::KeyOpAlg::TAlgorithm type
) {
exists(string name |
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
name = e.getNormalizedName() and
(
name.matches("AES%") and type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::AES())
or
@@ -33,9 +33,9 @@ predicate knownOpenSslConstantToCipherFamilyType(
or
name.matches("CAST5%") and type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::CAST5())
or
name.matches("2DES%") and type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::DOUBLE_DES())
name.matches("2DES%") and type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::DoubleDES())
or
name.matches("3DES%") and type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::TRIPLE_DES())
name.matches("3DES%") and type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::TripleDES())
or
name.matches("DES%") and type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::DES())
or
@@ -64,29 +64,28 @@ predicate knownOpenSslConstantToCipherFamilyType(
)
}
class KnownOpenSslCipherConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
Crypto::KeyOperationAlgorithmInstance instanceof KnownOpenSslCipherAlgorithmExpr
class KnownOpenSSLCipherConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
Crypto::KeyOperationAlgorithmInstance instanceof KnownOpenSSLCipherAlgorithmConstant
{
OpenSslAlgorithmValueConsumer getterCall;
OpenSSLAlgorithmValueConsumer getterCall;
KnownOpenSslCipherConstantAlgorithmInstance() {
KnownOpenSSLCipherConstantAlgorithmInstance() {
// Two possibilities:
// 1) The source is a literal and flows to a getter, then we know we have an instance
// 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that
// 2) The source is a KnownOpenSSLAlgorithm is call, and we know we have an instance immediately from that
// Possibility 1:
this instanceof OpenSslAlgorithmLiteral and
this instanceof Literal and
exists(DataFlow::Node src, DataFlow::Node sink |
// Sink is an argument to a CipherGetterCall
sink = getterCall.getInputNode() and
sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and
// Source is `this`
src.asExpr() = this and
// This traces to a getter
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
)
or
// Possibility 2:
this instanceof OpenSslAlgorithmCall and
getterCall = this
this instanceof DirectAlgorithmValueConsumer and getterCall = this
}
override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() {
@@ -103,24 +102,20 @@ class KnownOpenSslCipherConstantAlgorithmInstance extends OpenSslAlgorithmInstan
// TODO or trace through getter ctx to set padding
}
override string getRawAlgorithmName() {
result = this.(Literal).getValue().toString()
or
result = this.(Call).getTarget().getName()
}
override string getRawAlgorithmName() { result = this.(Literal).getValue().toString() }
override int getKeySizeFixed() {
this.(KnownOpenSslCipherAlgorithmExpr).getExplicitKeySize() = result
this.(KnownOpenSSLCipherAlgorithmConstant).getExplicitKeySize() = result
}
override KeyOpAlg::AlgorithmType getAlgorithmType() {
knownOpenSslConstantToCipherFamilyType(this, result)
override Crypto::KeyOpAlg::Algorithm getAlgorithmType() {
knownOpenSSLConstantToCipherFamilyType(this, result)
or
not knownOpenSslConstantToCipherFamilyType(this, _) and
not knownOpenSSLConstantToCipherFamilyType(this, _) and
result = Crypto::KeyOpAlg::TUnknownKeyOperationAlgorithmType()
}
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() {
// TODO: trace to any key size initializer, symmetric and asymmetric

View File

@@ -6,55 +6,44 @@ private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgor
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
private import AlgToAVCFlow
class KnownOpenSslEllipticCurveConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
Crypto::EllipticCurveInstance instanceof KnownOpenSslEllipticCurveAlgorithmExpr
class KnownOpenSSLEllipticCurveConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
Crypto::EllipticCurveInstance instanceof KnownOpenSSLEllipticCurveAlgorithmConstant
{
OpenSslAlgorithmValueConsumer getterCall;
OpenSSLAlgorithmValueConsumer getterCall;
KnownOpenSslEllipticCurveConstantAlgorithmInstance() {
KnownOpenSSLEllipticCurveConstantAlgorithmInstance() {
// Two possibilities:
// 1) The source is a literal and flows to a getter, then we know we have an instance
// 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that
// 2) The source is a KnownOpenSSLAlgorithm is call, and we know we have an instance immediately from that
// Possibility 1:
this instanceof OpenSslAlgorithmLiteral and
this instanceof Literal and
exists(DataFlow::Node src, DataFlow::Node sink |
// Sink is an argument to a CipherGetterCall
sink = getterCall.getInputNode() and
// Source is `this`
src.asExpr() = this and
// This traces to a getter
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
)
or
// Possibility 2:
this instanceof OpenSslAlgorithmCall and
getterCall = this
this instanceof DirectAlgorithmValueConsumer and getterCall = this
}
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
override string getRawEllipticCurveName() {
result = this.(Literal).getValue().toString()
or
result = this.(Call).getTarget().getName()
}
override string getRawEllipticCurveName() { result = this.(Literal).getValue().toString() }
override Crypto::EllipticCurveFamilyType getEllipticCurveFamilyType() {
if
Crypto::ellipticCurveNameToKnownKeySizeAndFamilyMapping(this.getParsedEllipticCurveName(), _,
_)
then
Crypto::ellipticCurveNameToKnownKeySizeAndFamilyMapping(this.getParsedEllipticCurveName(), _,
result)
else result = Crypto::OtherEllipticCurveType()
override Crypto::TEllipticCurveType getEllipticCurveType() {
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.getParsedEllipticCurveName(), _, result)
}
override string getParsedEllipticCurveName() {
result = this.(KnownOpenSslAlgorithmExpr).getNormalizedName()
result = this.(KnownOpenSSLEllipticCurveAlgorithmConstant).getNormalizedName()
}
override int getKeySize() {
Crypto::ellipticCurveNameToKnownKeySizeAndFamilyMapping(this.(KnownOpenSslAlgorithmExpr)
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.(KnownOpenSSLEllipticCurveAlgorithmConstant)
.getNormalizedName(), result, _)
}
}

View File

@@ -5,85 +5,80 @@ private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgor
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
private import AlgToAVCFlow
predicate knownOpenSslConstantToHashFamilyType(
KnownOpenSslHashAlgorithmExpr e, Crypto::THashType type
predicate knownOpenSSLConstantToHashFamilyType(
KnownOpenSSLHashAlgorithmConstant e, Crypto::THashType type
) {
exists(string name |
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
name = e.getNormalizedName() and
(
name = "BLAKE2B" and type instanceof Crypto::BLAKE2B
name.matches("BLAKE2B") and type instanceof Crypto::BLAKE2B
or
name = "BLAKE2S" and type instanceof Crypto::BLAKE2S
name.matches("BLAKE2S") and type instanceof Crypto::BLAKE2S
or
name.matches("GOST%") and type instanceof Crypto::GOST_HASH
name.matches("GOST%") and type instanceof Crypto::GOSTHash
or
name = "MD2" and type instanceof Crypto::MD2
name.matches("MD2") and type instanceof Crypto::MD2
or
name = "MD4" and type instanceof Crypto::MD4
name.matches("MD4") and type instanceof Crypto::MD4
or
name = "MD5" and type instanceof Crypto::MD5
name.matches("MD5") and type instanceof Crypto::MD5
or
name = "MDC2" and type instanceof Crypto::MDC2
name.matches("MDC2") and type instanceof Crypto::MDC2
or
name = "POLY1305" and type instanceof Crypto::POLY1305
name.matches("POLY1305") and type instanceof Crypto::POLY1305
or
name.matches(["SHA", "SHA1"]) and type instanceof Crypto::SHA1
or
name.matches("SHA_%") and not name.matches(["SHA1", "SHA3-"]) and type instanceof Crypto::SHA2
name.matches("SHA+%") and not name.matches(["SHA1", "SHA3-"]) and type instanceof Crypto::SHA2
or
name.matches("SHA3-%") and type instanceof Crypto::SHA3
or
name = "SHAKE" and type instanceof Crypto::SHAKE
name.matches(["SHAKE"]) and type instanceof Crypto::SHAKE
or
name = "SM3" and type instanceof Crypto::SM3
name.matches("SM3") and type instanceof Crypto::SM3
or
name = "RIPEMD160" and type instanceof Crypto::RIPEMD160
name.matches("RIPEMD160") and type instanceof Crypto::RIPEMD160
or
name = "WHIRLPOOL" and type instanceof Crypto::WHIRLPOOL
name.matches("WHIRLPOOL") and type instanceof Crypto::WHIRLPOOL
)
)
}
class KnownOpenSslHashConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
Crypto::HashAlgorithmInstance instanceof KnownOpenSslHashAlgorithmExpr
class KnownOpenSSLHashConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
Crypto::HashAlgorithmInstance instanceof KnownOpenSSLHashAlgorithmConstant
{
OpenSslAlgorithmValueConsumer getterCall;
OpenSSLAlgorithmValueConsumer getterCall;
KnownOpenSslHashConstantAlgorithmInstance() {
KnownOpenSSLHashConstantAlgorithmInstance() {
// Two possibilities:
// 1) The source is a literal and flows to a getter, then we know we have an instance
// 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that
// 2) The source is a KnownOpenSSLAlgorithm is call, and we know we have an instance immediately from that
// Possibility 1:
this instanceof OpenSslAlgorithmLiteral and
this instanceof Literal and
exists(DataFlow::Node src, DataFlow::Node sink |
// Sink is an argument to a CipherGetterCall
sink = getterCall.getInputNode() and
sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and
// Source is `this`
src.asExpr() = this and
// This traces to a getter
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
)
or
// Possibility 2:
this instanceof OpenSslAlgorithmCall and
getterCall = this
this instanceof DirectAlgorithmValueConsumer and getterCall = this
}
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
override Crypto::THashType getHashFamily() {
knownOpenSslConstantToHashFamilyType(this, result)
knownOpenSSLConstantToHashFamilyType(this, result)
or
not knownOpenSslConstantToHashFamilyType(this, _) and result = Crypto::OtherHashType()
not knownOpenSSLConstantToHashFamilyType(this, _) and result = Crypto::OtherHashType()
}
override string getRawHashAlgorithmName() {
result = this.(Literal).getValue().toString()
or
result = this.(Call).getTarget().getName()
}
override string getRawHashAlgorithmName() { result = this.(Literal).getValue().toString() }
override int getFixedDigestLength() {
this.(KnownOpenSslHashAlgorithmExpr).getExplicitDigestLength() = result
this.(KnownOpenSSLHashAlgorithmConstant).getExplicitDigestLength() = result
}
}

View File

@@ -1,64 +0,0 @@
import cpp
private import experimental.quantum.Language
private import KnownAlgorithmConstants
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
private import AlgToAVCFlow
predicate knownOpenSslConstantToKeyAgreementFamilyType(
KnownOpenSslKeyAgreementAlgorithmExpr e, Crypto::TKeyAgreementType type
) {
exists(string name |
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
(
name = "ECDH" and type = Crypto::ECDH()
or
name = "DH" and type = Crypto::DH()
or
name = "EDH" and type = Crypto::EDH()
or
name = "ESDH" and type = Crypto::EDH()
)
)
}
class KnownOpenSslKeyAgreementConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
Crypto::KeyAgreementAlgorithmInstance instanceof KnownOpenSslKeyAgreementAlgorithmExpr
{
OpenSslAlgorithmValueConsumer getterCall;
KnownOpenSslKeyAgreementConstantAlgorithmInstance() {
// Two possibilities:
// 1) The source is a literal and flows to a getter, then we know we have an instance
// 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that
// Possibility 1:
this instanceof OpenSslAlgorithmLiteral and
exists(DataFlow::Node src, DataFlow::Node sink |
// Sink is an argument to a CipherGetterCall
sink = getterCall.getInputNode() and
// Source is `this`
src.asExpr() = this and
// This traces to a getter
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
)
or
// Possibility 2:
this instanceof OpenSslAlgorithmCall and
getterCall = this
}
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
override Crypto::TKeyAgreementType getKeyAgreementType() {
knownOpenSslConstantToKeyAgreementFamilyType(this, result)
or
not knownOpenSslConstantToKeyAgreementFamilyType(this, _) and
result = Crypto::OtherKeyAgreementType()
}
override string getRawKeyAgreementAlgorithmName() {
result = this.(Literal).getValue().toString()
or
result = this.(Call).getTarget().getName()
}
}

View File

@@ -1,116 +1,39 @@
import cpp
import experimental.quantum.OpenSSL.GenericSourceCandidateLiteral
predicate resolveAlgorithmFromExpr(
KnownOpenSslAlgorithmExpr e, string normalizedName, string algType
) {
normalizedName = e.getNormalizedName() and
algType = e.getAlgType()
predicate resolveAlgorithmFromExpr(Expr e, string normalizedName, string algType) {
resolveAlgorithmFromCall(e, normalizedName, algType)
or
resolveAlgorithmFromLiteral(e, normalizedName, algType)
}
/**
* An expression that resolves to a known OpenSsl algorithm constant.
* This can be a literal, a call to a known OpenSsl algorithm constant getter,
* or a call to an operation that directly operates on a known algorithm.
*/
abstract class KnownOpenSslAlgorithmExpr extends Expr {
abstract string getNormalizedName();
class KnownOpenSSLAlgorithmConstant extends Expr {
KnownOpenSSLAlgorithmConstant() { resolveAlgorithmFromExpr(this, _, _) }
abstract string getAlgType();
string getNormalizedName() { resolveAlgorithmFromExpr(this, result, _) }
string getAlgType() { resolveAlgorithmFromExpr(this, _, result) }
}
class OpenSslAlgorithmLiteral extends KnownOpenSslAlgorithmExpr instanceof Literal {
string normalizedName;
class KnownOpenSSLCipherAlgorithmConstant extends KnownOpenSSLAlgorithmConstant {
string algType;
OpenSslAlgorithmLiteral() { resolveAlgorithmFromLiteral(this, normalizedName, algType) }
override string getNormalizedName() { result = normalizedName }
override string getAlgType() { result = algType }
}
/**
* A call to either an OpenSsl algorithm constant 'getter', e.g., EVP_MD5()
* or call to an operation that directly operates on a known algorithm, e.g., AES_encrypt
*/
abstract class OpenSslAlgorithmCall extends KnownOpenSslAlgorithmExpr instanceof Call { }
/**
* A call to a 'direct algorithm getter', e.g., EVP_MD5()
* This approach to fetching algorithms was used in OpenSsl 1.0.2.
* The strategy for resolving these calls is to parse the target name
* and resolve the name as though it were a known literal.
* There are a few exceptions where the name doesn't directly match the
* known literal set. If that occurs, users must add the name to the
* set of aliases. E.g., EVP_dss() and EVP_dss1() needed such mappings
* alias = "dss" and target = "dsa"
* or
* alias = "dss1" and target = "dsaWithSHA1"
*/
class OpenSslDirectAlgorithmFetchCall extends OpenSslAlgorithmCall {
string normalizedName;
string algType;
OpenSslDirectAlgorithmFetchCall() {
//ASSUMPTION: these cases will have operands for the call
not exists(this.(Call).getAnArgument()) and
exists(string name, string parsedTargetName |
parsedTargetName =
this.(Call).getTarget().getName().replaceAll("EVP_", "").toLowerCase().replaceAll("_", "-") and
name = resolveAlgorithmAlias(parsedTargetName) and
knownOpenSslAlgorithmLiteral(name, _, normalizedName, algType)
)
}
override string getNormalizedName() { result = normalizedName }
override string getAlgType() { result = algType }
}
/**
* A call to an OpenSsl operation that directly operates on a known algorithm.
* An algorithm construct is not generated for these calls, rather, the operation
* is directly performed, and the algorithm is inferred by the operation itself.
*/
class OpenSslDirectAlgorithmOperationCall extends OpenSslAlgorithmCall {
string normalizedName;
string algType;
OpenSslDirectAlgorithmOperationCall() {
//TODO: this set will have to be exhaustive, and for each operation
//further modeling will be necessary for each case to map the APIs operands
//ASSUMPTION: these cases must have operands for the call
exists(this.(Call).getAnArgument()) and
//TODO: Each case would be enumerated here. Will likely need an exhaustive mapping much like
// for known constants.
knownOpenSslAlgorithmOperationCall(this, normalizedName, algType)
}
override string getNormalizedName() { result = normalizedName }
override string getAlgType() { result = algType }
}
class KnownOpenSslCipherAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr {
string algType;
KnownOpenSslCipherAlgorithmExpr() {
algType = this.(KnownOpenSslAlgorithmExpr).getAlgType() and
KnownOpenSSLCipherAlgorithmConstant() {
resolveAlgorithmFromExpr(this, _, algType) and
algType.matches("%ENCRYPTION")
}
int getExplicitKeySize() {
exists(string name |
name = this.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
name = this.getNormalizedName() and
resolveAlgorithmFromExpr(this, name, algType) and
result = name.regexpCapture(".*-(\\d*)", 1).toInt()
)
}
}
class KnownOpenSslPaddingAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr {
KnownOpenSslPaddingAlgorithmExpr() {
class KnownOpenSSLPaddingAlgorithmConstant extends KnownOpenSSLAlgorithmConstant {
KnownOpenSSLPaddingAlgorithmConstant() {
exists(string algType |
resolveAlgorithmFromExpr(this, _, algType) and
algType.matches("%PADDING")
@@ -118,62 +41,51 @@ class KnownOpenSslPaddingAlgorithmExpr extends Expr instanceof KnownOpenSslAlgor
}
}
class KnownOpenSslBlockModeAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr {
KnownOpenSslBlockModeAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "BLOCK_MODE") }
class KnownOpenSSLBlockModeAlgorithmConstant extends KnownOpenSSLAlgorithmConstant {
KnownOpenSSLBlockModeAlgorithmConstant() { resolveAlgorithmFromExpr(this, _, "BLOCK_MODE") }
}
class KnownOpenSslHashAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr {
KnownOpenSslHashAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "HASH") }
class KnownOpenSSLHashAlgorithmConstant extends KnownOpenSSLAlgorithmConstant {
KnownOpenSSLHashAlgorithmConstant() { resolveAlgorithmFromExpr(this, _, "HASH") }
int getExplicitDigestLength() {
exists(string name |
name = this.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
name = this.getNormalizedName() and
resolveAlgorithmFromExpr(this, name, "HASH") and
result = name.regexpCapture(".*-(\\d*)$", 1).toInt()
)
}
}
class KnownOpenSslMacAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr {
KnownOpenSslMacAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "MAC") }
class KnownOpenSSLEllipticCurveAlgorithmConstant extends KnownOpenSSLAlgorithmConstant {
KnownOpenSSLEllipticCurveAlgorithmConstant() {
resolveAlgorithmFromExpr(this, _, "ELLIPTIC_CURVE")
}
}
class KnownOpenSslHMacAlgorithmExpr extends Expr instanceof KnownOpenSslMacAlgorithmExpr {
KnownOpenSslHMacAlgorithmExpr() { resolveAlgorithmFromExpr(this, "HMAC", "MAC") }
/**
* Gets an explicit cipher algorithm for this MAC algorithm.
* This occurs when the MAC specifies the algorithm at the same time "HMAC-SHA-256"
*/
KnownOpenSslHashAlgorithmExpr getExplicitHashAlgorithm() { result = this }
class KnownOpenSSLSignatureAlgorithmConstant extends KnownOpenSSLAlgorithmConstant {
KnownOpenSSLSignatureAlgorithmConstant() { resolveAlgorithmFromExpr(this, _, "SIGNATURE") }
}
class KnownOpenSslCMacAlgorithmExpr extends Expr instanceof KnownOpenSslMacAlgorithmExpr {
KnownOpenSslCMacAlgorithmExpr() { resolveAlgorithmFromExpr(this, "CMAC", "MAC") }
/**
* Gets an explicit cipher algorithm for this MAC algorithm.
* This occurs when the MAC specifies the algorithm at the same time "HMAC-SHA-256"
*/
KnownOpenSslCipherAlgorithmExpr getExplicitCipherAlgorithm() { result = this }
}
class KnownOpenSslEllipticCurveAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr {
KnownOpenSslEllipticCurveAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "ELLIPTIC_CURVE") }
}
class KnownOpenSslSignatureAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr {
KnownOpenSslSignatureAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "SIGNATURE") }
}
class KnownOpenSslKeyAgreementAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr {
KnownOpenSslKeyAgreementAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "KEY_AGREEMENT") }
}
predicate knownOpenSslAlgorithmOperationCall(Call c, string normalized, string algType) {
c.getTarget().getName() in ["EVP_RSA_gen", "RSA_generate_key_ex", "RSA_generate_key", "RSA_new"] and
normalized = "RSA" and
algType = "ASYMMETRIC_ENCRYPTION"
/**
* Resolves a call to a 'direct algorithm getter', e.g., EVP_MD5()
* This approach to fetching algorithms was used in OpenSSL 1.0.2.
* The strategy for resolving these calls is to parse the target name
* and resolve the name as though it were a known literal.
* There are a few exceptions where the name doesn't directly match the
* known literal set. If that occurs, users must add the name to the
* set of aliases. E.g., EVP_dss() and EVP_dss1() needed such mappings
* alias = "dss" and target = "dsa"
* or
* alias = "dss1" and target = "dsaWithSHA1"
*/
predicate resolveAlgorithmFromCall(Call c, string normalized, string algType) {
exists(string name, string parsedTargetName |
parsedTargetName =
c.getTarget().getName().replaceAll("EVP_", "").toLowerCase().replaceAll("_", "-") and
name = resolveAlgorithmAlias(parsedTargetName) and
knownOpenSSLAlgorithmLiteral(name, _, normalized, algType)
)
}
/**
@@ -182,13 +94,13 @@ predicate knownOpenSslAlgorithmOperationCall(Call c, string normalized, string a
* If this predicate does not hold, then `e` can be interpreted as being of `UNKNOWN` type.
*/
predicate resolveAlgorithmFromLiteral(
OpenSslGenericSourceCandidateLiteral e, string normalized, string algType
OpenSSLGenericSourceCandidateLiteral e, string normalized, string algType
) {
knownOpenSslAlgorithmLiteral(_, e.getValue().toInt(), normalized, algType)
knownOpenSSLAlgorithmLiteral(_, e.getValue().toInt(), normalized, algType)
or
exists(string name |
name = resolveAlgorithmAlias(e.getValue()) and
knownOpenSslAlgorithmLiteral(name, _, normalized, algType)
knownOpenSSLAlgorithmLiteral(name, _, normalized, algType)
)
}
@@ -199,7 +111,7 @@ string resolveAlgorithmAlias(string name) {
result = getAlgorithmAlias(lower)
or
// or the name is itself a known algorithm
knownOpenSslAlgorithmLiteral(lower, _, _, _) and result = lower
knownOpenSSLAlgorithmLiteral(lower, _, _, _) and result = lower
)
}
@@ -210,8 +122,7 @@ string getAlgorithmAlias(string alias) {
}
/**
* Holds for aliases of known algorithms defined by users
* (through obj_name_add and various macros pointing to this function).
* Finds aliases of known alagorithms defined by users (through obj_name_add and various macros pointing to this function)
*
* The `target` and `alias` are converted to lowercase to be of a standard form.
*/
@@ -223,21 +134,13 @@ predicate customAliases(string target, string alias) {
}
/**
* Holds for a hard-coded mapping of known algorithm aliases in OpenSsl.
* A hard-coded mapping of known algorithm aliases in OpenSSL.
* This was derived by applying the same kind of logic foun din `customAliases` to the
* OpenSsl code base directly.
* OpenSSL code base directly.
*
* The `target` and `alias` are converted to lowercase to be of a standard form.
*/
predicate defaultAliases(string target, string alias) {
// "DH" and "DHX" are not aliases in the traditional sense,
// i.e., they are not registered as aliases explicitly,
// rather they appear in common usage, and experiments reveal their
// NID matches those of the `dhKeyAgreement` and `x9.42 dh` algorithms respectively.
alias = "dh" and target = "dhKeyAgreement"
or
alias = "dhx" and target = "x9.42 dh"
or
alias = "aes128" and target = "aes-128-cbc"
or
alias = "aes192" and target = "aes-192-cbc"
@@ -332,11 +235,7 @@ predicate defaultAliases(string target, string alias) {
* `normalized` is the normalized name of the algorithm (e.g., "AES128" for "aes-128-cbc")
* `algType` is the type of algorithm (e.g., "SYMMETRIC_ENCRYPTION")
*/
predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized, string algType) {
name = "dhKeyAgreement" and nid = 28 and normalized = "DH" and algType = "KEY_AGREEMENT"
or
name = "x9.42 dh" and nid = 29 and normalized = "DH" and algType = "KEY_AGREEMENT"
or
predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized, string algType) {
name = "rsa" and nid = 19 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "prime192v1" and nid = 409 and normalized = "PRIME192V1" and algType = "ELLIPTIC_CURVE"
@@ -969,10 +868,6 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
or
name = "id-alg-dh-sig-hmac-sha1" and nid = 325 and normalized = "SHA1" and algType = "HASH"
or
name = "id-alg-dh-sig-hmac-sha1" and nid = 325 and normalized = "DH" and algType = "KEY_AGREEMENT"
or
name = "id-alg-dh-sig-hmac-sha1" and nid = 325 and normalized = "HMAC" and algType = "MAC"
or
name = "aes-128-ofb" and nid = 420 and normalized = "AES-128" and algType = "SYMMETRIC_ENCRYPTION"
or
name = "aes-128-ofb" and nid = 420 and normalized = "OFB" and algType = "BLOCK_MODE"
@@ -1151,12 +1046,8 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
or
name = "hmac-md5" and nid = 780 and normalized = "MD5" and algType = "HASH"
or
name = "hmac-md5" and nid = 780 and normalized = "HMAC" and algType = "HASH"
or
name = "hmac-sha1" and nid = 781 and normalized = "SHA1" and algType = "HASH"
or
name = "hmac-sha1" and nid = 781 and normalized = "HMAC" and algType = "MAC"
or
name = "md_gost94" and nid = 809 and normalized = "GOST94" and algType = "HASH"
or
name = "gost94" and nid = 812 and normalized = "GOST94" and algType = "HASH"
@@ -1231,14 +1122,10 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
or
name = "rc4-hmac-md5" and nid = 915 and normalized = "MD5" and algType = "HASH"
or
name = "rc4-hmac-md5" and nid = 915 and normalized = "HMAC" and algType = "MAC"
or
name = "rc4-hmac-md5" and nid = 915 and normalized = "RC4" and algType = "SYMMETRIC_ENCRYPTION"
or
name = "aes-128-cbc-hmac-sha1" and nid = 916 and normalized = "SHA1" and algType = "HASH"
or
name = "aes-128-cbc-hmac-sha1" and nid = 916 and normalized = "HMAC" and algType = "MAC"
or
name = "aes-128-cbc-hmac-sha1" and
nid = 916 and
normalized = "AES-128" and
@@ -1248,8 +1135,6 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
or
name = "aes-192-cbc-hmac-sha1" and nid = 917 and normalized = "SHA1" and algType = "HASH"
or
name = "aes-192-cbc-hmac-sha1" and nid = 917 and normalized = "HMAC" and algType = "MAC"
or
name = "aes-192-cbc-hmac-sha1" and
nid = 917 and
normalized = "AES-192" and
@@ -1264,8 +1149,6 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
or
name = "aes-256-cbc-hmac-sha1" and nid = 918 and normalized = "CBC" and algType = "BLOCK_MODE"
or
name = "aes-256-cbc-hmac-sha1" and nid = 918 and normalized = "HMAC" and algType = "MAC"
or
name = "aes-128-cbc-hmac-sha256" and nid = 948 and normalized = "SHA-256" and algType = "HASH"
or
name = "aes-128-cbc-hmac-sha256" and
@@ -1277,8 +1160,6 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
or
name = "aes-192-cbc-hmac-sha256" and nid = 949 and normalized = "SHA-256" and algType = "HASH"
or
name = "aes-192-cbc-hmac-sha256" and nid = 949 and normalized = "HMAC" and algType = "MAC"
or
name = "aes-192-cbc-hmac-sha256" and
nid = 949 and
normalized = "AES-192" and
@@ -1288,8 +1169,6 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
or
name = "aes-256-cbc-hmac-sha256" and nid = 950 and normalized = "SHA-256" and algType = "HASH"
or
name = "aes-256-cbc-hmac-sha256" and nid = 950 and normalized = "HMAC" and algType = "MAC"
or
name = "aes-256-cbc-hmac-sha256" and
nid = 950 and
normalized = "AES-256" and
@@ -1329,11 +1208,6 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
normalized = "CAMELLIA-128" and
algType = "SYMMETRIC_ENCRYPTION"
or
name = "camellia-128-cmac" and
nid = 964 and
normalized = "CMAC" and
algType = "MAC"
or
name = "camellia-192-gcm" and
nid = 965 and
normalized = "CAMELLIA-192" and
@@ -1386,11 +1260,6 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
normalized = "CAMELLIA-256" and
algType = "SYMMETRIC_ENCRYPTION"
or
name = "camellia-256-cmac" and
nid = 972 and
normalized = "CMAC" and
algType = "MAC"
or
name = "id-scrypt" and nid = 973 and normalized = "SCRYPT" and algType = "KEY_DERIVATION"
or
name = "gost89-cnt-12" and
@@ -1404,13 +1273,11 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
or
name = "md_gost12_512" and nid = 983 and normalized = "GOST" and algType = "HASH"
or
// TODO: re-evaluate: this is a signing algorithm using hashing and curves
name = "id-tc26-signwithdigest-gost3410-2012-256" and
nid = 985 and
normalized = "GOST34102012" and
algType = "SYMMETRIC_ENCRYPTION"
or
// TODO: re-evaluate: this is a signing algorithm using hashing and curves
name = "id-tc26-signwithdigest-gost3410-2012-512" and
nid = 986 and
normalized = "GOST34102012" and
@@ -1419,42 +1286,22 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
name = "id-tc26-hmac-gost-3411-2012-256" and
nid = 988 and
normalized = "GOST34112012" and
algType = "HASH"
or
name = "id-tc26-hmac-gost-3411-2012-256" and
nid = 988 and
normalized = "HMAC" and
algType = "MAC"
algType = "SYMMETRIC_ENCRYPTION"
or
name = "id-tc26-hmac-gost-3411-2012-512" and
nid = 989 and
normalized = "GOST34112012" and
algType = "HASH"
or
name = "id-tc26-hmac-gost-3411-2012-512" and
nid = 989 and
normalized = "HMAC" and
algType = "MAC"
algType = "SYMMETRIC_ENCRYPTION"
or
name = "id-tc26-agreement-gost-3410-2012-256" and
nid = 992 and
normalized = "GOST34102012" and
algType = "ELLIPTIC_CURVE"
or
name = "id-tc26-agreement-gost-3410-2012-256" and
nid = 992 and
normalized = "GOST34102012" and
algType = "KEY_AGREEMENT"
algType = "SYMMETRIC_ENCRYPTION"
or
name = "id-tc26-agreement-gost-3410-2012-512" and
nid = 993 and
normalized = "GOST34102012" and
algType = "ELLIPTIC_CURVE"
or
name = "id-tc26-agreement-gost-3410-2012-512" and
nid = 993 and
normalized = "GOST34102012" and
algType = "KEY_AGREEMENT"
algType = "SYMMETRIC_ENCRYPTION"
or
name = "id-tc26-gost-3410-2012-512-constants" and
nid = 996 and
@@ -1522,9 +1369,9 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
or
name = "kx-rsa" and nid = 1037 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "kx-ecdhe" and nid = 1038 and normalized = "ECDH" and algType = "KEY_AGREEMENT"
name = "kx-ecdhe" and nid = 1038 and normalized = "ECDH" and algType = "KEY_EXCHANGE"
or
name = "kx-ecdhe-psk" and nid = 1040 and normalized = "ECDH" and algType = "KEY_AGREEMENT"
name = "kx-ecdhe-psk" and nid = 1040 and normalized = "ECDH" and algType = "KEY_EXCHANGE"
or
name = "kx-rsa-psk" and nid = 1042 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
@@ -1542,20 +1389,12 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
or
name = "hmac-sha3-224" and nid = 1102 and normalized = "SHA3-224" and algType = "HASH"
or
name = "hmac-sha3-224" and nid = 1102 and normalized = "HMAC" and algType = "MAC"
or
name = "hmac-sha3-256" and nid = 1103 and normalized = "SHA3-256" and algType = "HASH"
or
name = "hmac-sha3-256" and nid = 1103 and normalized = "HMAC" and algType = "MAC"
or
name = "hmac-sha3-384" and nid = 1104 and normalized = "SHA3-384" and algType = "HASH"
or
name = "hmac-sha3-384" and nid = 1104 and normalized = "HMAC" and algType = "MAC"
or
name = "hmac-sha3-512" and nid = 1105 and normalized = "SHA3-512" and algType = "HASH"
or
name = "hmac-sha3-512" and nid = 1105 and normalized = "HMAC" and algType = "MAC"
or
name = "id-dsa-with-sha384" and nid = 1106 and normalized = "DSA" and algType = "SIGNATURE"
or
name = "id-dsa-with-sha384" and nid = 1106 and normalized = "SHA-384" and algType = "HASH"
@@ -1840,11 +1679,11 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
or
name = "x448" and nid = 1035 and normalized = "X448" and algType = "ELLIPTIC_CURVE"
or
name = "x448" and nid = 1035 and normalized = "X448" and algType = "KEY_AGREEMENT"
name = "x448" and nid = 1035 and normalized = "X448" and algType = "KEY_EXCHANGE"
or
name = "x25519" and nid = 1034 and normalized = "X25519" and algType = "ELLIPTIC_CURVE"
or
name = "x25519" and nid = 1034 and normalized = "X25519" and algType = "KEY_AGREEMENT"
name = "x25519" and nid = 1034 and normalized = "X25519" and algType = "KEY_EXCHANGE"
or
name = "authecdsa" and nid = 1047 and normalized = "ECDSA" and algType = "SIGNATURE"
or
@@ -1944,101 +1783,51 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
normalized = "SHA1" and
algType = "HASH"
or
name = "dhsinglepass-cofactordh-sha1kdf-scheme" and
nid = 941 and
normalized = "DH" and
algType = "KEY_AGREEMENT"
or
name = "dhsinglepass-cofactordh-sha224kdf-scheme" and
nid = 942 and
normalized = "SHA-224" and
algType = "HASH"
or
name = "dhsinglepass-cofactordh-sha224kdf-scheme" and
nid = 942 and
normalized = "DH" and
algType = "KEY_AGREEMENT"
or
name = "dhsinglepass-cofactordh-sha256kdf-scheme" and
nid = 943 and
normalized = "SHA-256" and
algType = "HASH"
or
name = "dhsinglepass-cofactordh-sha256kdf-scheme" and
nid = 943 and
normalized = "DH" and
algType = "KEY_AGREEMENT"
or
name = "dhsinglepass-cofactordh-sha384kdf-scheme" and
nid = 944 and
normalized = "SHA-384" and
algType = "HASH"
or
name = "dhsinglepass-cofactordh-sha384kdf-scheme" and
nid = 944 and
normalized = "DH" and
algType = "KEY_AGREEMENT"
or
name = "dhsinglepass-cofactordh-sha512kdf-scheme" and
nid = 945 and
normalized = "SHA-512" and
algType = "HASH"
or
name = "dhsinglepass-cofactordh-sha512kdf-scheme" and
nid = 945 and
normalized = "DH" and
algType = "KEY_AGREEMENT"
or
name = "dhsinglepass-stddh-sha1kdf-scheme" and
nid = 936 and
normalized = "SHA1" and
algType = "HASH"
or
name = "dhsinglepass-stddh-sha1kdf-scheme" and
nid = 936 and
normalized = "DH" and
algType = "KEY_AGREEMENT"
or
name = "dhsinglepass-stddh-sha224kdf-scheme" and
nid = 937 and
normalized = "SHA-224" and
algType = "HASH"
or
name = "dhsinglepass-stddh-sha224kdf-scheme" and
nid = 937 and
normalized = "DH" and
algType = "KEY_AGREEMENT"
or
name = "dhsinglepass-stddh-sha256kdf-scheme" and
nid = 938 and
normalized = "SHA-256" and
algType = "HASH"
or
name = "dhsinglepass-stddh-sha256kdf-scheme" and
nid = 938 and
normalized = "DH" and
algType = "KEY_AGREEMENT"
or
name = "dhsinglepass-stddh-sha384kdf-scheme" and
nid = 939 and
normalized = "SHA-384" and
algType = "HASH"
or
name = "dhsinglepass-stddh-sha384kdf-scheme" and
nid = 939 and
normalized = "DH" and
algType = "KEY_AGREEMENT"
or
name = "dhsinglepass-stddh-sha512kdf-scheme" and
nid = 940 and
normalized = "SHA-512" and
algType = "HASH"
or
name = "dhsinglepass-stddh-sha512kdf-scheme" and
nid = 940 and
normalized = "DH" and
algType = "KEY_AGREEMENT"
or
name = "dsa-old" and nid = 67 and normalized = "DSA" and algType = "SIGNATURE"
or
name = "dsa-sha" and nid = 66 and normalized = "DSA" and algType = "SIGNATURE"
@@ -2198,7 +1987,7 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
normalized = "GOST" and
algType = "SYMMETRIC_ENCRYPTION"
or
name = "gost r 34.10-2001 dh" and // TODO: review this algorithm
name = "gost r 34.10-2001 dh" and
nid = 817 and
normalized = "GOST" and
algType = "SYMMETRIC_ENCRYPTION"
@@ -2268,7 +2057,7 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
normalized = "GOST" and
algType = "SYMMETRIC_ENCRYPTION"
or
name = "gost r 34.10-94 dh" and // TODO: review this algorithm
name = "gost r 34.10-94 dh" and
nid = 818 and
normalized = "GOST" and
algType = "SYMMETRIC_ENCRYPTION"
@@ -2323,67 +2112,34 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
normalized = "GOST" and
algType = "SYMMETRIC_ENCRYPTION"
or
name = "hmac gost 34.11-2012 256 bit" and
nid = 988 and
normalized = "HMAC" and
algType = "MAC"
or
name = "hmac gost 34.11-2012 512 bit" and
nid = 989 and
normalized = "GOST" and
algType = "SYMMETRIC_ENCRYPTION"
or
name = "hmac gost 34.11-2012 512 bit" and
nid = 989 and
normalized = "HMAC" and
algType = "MAC"
or
name = "hmac gost 34.11-94" and
nid = 810 and
normalized = "GOST" and
algType = "SYMMETRIC_ENCRYPTION"
or
name = "hmac gost 34.11-94" and
nid = 810 and
normalized = "HMAC" and
algType = "MAC"
or
name = "hmacwithmd5" and nid = 797 and normalized = "MD5" and algType = "HASH"
or
name = "hmacwithmd5" and nid = 797 and normalized = "HMAC" and algType = "MAC"
or
name = "hmacwithsha1" and nid = 163 and normalized = "SHA1" and algType = "HASH"
or
name = "hmacwithsha1" and nid = 163 and normalized = "HMAC" and algType = "MAC"
or
name = "hmacwithsha224" and nid = 798 and normalized = "SHA-224" and algType = "HASH"
or
name = "hmacwithsha224" and nid = 798 and normalized = "HMAC" and algType = "MAC"
or
name = "hmacwithsha256" and nid = 799 and normalized = "SHA-256" and algType = "HASH"
or
name = "hmacwithsha256" and nid = 799 and normalized = "HMAC" and algType = "MAC"
or
name = "hmacwithsha384" and nid = 800 and normalized = "SHA-384" and algType = "HASH"
or
name = "hmacwithsha384" and nid = 800 and normalized = "HMAC" and algType = "MAC"
or
name = "hmacwithsha512" and nid = 801 and normalized = "SHA-512" and algType = "HASH"
or
name = "hmacwithsha512" and nid = 801 and normalized = "HMAC" and algType = "MAC"
or
name = "hmacwithsha512-224" and nid = 1193 and normalized = "SHA-512-224" and algType = "HASH"
or
name = "hmacwithsha512-224" and nid = 1193 and normalized = "HMAC" and algType = "MAC"
or
name = "hmacwithsha512-256" and nid = 1194 and normalized = "SHA-512-256" and algType = "HASH"
or
name = "hmacwithsha512-256" and nid = 1194 and normalized = "HMAC" and algType = "MAC"
or
name = "hmacwithsm3" and nid = 1281 and normalized = "SM3" and algType = "HASH"
or
name = "hmacwithsm3" and nid = 1281 and normalized = "HMAC" and algType = "MAC"
or
name = "id-aes128-ccm" and
nid = 896 and
normalized = "AES-128" and
@@ -2516,7 +2272,7 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
normalized = "GOSTR34102001" and
algType = "SYMMETRIC_ENCRYPTION"
or
name = "id-gostr3410-2001dh" and // TODO: review this algorithm
name = "id-gostr3410-2001dh" and
nid = 817 and
normalized = "GOSTR34102001" and
algType = "SYMMETRIC_ENCRYPTION"
@@ -2581,7 +2337,7 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
normalized = "GOSTR341094" and
algType = "SYMMETRIC_ENCRYPTION"
or
name = "id-gostr3410-94dh" and // TODO: review this algorithm
name = "id-gostr3410-94dh" and
nid = 818 and
normalized = "GOSTR341094" and
algType = "SYMMETRIC_ENCRYPTION"
@@ -2633,20 +2389,12 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
or
name = "id-hmacwithsha3-224" and nid = 1102 and normalized = "SHA3-224" and algType = "HASH"
or
name = "id-hmacwithsha3-224" and nid = 1102 and normalized = "HMAC" and algType = "MAC"
or
name = "id-hmacwithsha3-256" and nid = 1103 and normalized = "SHA3-256" and algType = "HASH"
or
name = "id-hmacwithsha3-256" and nid = 1103 and normalized = "HMAC" and algType = "MAC"
or
name = "id-hmacwithsha3-384" and nid = 1104 and normalized = "SHA3-384" and algType = "HASH"
or
name = "id-hmacwithsha3-384" and nid = 1104 and normalized = "HMAC" and algType = "MAC"
or
name = "id-hmacwithsha3-512" and nid = 1105 and normalized = "SHA3-512" and algType = "HASH"
or
name = "id-hmacwithsha3-512" and nid = 1105 and normalized = "HMAC" and algType = "MAC"
or
name = "id-regctrl" and nid = 313 and normalized = "CTR" and algType = "BLOCK_MODE"
or
name = "id-smime-alg-3deswrap" and
@@ -2673,31 +2421,16 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
normalized = "3DES" and
algType = "SYMMETRIC_ENCRYPTION"
or
name = "id-smime-alg-esdhwith3des" and
nid = 241 and
normalized = "ESDH" and
algType = "KEY_AGREEMENT"
or
name = "id-smime-alg-esdhwithrc2" and
nid = 242 and
normalized = "RC2" and
algType = "SYMMETRIC_ENCRYPTION"
or
name = "id-smime-alg-esdhwithrc2" and
nid = 242 and
normalized = "ESDH" and
algType = "KEY_AGREEMENT"
or
name = "id-smime-alg-rc2wrap" and
nid = 244 and
normalized = "RC2" and
algType = "SYMMETRIC_ENCRYPTION"
or
name = "id_smime_alg_esdh" and
nid = 245 and
normalized = "ESDH" and
algType = "KEY_AGREEMENT"
or
name = "id-tc26-gost-28147-param-z" and
nid = 1003 and
normalized = "GOST28147" and
@@ -2743,9 +2476,9 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
normalized = "GOST34102012" and
algType = "SYMMETRIC_ENCRYPTION"
or
name = "kxecdhe" and nid = 1038 and normalized = "ECDH" and algType = "KEY_AGREEMENT"
name = "kxecdhe" and nid = 1038 and normalized = "ECDH" and algType = "KEY_EXCHANGE"
or
name = "kxecdhe-psk" and nid = 1040 and normalized = "ECDH" and algType = "KEY_AGREEMENT"
name = "kxecdhe-psk" and nid = 1040 and normalized = "ECDH" and algType = "KEY_EXCHANGE"
or
name = "kxgost" and nid = 1045 and normalized = "GOST" and algType = "SYMMETRIC_ENCRYPTION"
or
@@ -3002,93 +2735,93 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
name = "ripemd160withrsa" and
nid = 119 and
normalized = "RSA" and
algType = "SIGNATURE"
algType = "ASYMMETRIC_ENCRYPTION"
or
name = "ripemd160withrsa" and nid = 119 and normalized = "RIPEMD160" and algType = "HASH"
or
name = "rsa-md2" and nid = 7 and normalized = "RSA" and algType = "SIGNATURE"
name = "rsa-md2" and nid = 7 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "rsa-md2" and nid = 7 and normalized = "MD2" and algType = "HASH"
or
name = "rsa-md4" and nid = 396 and normalized = "RSA" and algType = "SIGNATURE"
name = "rsa-md4" and nid = 396 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "rsa-md4" and nid = 396 and normalized = "MD4" and algType = "HASH"
or
name = "rsa-md5" and nid = 8 and normalized = "RSA" and algType = "SIGNATURE"
name = "rsa-md5" and nid = 8 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "rsa-md5" and nid = 8 and normalized = "MD5" and algType = "HASH"
or
name = "rsa-mdc2" and nid = 96 and normalized = "RSA" and algType = "SIGNATURE"
name = "rsa-mdc2" and nid = 96 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "rsa-mdc2" and nid = 96 and normalized = "MDC2" and algType = "HASH"
or
name = "rsa-np-md5" and nid = 104 and normalized = "RSA" and algType = "SIGNATURE"
name = "rsa-np-md5" and nid = 104 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "rsa-np-md5" and nid = 104 and normalized = "MD5" and algType = "HASH"
or
name = "rsa-ripemd160" and nid = 119 and normalized = "RSA" and algType = "SIGNATURE"
name = "rsa-ripemd160" and nid = 119 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "rsa-ripemd160" and nid = 119 and normalized = "RIPEMD160" and algType = "HASH"
or
name = "rsa-sha" and nid = 42 and normalized = "RSA" and algType = "SIGNATURE"
name = "rsa-sha" and nid = 42 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "rsa-sha" and nid = 42 and normalized = "SHA" and algType = "HASH"
or
name = "rsa-sha1" and nid = 65 and normalized = "RSA" and algType = "SIGNATURE"
name = "rsa-sha1" and nid = 65 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "rsa-sha1" and nid = 65 and normalized = "SHA1" and algType = "HASH"
or
name = "rsa-sha1-2" and nid = 115 and normalized = "RSA" and algType = "SIGNATURE"
name = "rsa-sha1-2" and nid = 115 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "rsa-sha1-2" and nid = 115 and normalized = "SHA1" and algType = "HASH"
or
name = "rsa-sha224" and nid = 671 and normalized = "RSA" and algType = "SIGNATURE"
name = "rsa-sha224" and nid = 671 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "rsa-sha224" and nid = 671 and normalized = "SHA-224" and algType = "HASH"
or
name = "rsa-sha256" and nid = 668 and normalized = "RSA" and algType = "SIGNATURE"
name = "rsa-sha256" and nid = 668 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "rsa-sha256" and nid = 668 and normalized = "SHA-256" and algType = "HASH"
or
name = "rsa-sha3-224" and nid = 1116 and normalized = "RSA" and algType = "SIGNATURE"
name = "rsa-sha3-224" and nid = 1116 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "rsa-sha3-224" and nid = 1116 and normalized = "SHA3-224" and algType = "HASH"
or
name = "rsa-sha3-256" and nid = 1117 and normalized = "RSA" and algType = "SIGNATURE"
name = "rsa-sha3-256" and nid = 1117 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "rsa-sha3-256" and nid = 1117 and normalized = "SHA3-256" and algType = "HASH"
or
name = "rsa-sha3-384" and nid = 1118 and normalized = "RSA" and algType = "SIGNATURE"
name = "rsa-sha3-384" and nid = 1118 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "rsa-sha3-384" and nid = 1118 and normalized = "SHA3-384" and algType = "HASH"
or
name = "rsa-sha3-512" and nid = 1119 and normalized = "RSA" and algType = "SIGNATURE"
name = "rsa-sha3-512" and nid = 1119 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "rsa-sha3-512" and nid = 1119 and normalized = "SHA3-512" and algType = "HASH"
or
name = "rsa-sha384" and nid = 669 and normalized = "RSA" and algType = "SIGNATURE"
name = "rsa-sha384" and nid = 669 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "rsa-sha384" and nid = 669 and normalized = "SHA-384" and algType = "HASH"
or
name = "rsa-sha512" and nid = 670 and normalized = "RSA" and algType = "SIGNATURE"
name = "rsa-sha512" and nid = 670 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "rsa-sha512" and nid = 670 and normalized = "SHA-512" and algType = "HASH"
or
name = "rsa-sha512/224" and
nid = 1145 and
normalized = "RSA" and
algType = "SIGNATURE"
algType = "ASYMMETRIC_ENCRYPTION"
or
name = "rsa-sha512/224" and nid = 1145 and normalized = "SHA-512-224" and algType = "HASH"
or
name = "rsa-sha512/256" and
nid = 1146 and
normalized = "RSA" and
algType = "SIGNATURE"
algType = "ASYMMETRIC_ENCRYPTION"
or
name = "rsa-sha512/256" and nid = 1146 and normalized = "SHA-512-256" and algType = "HASH"
or
name = "rsa-sm3" and nid = 1144 and normalized = "RSA" and algType = "SIGNATURE"
name = "rsa-sm3" and nid = 1144 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "rsa-sm3" and nid = 1144 and normalized = "SM3" and algType = "HASH"
or
@@ -3112,52 +2845,52 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
normalized = "OAEP" and
algType = "ASYMMETRIC_PADDING"
or
name = "rsasignature" and nid = 377 and normalized = "RSA" and algType = "SIGNATURE"
name = "rsasignature" and nid = 377 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "rsassa-pss" and nid = 912 and normalized = "RSA" and algType = "SIGNATURE"
name = "rsassa-pss" and nid = 912 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "rsassa-pss" and nid = 912 and normalized = "PSS" and algType = "ASYMMETRIC_PADDING"
or
name = "rsassapss" and nid = 912 and normalized = "RSA" and algType = "SIGNATURE"
name = "rsassapss" and nid = 912 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "rsassapss" and nid = 912 and normalized = "PSS" and algType = "SIGNATURE"
name = "rsassapss" and nid = 912 and normalized = "PSS" and algType = "ASYMMETRIC_PADDING"
or
name = "sha1withrsa" and nid = 115 and normalized = "RSA" and algType = "SIGNATURE"
name = "sha1withrsa" and nid = 115 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
or
name = "sha1withrsa" and nid = 115 and normalized = "SHA1" and algType = "HASH"
or
name = "sha1withrsaencryption" and
nid = 65 and
normalized = "RSA" and
algType = "SIGNATURE"
algType = "ASYMMETRIC_ENCRYPTION"
or
name = "sha1withrsaencryption" and nid = 65 and normalized = "SHA1" and algType = "HASH"
or
name = "sha224withrsaencryption" and
nid = 671 and
normalized = "RSA" and
algType = "SIGNATURE"
algType = "ASYMMETRIC_ENCRYPTION"
or
name = "sha224withrsaencryption" and nid = 671 and normalized = "SHA-224" and algType = "HASH"
or
name = "sha256withrsaencryption" and
nid = 668 and
normalized = "RSA" and
algType = "SIGNATURE"
algType = "ASYMMETRIC_ENCRYPTION"
or
name = "sha256withrsaencryption" and nid = 668 and normalized = "SHA-256" and algType = "HASH"
or
name = "sha384withrsaencryption" and
nid = 669 and
normalized = "RSA" and
algType = "SIGNATURE"
algType = "ASYMMETRIC_ENCRYPTION"
or
name = "sha384withrsaencryption" and nid = 669 and normalized = "SHA-384" and algType = "HASH"
or
name = "sha512-224withrsaencryption" and
nid = 1145 and
normalized = "RSA" and
algType = "SIGNATURE"
algType = "ASYMMETRIC_ENCRYPTION"
or
name = "sha512-224withrsaencryption" and
nid = 1145 and
@@ -3167,7 +2900,7 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
name = "sha512-256withrsaencryption" and
nid = 1146 and
normalized = "RSA" and
algType = "SIGNATURE"
algType = "ASYMMETRIC_ENCRYPTION"
or
name = "sha512-256withrsaencryption" and
nid = 1146 and
@@ -3177,14 +2910,14 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
name = "sha512withrsaencryption" and
nid = 670 and
normalized = "RSA" and
algType = "SIGNATURE"
algType = "ASYMMETRIC_ENCRYPTION"
or
name = "sha512withrsaencryption" and nid = 670 and normalized = "SHA-512" and algType = "HASH"
or
name = "shawithrsaencryption" and
nid = 42 and
normalized = "RSA" and
algType = "SIGNATURE"
algType = "ASYMMETRIC_ENCRYPTION"
or
name = "shawithrsaencryption" and nid = 42 and normalized = "SHA" and algType = "HASH"
or
@@ -3201,11 +2934,7 @@ predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized,
name = "sm3withrsaencryption" and
nid = 1144 and
normalized = "RSA" and
algType = "SIGNATURE"
algType = "ASYMMETRIC_ENCRYPTION"
or
name = "sm3withrsaencryption" and nid = 1144 and normalized = "SM3" and algType = "HASH"
or
name = "hmac" and nid = 855 and normalized = "HMAC" and algType = "MAC"
or
name = "cmac" and nid = 894 and normalized = "CMAC" and algType = "MAC"
}

View File

@@ -1,66 +0,0 @@
import cpp
private import experimental.quantum.Language
private import KnownAlgorithmConstants
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
private import experimental.quantum.OpenSSL.Operations.OpenSSLOperations
private import AlgToAVCFlow
class KnownOpenSslMacConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
Crypto::MacAlgorithmInstance instanceof KnownOpenSslMacAlgorithmExpr
{
OpenSslAlgorithmValueConsumer getterCall;
KnownOpenSslMacConstantAlgorithmInstance() {
// Two possibilities:
// 1) The source is a literal and flows to a getter, then we know we have an instance
// 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that
// Possibility 1:
this instanceof OpenSslAlgorithmLiteral and
exists(DataFlow::Node src, DataFlow::Node sink |
// Sink is an argument to a CipherGetterCall
sink = getterCall.getInputNode() and
// Source is `this`
src.asExpr() = this and
// This traces to a getter
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
)
or
// Possibility 2:
this instanceof OpenSslAlgorithmCall and
getterCall = this
}
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
override string getRawMacAlgorithmName() {
result = this.(Literal).getValue().toString()
or
result = this.(Call).getTarget().getName()
}
override Crypto::MacType getMacType() {
this instanceof KnownOpenSslHMacAlgorithmExpr and result = Crypto::HMAC()
or
this instanceof KnownOpenSslCMacAlgorithmExpr and result = Crypto::CMAC()
}
}
class KnownOpenSslHMacConstantAlgorithmInstance extends Crypto::HmacAlgorithmInstance,
KnownOpenSslMacConstantAlgorithmInstance
{
override Crypto::AlgorithmValueConsumer getHashAlgorithmValueConsumer() {
if exists(this.(KnownOpenSslHMacAlgorithmExpr).getExplicitHashAlgorithm())
then
// ASSUMPTION: if there is an explicit hash algorithm, it is already modeled
// and we can simply grab that model's AVC
exists(OpenSslAlgorithmInstance inst | inst.getAvc() = result and inst = this)
else
// ASSUMPTION: If no explicit algorithm is given, then it is assumed to be configured by
// a signature operation
exists(Crypto::SignatureOperationInstance s |
s.getHashAlgorithmValueConsumer() = result and
s.getAnAlgorithmValueConsumer() = this.getAvc()
)
}
}

View File

@@ -1,6 +1,6 @@
private import experimental.quantum.Language
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
abstract class OpenSslAlgorithmInstance extends Crypto::AlgorithmInstance {
abstract OpenSslAlgorithmValueConsumer getAvc();
abstract class OpenSSLAlgorithmInstance extends Crypto::AlgorithmInstance {
abstract OpenSSLAlgorithmValueConsumer getAVC();
}

View File

@@ -4,5 +4,3 @@ import PaddingAlgorithmInstance
import BlockAlgorithmInstance
import HashAlgorithmInstance
import EllipticCurveAlgorithmInstance
import SignatureAlgorithmInstance
import MACAlgorithmInstance

View File

@@ -5,7 +5,6 @@ private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmCon
private import AlgToAVCFlow
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
private import codeql.quantum.experimental.Standardization::Types::KeyOpAlg as KeyOpAlg
/**
* A class to define padding specific integer values.
@@ -18,109 +17,105 @@ private import codeql.quantum.experimental.Standardization::Types::KeyOpAlg as K
* # define RSA_PKCS1_WITH_TLS_PADDING 7
* # define RSA_PKCS1_NO_IMPLICIT_REJECT_PADDING 8
*/
class OpenSslPaddingLiteral extends Literal {
class OpenSSLPaddingLiteral extends Literal {
// TODO: we can be more specific about where the literal is in a larger expression
// to avoid literals that are clealy not representing an algorithm, e.g., array indices.
OpenSslPaddingLiteral() { this.getValue().toInt() in [0, 1, 3, 4, 5, 6, 7, 8] }
OpenSSLPaddingLiteral() { this.getValue().toInt() in [0, 1, 3, 4, 5, 6, 7, 8] }
}
/**
* Given a `KnownOpenSslPaddingAlgorithmExpr`, converts this to a padding family type.
* Given a `KnownOpenSSLPaddingAlgorithmConstant`, converts this to a padding family type.
* Does not bind if there is no mapping (no mapping to 'unknown' or 'other').
*/
predicate knownOpenSslConstantToPaddingFamilyType(
KnownOpenSslPaddingAlgorithmExpr e, KeyOpAlg::PaddingSchemeType type
predicate knownOpenSSLConstantToPaddingFamilyType(
KnownOpenSSLPaddingAlgorithmConstant e, Crypto::TPaddingType type
) {
exists(string name |
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
name = e.getNormalizedName() and
(
name = "OAEP" and type = KeyOpAlg::OAEP()
name.matches("OAEP") and type = Crypto::OAEP()
or
name = "PSS" and type = KeyOpAlg::PSS()
name.matches("PSS") and type = Crypto::PSS()
or
name = "PKCS7" and type = KeyOpAlg::PKCS7()
name.matches("PKCS7") and type = Crypto::PKCS7()
or
name = "PKCS1V15" and type = KeyOpAlg::PKCS1_V1_5()
name.matches("PKCS1V15") and type = Crypto::PKCS1_v1_5()
)
)
}
//abstract class OpenSslPaddingAlgorithmInstance extends OpenSslAlgorithmInstance, Crypto::PaddingAlgorithmInstance{}
//abstract class OpenSSLPaddingAlgorithmInstance extends OpenSSLAlgorithmInstance, Crypto::PaddingAlgorithmInstance{}
// TODO: need to alter this to include known padding constants which don't have the
// same mechanics as those with known nids
class KnownOpenSslPaddingConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
class KnownOpenSSLPaddingConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
Crypto::PaddingAlgorithmInstance instanceof Expr
{
OpenSslAlgorithmValueConsumer getterCall;
OpenSSLAlgorithmValueConsumer getterCall;
boolean isPaddingSpecificConsumer;
KnownOpenSslPaddingConstantAlgorithmInstance() {
KnownOpenSSLPaddingConstantAlgorithmInstance() {
// three possibilities:
// 1) The source is a 'typical' literal and flows to a getter, then we know we have an instance
// 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that
// 2) The source is a KnownOpenSSLAlgorithm is call, and we know we have an instance immediately from that
// 3) the source is a padding-specific literal flowing to a padding-specific consumer
// Possibility 1:
this instanceof OpenSslAlgorithmLiteral and
this instanceof KnownOpenSslPaddingAlgorithmExpr and
this instanceof Literal and
this instanceof KnownOpenSSLPaddingAlgorithmConstant and
exists(DataFlow::Node src, DataFlow::Node sink |
// Sink is an argument to a CipherGetterCall
sink = getterCall.getInputNode() and
sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and
// Source is `this`
src.asExpr() = this and
// This traces to a getter
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) and
KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) and
isPaddingSpecificConsumer = false
)
or
// Possibility 2:
this instanceof OpenSslAlgorithmCall and
this instanceof DirectAlgorithmValueConsumer and
getterCall = this and
this instanceof KnownOpenSslPaddingAlgorithmExpr and
this instanceof KnownOpenSSLPaddingAlgorithmConstant and
isPaddingSpecificConsumer = false
or
// Possibility 3: padding-specific literal
this instanceof OpenSslPaddingLiteral and
this instanceof OpenSSLPaddingLiteral and
exists(DataFlow::Node src, DataFlow::Node sink |
// Sink is an argument to a CipherGetterCall
sink = getterCall.getInputNode() and
sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and
// Source is `this`
src.asExpr() = this and
// This traces to a padding-specific consumer
RsaPaddingAlgorithmToPaddingAlgorithmValueConsumerFlow::flow(src, sink)
RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerFlow::flow(src, sink)
) and
isPaddingSpecificConsumer = true
}
override string getRawPaddingAlgorithmName() {
result = this.(Literal).getValue().toString()
override string getRawPaddingAlgorithmName() { result = this.(Literal).getValue().toString() }
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
Crypto::TPaddingType getKnownPaddingType() {
this.(Literal).getValue().toInt() in [1, 7, 8] and result = Crypto::PKCS1_v1_5()
or
result = this.(Call).getTarget().getName()
this.(Literal).getValue().toInt() = 3 and result = Crypto::NoPadding()
or
this.(Literal).getValue().toInt() = 4 and result = Crypto::OAEP()
or
this.(Literal).getValue().toInt() = 5 and result = Crypto::ANSI_X9_23()
or
this.(Literal).getValue().toInt() = 6 and result = Crypto::PSS()
}
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
KeyOpAlg::PaddingSchemeType getKnownPaddingType() {
this.(Literal).getValue().toInt() in [1, 7, 8] and result = KeyOpAlg::PKCS1_V1_5()
or
this.(Literal).getValue().toInt() = 3 and result = KeyOpAlg::NoPadding()
or
this.(Literal).getValue().toInt() = 4 and result = KeyOpAlg::OAEP()
or
this.(Literal).getValue().toInt() = 5 and result = KeyOpAlg::ANSI_X9_23()
or
this.(Literal).getValue().toInt() = 6 and result = KeyOpAlg::PSS()
}
override KeyOpAlg::PaddingSchemeType getPaddingType() {
override Crypto::TPaddingType getPaddingType() {
isPaddingSpecificConsumer = true and
(
result = this.getKnownPaddingType()
or
not exists(this.getKnownPaddingType()) and result = KeyOpAlg::OtherPadding()
not exists(this.getKnownPaddingType()) and result = Crypto::OtherPadding()
)
or
isPaddingSpecificConsumer = false and
knownOpenSslConstantToPaddingFamilyType(this, result)
knownOpenSSLConstantToPaddingFamilyType(this, result)
}
}
@@ -128,7 +123,7 @@ class KnownOpenSslPaddingConstantAlgorithmInstance extends OpenSslAlgorithmInsta
// // not the same as 'typical' constants found in the set of known algorithm constants
// // they do not have an NID
// // TODO: what about setting the padding directly?
// class KnownRSAPaddingConstant extends OpenSslPaddingAlgorithmInstance, Crypto::PaddingAlgorithmInstance instanceof Literal
// class KnownRSAPaddingConstant extends OpenSSLPaddingAlgorithmInstance, Crypto::PaddingAlgorithmInstance instanceof Literal
// {
// KnownRSAPaddingConstant() {
// // from rsa.h in openssl:
@@ -144,7 +139,7 @@ class KnownOpenSslPaddingConstantAlgorithmInstance extends OpenSslAlgorithmInsta
// this instanceof Literal and
// this.getValue().toInt() in [0, 1, 3, 4, 5, 6, 7, 8]
// // TODO: trace to padding-specific consumers
// RsaPaddingAlgorithmToPaddingAlgorithmValueConsumerFlow
// RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerFlow
// }
// override string getRawPaddingAlgorithmName() { result = this.(Literal).getValue().toString() }
// override Crypto::TPaddingType getPaddingType() {
@@ -162,18 +157,18 @@ class KnownOpenSslPaddingConstantAlgorithmInstance extends OpenSslAlgorithmInsta
// else result = Crypto::OtherPadding()
// }
// }
class OaepPaddingAlgorithmInstance extends Crypto::OaepPaddingAlgorithmInstance,
KnownOpenSslPaddingConstantAlgorithmInstance
class OAEPPaddingAlgorithmInstance extends Crypto::OAEPPaddingAlgorithmInstance,
KnownOpenSSLPaddingConstantAlgorithmInstance
{
OaepPaddingAlgorithmInstance() {
this.(Crypto::PaddingAlgorithmInstance).getPaddingType() = KeyOpAlg::OAEP()
OAEPPaddingAlgorithmInstance() {
this.(Crypto::PaddingAlgorithmInstance).getPaddingType() = Crypto::OAEP()
}
override Crypto::HashAlgorithmInstance getOaepEncodingHashAlgorithm() {
override Crypto::HashAlgorithmInstance getOAEPEncodingHashAlgorithm() {
none() //TODO
}
override Crypto::HashAlgorithmInstance getMgf1HashAlgorithm() {
override Crypto::HashAlgorithmInstance getMGF1HashAlgorithm() {
none() //TODO
}
}

View File

@@ -1,102 +0,0 @@
import cpp
private import experimental.quantum.Language
private import KnownAlgorithmConstants
private import Crypto::KeyOpAlg as KeyOpAlg
private import OpenSSLAlgorithmInstanceBase
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
private import AlgToAVCFlow
/**
* Gets the signature algorithm type based on the normalized algorithm name.
*/
private predicate knownOpenSslConstantToSignatureFamilyType(
KnownOpenSslSignatureAlgorithmExpr e, Crypto::KeyOpAlg::TAlgorithm type
) {
exists(string name |
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
(
name.matches("RSA%") and type = KeyOpAlg::TAsymmetricCipher(KeyOpAlg::RSA())
or
name.matches("DSA%") and type = KeyOpAlg::TSignature(KeyOpAlg::DSA())
or
name.matches("ECDSA%") and type = KeyOpAlg::TSignature(KeyOpAlg::ECDSA())
or
name.matches("ED25519%") and type = KeyOpAlg::TSignature(KeyOpAlg::EDDSA())
or
name.matches("ED448%") and type = KeyOpAlg::TSignature(KeyOpAlg::EDDSA())
)
)
}
/**
* A signature algorithm instance derived from an OpenSsl constant.
*/
class KnownOpenSslSignatureConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
Crypto::KeyOperationAlgorithmInstance instanceof KnownOpenSslSignatureAlgorithmExpr
{
OpenSslAlgorithmValueConsumer getterCall;
KnownOpenSslSignatureConstantAlgorithmInstance() {
// Two possibilities:
// 1) The source is a literal and flows to a getter, then we know we have an instance
// 2) The source is a KnownOpenSslAlgorithm call, and we know we have an instance immediately from that
// Possibility 1:
this instanceof OpenSslAlgorithmLiteral and
exists(DataFlow::Node src, DataFlow::Node sink |
// Sink is an argument to a signature getter call
sink = getterCall.getInputNode() and
// Source is `this`
src.asExpr() = this and
// This traces to a getter
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
)
or
// Possibility 2:
this instanceof OpenSslAlgorithmCall and
getterCall = this
}
override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() { none() }
override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() { none() }
override string getRawAlgorithmName() {
result = this.(Literal).getValue().toString()
or
result = this.(Call).getTarget().getName()
}
override int getKeySizeFixed() {
// TODO: use ellipticCurveNameToKeySizeAndFamilyMapping or KnownOpenSslEllipticCurveConstantAlgorithmInstance
// TODO: maybe add getExplicitKeySize to KnownOpenSslSignatureAlgorithmExpr and use it here
none()
}
override KeyOpAlg::AlgorithmType getAlgorithmType() {
knownOpenSslConstantToSignatureFamilyType(this, result)
or
not knownOpenSslConstantToSignatureFamilyType(this, _) and
result = KeyOpAlg::TSignature(KeyOpAlg::OtherSignatureAlgorithmType())
}
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() {
// TODO: trace to any key size initializer
// probably PKeyAlgorithmValueConsumer and SignatureAlgorithmValueConsumer
none()
}
/**
* No mode for signatures.
*/
override predicate shouldHaveModeOfOperation() { none() }
/**
* Padding only for RSA.
*/
override predicate shouldHavePaddingScheme() {
this.getAlgorithmType() instanceof KeyOpAlg::TAsymmetricCipher
}
}

View File

@@ -4,14 +4,14 @@ private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmCon
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
private import OpenSSLAlgorithmValueConsumerBase
abstract class CipherAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer { }
abstract class CipherAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { }
// https://www.openssl.org/docs/manmaster/man3/EVP_CIPHER_fetch.html
class EvpCipherAlgorithmValueConsumer extends CipherAlgorithmValueConsumer {
class EVPCipherAlgorithmValueConsumer extends CipherAlgorithmValueConsumer {
DataFlow::Node valueArgNode;
DataFlow::Node resultNode;
EvpCipherAlgorithmValueConsumer() {
EVPCipherAlgorithmValueConsumer() {
resultNode.asExpr() = this and
(
this.(Call).getTarget().getName() in [
@@ -30,8 +30,8 @@ class EvpCipherAlgorithmValueConsumer extends CipherAlgorithmValueConsumer {
// override DataFlow::Node getInputNode() { result = valueArgNode }
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
//TODO: As a potential alternative, for OpenSsl only, add a generic source node for literals and only create flow (flowsTo) to
// OpenSsl AVCs... the unknown literal sources would have to be any literals not in the known set.
exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i)
//TODO: As a potential alternative, for OpenSSL only, add a generic source node for literals and only create flow (flowsTo) to
// OpenSSL AVCs... the unknown literal sources would have to be any literals not in the known set.
}
}

Some files were not shown because too many files have changed in this diff Show More