mirror of
https://github.com/github/codeql.git
synced 2026-04-19 14:04:09 +02:00
Merge branch 'main' into lifetime
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
name: Codegen
|
||||
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
|
||||
@@ -17,17 +18,17 @@ permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
codegen:
|
||||
check-python-tooling:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version-file: 'misc/codegen/.python-version'
|
||||
python-version: '3.12'
|
||||
- uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507
|
||||
name: Check that python code is properly formatted
|
||||
with:
|
||||
extra_args: autopep8 --all-files
|
||||
extra_args: black --all-files
|
||||
- name: Run codegen tests
|
||||
shell: bash
|
||||
run: |
|
||||
2
.github/workflows/validate-change-notes.yml
vendored
2
.github/workflows/validate-change-notes.yml
vendored
@@ -31,4 +31,4 @@ jobs:
|
||||
- name: Fail if there are any errors with existing change notes
|
||||
|
||||
run: |
|
||||
codeql pack release --groups cpp,csharp,java,javascript,python,ruby,-examples,-test,-experimental
|
||||
codeql pack release --groups actions,cpp,csharp,go,java,javascript,python,ruby,shared,swift -examples,-test,-experimental
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# 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
|
||||
@@ -7,18 +9,18 @@ repos:
|
||||
- id: trailing-whitespace
|
||||
exclude: /test/.*$(?<!\.qlref)|.*\.patch$|.*\.qll?$
|
||||
- id: end-of-file-fixer
|
||||
exclude: /test/.*$(?<!\.qlref)|.*\.patch$|.*\.qll?$
|
||||
exclude: Cargo.lock$|/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/pre-commit/mirrors-autopep8
|
||||
rev: v2.0.4
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 25.1.0
|
||||
hooks:
|
||||
- id: autopep8
|
||||
files: ^misc/codegen/.*\.py
|
||||
- id: black
|
||||
files: ^(misc/codegen/.*|misc/scripts/models-as-data/.*)\.py$
|
||||
|
||||
- repo: local
|
||||
hooks:
|
||||
|
||||
919
Cargo.lock
generated
919
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -11,8 +11,3 @@ 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" }
|
||||
|
||||
54
MODULE.bazel
54
MODULE.bazel
@@ -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.85.0"
|
||||
RUST_VERSION = "1.86.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.97",
|
||||
"vendor_ts__anyhow-1.0.98",
|
||||
"vendor_ts__argfile-0.2.1",
|
||||
"vendor_ts__chalk-ir-0.100.0",
|
||||
"vendor_ts__chrono-0.4.40",
|
||||
"vendor_ts__clap-4.5.35",
|
||||
"vendor_ts__chalk-ir-0.103.0",
|
||||
"vendor_ts__chrono-0.4.41",
|
||||
"vendor_ts__clap-4.5.40",
|
||||
"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.16.0",
|
||||
"vendor_ts__proc-macro2-1.0.94",
|
||||
"vendor_ts__num_cpus-1.17.0",
|
||||
"vendor_ts__proc-macro2-1.0.95",
|
||||
"vendor_ts__quote-1.0.40",
|
||||
"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__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__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.12.0",
|
||||
"vendor_ts__syn-2.0.100",
|
||||
"vendor_ts__toml-0.8.20",
|
||||
"vendor_ts__serde_with-3.13.0",
|
||||
"vendor_ts__syn-2.0.103",
|
||||
"vendor_ts__toml-0.8.23",
|
||||
"vendor_ts__tracing-0.1.41",
|
||||
"vendor_ts__tracing-flame-0.2.0",
|
||||
"vendor_ts__tracing-subscriber-0.3.19",
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -2,7 +2,7 @@ import runs_on
|
||||
import pytest
|
||||
from query_suites import *
|
||||
|
||||
well_known_query_suites = ['actions-code-quality.qls', 'actions-security-and-quality.qls', 'actions-security-extended.qls', 'actions-code-scanning.qls']
|
||||
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']
|
||||
|
||||
@runs_on.posix
|
||||
@pytest.mark.parametrize("query_suite", well_known_query_suites)
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
## 0.4.11
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.4.10
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.4.9
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* 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.
|
||||
3
actions/ql/lib/change-notes/released/0.4.10.md
Normal file
3
actions/ql/lib/change-notes/released/0.4.10.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.4.10
|
||||
|
||||
No user-facing changes.
|
||||
3
actions/ql/lib/change-notes/released/0.4.11.md
Normal file
3
actions/ql/lib/change-notes/released/0.4.11.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.4.11
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.4.9
|
||||
lastReleaseVersion: 0.4.11
|
||||
|
||||
@@ -50,8 +50,8 @@ class Expression extends AstNode instanceof ExpressionImpl {
|
||||
string getNormalizedExpression() { result = normalizeExpr(expression) }
|
||||
}
|
||||
|
||||
/** A common class for `env` in workflow, job or step. */
|
||||
abstract class Env extends AstNode instanceof EnvImpl {
|
||||
/** An `env` in workflow, job or step. */
|
||||
class Env extends AstNode instanceof EnvImpl {
|
||||
/** Gets an environment variable value given its name. */
|
||||
ScalarValueImpl getEnvVarValue(string name) { result = super.getEnvVarValue(name) }
|
||||
|
||||
|
||||
@@ -8,35 +8,64 @@ class BashShellScript extends ShellScript {
|
||||
)
|
||||
}
|
||||
|
||||
private string lineProducer(int i) {
|
||||
result = this.getRawScript().regexpReplaceAll("\\\\\\s*\n", "").splitAt("\n", i)
|
||||
/**
|
||||
* 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 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
|
||||
)
|
||||
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 rankedCmdSubstitutionReplacements(int i, string old, string new) {
|
||||
old = rank[i](string old2 | this.cmdSubstitutionReplacement(old2, _, _) | old2) and
|
||||
this.cmdSubstitutionReplacement(old, new, _)
|
||||
/**
|
||||
* 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 doReplaceCmdSubstitutions(int line, int round, string old, string new) {
|
||||
@@ -64,31 +93,56 @@ 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(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]", "")
|
||||
)
|
||||
exists(int lineIndex |
|
||||
this.doubleQuotedString(lineIndex, quotedStr, id)
|
||||
or
|
||||
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]", "")
|
||||
)
|
||||
this.singleQuotedString(lineIndex, quotedStr, id)
|
||||
) and
|
||||
// Only do this for strings that might otherwise disrupt subsequent parsing
|
||||
quotedStr.regexpMatch("[\"'].*[$\n\r'\"" + Bash::separator() + "].*[\"']")
|
||||
}
|
||||
|
||||
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 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 doReplaceQuotedStrings(int line, int round, string old, string new) {
|
||||
|
||||
@@ -214,6 +214,10 @@ 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. */
|
||||
|
||||
@@ -16,6 +16,10 @@ 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. */
|
||||
|
||||
@@ -15,6 +15,10 @@ 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. */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-all
|
||||
version: 0.4.10-dev
|
||||
version: 0.4.12-dev
|
||||
library: true
|
||||
warnOnImplicitThis: true
|
||||
dependencies:
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
## 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.
|
||||
|
||||
@@ -24,6 +24,10 @@ 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>;
|
||||
|
||||
@@ -34,6 +34,10 @@ 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>;
|
||||
|
||||
@@ -25,6 +25,10 @@ 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>;
|
||||
|
||||
@@ -24,6 +24,10 @@ 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>;
|
||||
|
||||
@@ -34,6 +34,10 @@ 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>;
|
||||
|
||||
@@ -25,6 +25,10 @@ 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>;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
## 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.
|
||||
3
actions/ql/src/change-notes/released/0.6.3.md
Normal file
3
actions/ql/src/change-notes/released/0.6.3.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.6.3
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.6.1
|
||||
lastReleaseVersion: 0.6.3
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
- queries: .
|
||||
- apply: code-quality-extended-selectors.yml
|
||||
from: codeql/suite-helpers
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-queries
|
||||
version: 0.6.2-dev
|
||||
version: 0.6.4-dev
|
||||
library: false
|
||||
warnOnImplicitThis: true
|
||||
groups: [actions, queries]
|
||||
|
||||
81
actions/ql/test/query-tests/Security/CWE-094/.github/workflows/interpolation.yml
vendored
Normal file
81
actions/ql/test/query-tests/Security/CWE-094/.github/workflows/interpolation.yml
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
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
|
||||
31
cpp/bulk_generation_targets.yml
Normal file
31
cpp/bulk_generation_targets.yml
Normal file
@@ -0,0 +1,31 @@
|
||||
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
|
||||
@@ -0,0 +1,7 @@
|
||||
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
|
||||
2493
cpp/downgrades/3c45f8b9e71ec723bf50c40581e1f18f4f25e290/old.dbscheme
Normal file
2493
cpp/downgrades/3c45f8b9e71ec723bf50c40581e1f18f4f25e290/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
description: capture whether a lambda has an explicitly specified parameter list.
|
||||
compatibility: full
|
||||
lambdas.rel: run lambdas.qlo
|
||||
2499
cpp/downgrades/9baef67d1ffc1551429dbe1c1130815693e28218/old.dbscheme
Normal file
2499
cpp/downgrades/9baef67d1ffc1551429dbe1c1130815693e28218/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
description: Add a predicate `getAnAttribute` to `Namespace`
|
||||
compatibility: full
|
||||
namespaceattributes.rel: delete
|
||||
2494
cpp/downgrades/a8c2176e9a5cf9be8d17053a4c8e7e56b5aced6d/old.dbscheme
Normal file
2494
cpp/downgrades/a8c2176e9a5cf9be8d17053a4c8e7e56b5aced6d/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
||||
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
|
||||
@@ -0,0 +1,3 @@
|
||||
description: Support `__leave` statement
|
||||
compatibility: full
|
||||
stmts.rel: run stmts.qlo
|
||||
@@ -0,0 +1,9 @@
|
||||
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
|
||||
2492
cpp/downgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/old.dbscheme
Normal file
2492
cpp/downgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
description: Support __mfp8 type
|
||||
compatibility: backwards
|
||||
builtintypes.rel: run builtintypes.qlo
|
||||
@@ -0,0 +1,9 @@
|
||||
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
|
||||
@@ -0,0 +1,9 @@
|
||||
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
|
||||
2506
cpp/downgrades/e38346051783182ea75822e4adf8d4c6a949bc37/old.dbscheme
Normal file
2506
cpp/downgrades/e38346051783182ea75822e4adf8d4c6a949bc37/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
description: Arm scalable vector type support
|
||||
compatibility: backwards
|
||||
builtintypes.rel: run builtintypes.qlo
|
||||
derivedtypes.rel: run derivedtypes.qlo
|
||||
tupleelements.rel: delete
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"strategy": "dca",
|
||||
"language": "cpp",
|
||||
"targets": [
|
||||
{ "name": "openssl", "with-sources": false, "with-sinks": false },
|
||||
{ "name": "sqlite", "with-sources": false, "with-sinks": false }
|
||||
],
|
||||
"destination": "cpp/ql/lib/ext/generated"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -2,7 +2,7 @@ import runs_on
|
||||
import pytest
|
||||
from query_suites import *
|
||||
|
||||
well_known_query_suites = ['cpp-code-quality.qls', 'cpp-security-and-quality.qls', 'cpp-security-extended.qls', 'cpp-code-scanning.qls']
|
||||
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']
|
||||
|
||||
@runs_on.posix
|
||||
@pytest.mark.parametrize("query_suite", well_known_query_suites)
|
||||
|
||||
@@ -1,3 +1,33 @@
|
||||
## 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
|
||||
|
||||
4
cpp/ql/lib/change-notes/2014-12-13-deprecate-throwing.md
Normal file
4
cpp/ql/lib/change-notes/2014-12-13-deprecate-throwing.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: deprecated
|
||||
---
|
||||
* The `ThrowingFunction` class (`semmle.code.cpp.models.interfaces.Throwing`) has been deprecated. Please use the `AlwaysSehThrowingFunction` class instead.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* Fixed a problem where `asExpr()` on `DataFlow::Node` would never return `ClassAggregateLiteral`s.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* Fixed a problem where `asExpr()` on `DataFlow::Node` would never return `ArrayAggregateLiteral`s.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added support for `wmain` as part of the ArgvSource model.
|
||||
@@ -1,9 +0,0 @@
|
||||
---
|
||||
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`.
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* 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`.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added local flow source models for `ReadFile`, `ReadFileEx`, `MapViewOfFile`, `MapViewOfFile2`, `MapViewOfFile3`, `MapViewOfFile3FromApp`, `MapViewOfFileEx`, `MapViewOfFileFromApp`, `MapViewOfFileNuma2`, and `NtReadFile`.
|
||||
4
cpp/ql/lib/change-notes/2025-06-06-lambda-parameters.md
Normal file
4
cpp/ql/lib/change-notes/2025-06-06-lambda-parameters.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added a predicate `hasParameterList` to `LambdaExpression` to capture whether a lambda has an explicitly specified parameter list.
|
||||
5
cpp/ql/lib/change-notes/2025-06-11-leave-stmt.md
Normal file
5
cpp/ql/lib/change-notes/2025-06-11-leave-stmt.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* The Microsoft-specific `__leave` statement is now supported.
|
||||
* A new class `LeaveStmt` extending `JumpStmt` was added to represent `__leave` statements.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added a predicate `getAnAttribute` to `Namespace` to retrieve a namespace attribute.
|
||||
4
cpp/ql/lib/change-notes/2025-06-17-arraytype-typedefs.md
Normal file
4
cpp/ql/lib/change-notes/2025-06-17-arraytype-typedefs.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* `resolveTypedefs` now properly resolves typedefs for `ArrayType`s.
|
||||
23
cpp/ql/lib/change-notes/released/5.0.0.md
Normal file
23
cpp/ql/lib/change-notes/released/5.0.0.md
Normal file
@@ -0,0 +1,23 @@
|
||||
## 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.
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
## 5.1.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a predicate `getReferencedMember` to `UsingDeclarationEntry`, which yields a member depending on a type template parameter.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 4.3.1
|
||||
lastReleaseVersion: 5.1.0
|
||||
|
||||
@@ -13,7 +13,9 @@ module CryptoInput implements InputSig<Language::Location> {
|
||||
LocatableElement dfn_to_element(DataFlow::Node node) {
|
||||
result = node.asExpr() or
|
||||
result = node.asParameter() or
|
||||
result = node.asVariable()
|
||||
result = node.asVariable() or
|
||||
result = node.asDefiningArgument()
|
||||
// TODO: do we need asIndirectExpr()?
|
||||
}
|
||||
|
||||
string locationToFileBaseNameAndLineNumberString(Location location) {
|
||||
@@ -90,7 +92,7 @@ module GenericDataSourceFlowConfig implements DataFlow::ConfigSig {
|
||||
module GenericDataSourceFlow = TaintTracking::Global<GenericDataSourceFlowConfig>;
|
||||
|
||||
private class ConstantDataSource extends Crypto::GenericConstantSourceInstance instanceof Literal {
|
||||
ConstantDataSource() { this instanceof OpenSSLGenericSourceCandidateLiteral }
|
||||
ConstantDataSource() { this instanceof OpenSslGenericSourceCandidateLiteral }
|
||||
|
||||
override DataFlow::Node getOutputNode() { result.asExpr() = this }
|
||||
|
||||
|
||||
@@ -12,13 +12,15 @@ 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 KnownOpenSSLAlgorithmConstant
|
||||
source.asExpr() instanceof KnownOpenSslAlgorithmExpr and
|
||||
// No need to flow direct operations to AVCs
|
||||
not source.asExpr() instanceof OpenSslDirectAlgorithmOperationCall
|
||||
}
|
||||
|
||||
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
|
||||
@@ -43,11 +45,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 }
|
||||
predicate isSource(DataFlow::Node source) { source.asExpr() instanceof OpenSslPaddingLiteral }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(PaddingAlgorithmValueConsumer c | c.getInputNode() = sink)
|
||||
@@ -61,8 +63,8 @@ module RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig implements DataF
|
||||
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)
|
||||
|
||||
@@ -7,14 +7,14 @@ private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgor
|
||||
private import AlgToAVCFlow
|
||||
|
||||
/**
|
||||
* Given a `KnownOpenSSLBlockModeAlgorithmConstant`, converts this to a block family type.
|
||||
* Given a `KnownOpenSslBlockModeAlgorithmExpr`, converts this to a block family type.
|
||||
* Does not bind if there is no mapping (no mapping to 'unknown' or 'other').
|
||||
*/
|
||||
predicate knownOpenSSLConstantToBlockModeFamilyType(
|
||||
KnownOpenSSLBlockModeAlgorithmConstant e, Crypto::TBlockCipherModeOfOperationType type
|
||||
predicate knownOpenSslConstantToBlockModeFamilyType(
|
||||
KnownOpenSslBlockModeAlgorithmExpr e, Crypto::TBlockCipherModeOfOperationType type
|
||||
) {
|
||||
exists(string name |
|
||||
name = e.getNormalizedName() and
|
||||
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
|
||||
(
|
||||
name.matches("CBC") and type instanceof Crypto::CBC
|
||||
or
|
||||
@@ -39,34 +39,35 @@ predicate knownOpenSSLConstantToBlockModeFamilyType(
|
||||
)
|
||||
}
|
||||
|
||||
class KnownOpenSSLBlockModeConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
|
||||
Crypto::ModeOfOperationAlgorithmInstance instanceof KnownOpenSSLBlockModeAlgorithmConstant
|
||||
class KnownOpenSslBlockModeConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
|
||||
Crypto::ModeOfOperationAlgorithmInstance instanceof KnownOpenSslBlockModeAlgorithmExpr
|
||||
{
|
||||
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 Literal and
|
||||
this instanceof OpenSslAlgorithmLiteral and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink |
|
||||
// Sink is an argument to a CipherGetterCall
|
||||
sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and
|
||||
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 DirectAlgorithmValueConsumer and getterCall = this
|
||||
this instanceof OpenSslAlgorithmCall and
|
||||
getterCall = this
|
||||
}
|
||||
|
||||
override Crypto::TBlockCipherModeOfOperationType getModeType() {
|
||||
knownOpenSSLConstantToBlockModeFamilyType(this, result)
|
||||
knownOpenSslConstantToBlockModeFamilyType(this, result)
|
||||
or
|
||||
not knownOpenSSLConstantToBlockModeFamilyType(this, _) and result = Crypto::OtherMode()
|
||||
not knownOpenSslConstantToBlockModeFamilyType(this, _) and result = Crypto::OtherMode()
|
||||
}
|
||||
|
||||
// NOTE: I'm not going to attempt to parse out the mode specific part, so returning
|
||||
@@ -77,5 +78,5 @@ class KnownOpenSSLBlockModeConstantAlgorithmInstance extends OpenSSLAlgorithmIns
|
||||
result = this.(Call).getTarget().getName()
|
||||
}
|
||||
|
||||
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
|
||||
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
|
||||
}
|
||||
|
||||
@@ -10,14 +10,14 @@ private import AlgToAVCFlow
|
||||
private import BlockAlgorithmInstance
|
||||
|
||||
/**
|
||||
* Given a `KnownOpenSSLCipherAlgorithmConstant`, converts this to a cipher family type.
|
||||
* Given a `KnownOpenSslCipherAlgorithmExpr`, converts this to a cipher family type.
|
||||
* Does not bind if there is no mapping (no mapping to 'unknown' or 'other').
|
||||
*/
|
||||
predicate knownOpenSSLConstantToCipherFamilyType(
|
||||
KnownOpenSSLCipherAlgorithmConstant e, Crypto::KeyOpAlg::TAlgorithm type
|
||||
predicate knownOpenSslConstantToCipherFamilyType(
|
||||
KnownOpenSslCipherAlgorithmExpr e, Crypto::KeyOpAlg::TAlgorithm type
|
||||
) {
|
||||
exists(string name |
|
||||
name = e.getNormalizedName() and
|
||||
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
|
||||
(
|
||||
name.matches("AES%") and type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::AES())
|
||||
or
|
||||
@@ -64,28 +64,29 @@ predicate knownOpenSSLConstantToCipherFamilyType(
|
||||
)
|
||||
}
|
||||
|
||||
class KnownOpenSSLCipherConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
|
||||
Crypto::KeyOperationAlgorithmInstance instanceof KnownOpenSSLCipherAlgorithmConstant
|
||||
class KnownOpenSslCipherConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
|
||||
Crypto::KeyOperationAlgorithmInstance instanceof KnownOpenSslCipherAlgorithmExpr
|
||||
{
|
||||
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 Literal and
|
||||
this instanceof OpenSslAlgorithmLiteral and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink |
|
||||
// Sink is an argument to a CipherGetterCall
|
||||
sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and
|
||||
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 DirectAlgorithmValueConsumer and getterCall = this
|
||||
this instanceof OpenSslAlgorithmCall and
|
||||
getterCall = this
|
||||
}
|
||||
|
||||
override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() {
|
||||
@@ -109,17 +110,17 @@ class KnownOpenSSLCipherConstantAlgorithmInstance extends OpenSSLAlgorithmInstan
|
||||
}
|
||||
|
||||
override int getKeySizeFixed() {
|
||||
this.(KnownOpenSSLCipherAlgorithmConstant).getExplicitKeySize() = result
|
||||
this.(KnownOpenSslCipherAlgorithmExpr).getExplicitKeySize() = result
|
||||
}
|
||||
|
||||
override Crypto::KeyOpAlg::Algorithm getAlgorithmType() {
|
||||
knownOpenSSLConstantToCipherFamilyType(this, result)
|
||||
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
|
||||
|
||||
@@ -6,31 +6,32 @@ private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgor
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
|
||||
private import AlgToAVCFlow
|
||||
|
||||
class KnownOpenSSLEllipticCurveConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
|
||||
Crypto::EllipticCurveInstance instanceof KnownOpenSSLEllipticCurveAlgorithmConstant
|
||||
class KnownOpenSslEllipticCurveConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
|
||||
Crypto::EllipticCurveInstance instanceof KnownOpenSslEllipticCurveAlgorithmExpr
|
||||
{
|
||||
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 Literal and
|
||||
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)
|
||||
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
|
||||
)
|
||||
or
|
||||
// Possibility 2:
|
||||
this instanceof DirectAlgorithmValueConsumer and getterCall = this
|
||||
this instanceof OpenSslAlgorithmCall and
|
||||
getterCall = this
|
||||
}
|
||||
|
||||
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
|
||||
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
|
||||
|
||||
override string getRawEllipticCurveName() {
|
||||
result = this.(Literal).getValue().toString()
|
||||
@@ -43,11 +44,11 @@ class KnownOpenSSLEllipticCurveConstantAlgorithmInstance extends OpenSSLAlgorith
|
||||
}
|
||||
|
||||
override string getParsedEllipticCurveName() {
|
||||
result = this.(KnownOpenSSLEllipticCurveAlgorithmConstant).getNormalizedName()
|
||||
result = this.(KnownOpenSslAlgorithmExpr).getNormalizedName()
|
||||
}
|
||||
|
||||
override int getKeySize() {
|
||||
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.(KnownOpenSSLEllipticCurveAlgorithmConstant)
|
||||
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.(KnownOpenSslAlgorithmExpr)
|
||||
.getNormalizedName(), result, _)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,11 +5,11 @@ private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgor
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
|
||||
private import AlgToAVCFlow
|
||||
|
||||
predicate knownOpenSSLConstantToHashFamilyType(
|
||||
KnownOpenSSLHashAlgorithmConstant e, Crypto::THashType type
|
||||
predicate knownOpenSslConstantToHashFamilyType(
|
||||
KnownOpenSslHashAlgorithmExpr e, Crypto::THashType type
|
||||
) {
|
||||
exists(string name |
|
||||
name = e.getNormalizedName() and
|
||||
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
|
||||
(
|
||||
name.matches("BLAKE2B") and type instanceof Crypto::BLAKE2B
|
||||
or
|
||||
@@ -29,7 +29,7 @@ predicate knownOpenSSLConstantToHashFamilyType(
|
||||
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
|
||||
@@ -44,36 +44,37 @@ predicate knownOpenSSLConstantToHashFamilyType(
|
||||
)
|
||||
}
|
||||
|
||||
class KnownOpenSSLHashConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
|
||||
Crypto::HashAlgorithmInstance instanceof KnownOpenSSLHashAlgorithmConstant
|
||||
class KnownOpenSslHashConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
|
||||
Crypto::HashAlgorithmInstance instanceof KnownOpenSslHashAlgorithmExpr
|
||||
{
|
||||
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 Literal and
|
||||
this instanceof OpenSslAlgorithmLiteral and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink |
|
||||
// Sink is an argument to a CipherGetterCall
|
||||
sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and
|
||||
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 DirectAlgorithmValueConsumer and getterCall = this
|
||||
this instanceof OpenSslAlgorithmCall 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() {
|
||||
@@ -83,6 +84,6 @@ class KnownOpenSSLHashConstantAlgorithmInstance extends OpenSSLAlgorithmInstance
|
||||
}
|
||||
|
||||
override int getFixedDigestLength() {
|
||||
this.(KnownOpenSSLHashAlgorithmConstant).getExplicitDigestLength() = result
|
||||
this.(KnownOpenSslHashAlgorithmExpr).getExplicitDigestLength() = result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,11 +5,11 @@ private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgor
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
|
||||
private import AlgToAVCFlow
|
||||
|
||||
predicate knownOpenSSLConstantToKeyAgreementFamilyType(
|
||||
KnownOpenSSLKeyAgreementAlgorithmConstant e, Crypto::TKeyAgreementType type
|
||||
predicate knownOpenSslConstantToKeyAgreementFamilyType(
|
||||
KnownOpenSslKeyAgreementAlgorithmExpr e, Crypto::TKeyAgreementType type
|
||||
) {
|
||||
exists(string name |
|
||||
name = e.getNormalizedName() and
|
||||
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
|
||||
(
|
||||
name = "ECDH" and type = Crypto::ECDH()
|
||||
or
|
||||
@@ -22,36 +22,37 @@ predicate knownOpenSSLConstantToKeyAgreementFamilyType(
|
||||
)
|
||||
}
|
||||
|
||||
class KnownOpenSSLHashConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
|
||||
Crypto::KeyAgreementAlgorithmInstance instanceof KnownOpenSSLKeyAgreementAlgorithmConstant
|
||||
class KnownOpenSslKeyAgreementConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
|
||||
Crypto::KeyAgreementAlgorithmInstance instanceof KnownOpenSslKeyAgreementAlgorithmExpr
|
||||
{
|
||||
OpenSSLAlgorithmValueConsumer getterCall;
|
||||
OpenSslAlgorithmValueConsumer getterCall;
|
||||
|
||||
KnownOpenSSLHashConstantAlgorithmInstance() {
|
||||
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
|
||||
// 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that
|
||||
// Possibility 1:
|
||||
this instanceof Literal and
|
||||
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)
|
||||
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
|
||||
)
|
||||
or
|
||||
// Possibility 2:
|
||||
this instanceof DirectAlgorithmValueConsumer and getterCall = this
|
||||
this instanceof OpenSslAlgorithmCall and
|
||||
getterCall = this
|
||||
}
|
||||
|
||||
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
|
||||
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
|
||||
|
||||
override Crypto::TKeyAgreementType getKeyAgreementType() {
|
||||
knownOpenSSLConstantToKeyAgreementFamilyType(this, result)
|
||||
knownOpenSslConstantToKeyAgreementFamilyType(this, result)
|
||||
or
|
||||
not knownOpenSSLConstantToKeyAgreementFamilyType(this, _) and
|
||||
not knownOpenSslConstantToKeyAgreementFamilyType(this, _) and
|
||||
result = Crypto::OtherKeyAgreementType()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,79 +1,44 @@
|
||||
import cpp
|
||||
import experimental.quantum.OpenSSL.GenericSourceCandidateLiteral
|
||||
|
||||
predicate resolveAlgorithmFromExpr(Expr e, string normalizedName, string algType) {
|
||||
resolveAlgorithmFromCall(e, normalizedName, algType)
|
||||
or
|
||||
resolveAlgorithmFromLiteral(e, normalizedName, algType)
|
||||
}
|
||||
|
||||
class KnownOpenSSLAlgorithmConstant extends Expr {
|
||||
KnownOpenSSLAlgorithmConstant() { resolveAlgorithmFromExpr(this, _, _) }
|
||||
|
||||
string getNormalizedName() { resolveAlgorithmFromExpr(this, result, _) }
|
||||
|
||||
string getAlgType() { resolveAlgorithmFromExpr(this, _, result) }
|
||||
}
|
||||
|
||||
class KnownOpenSSLCipherAlgorithmConstant extends KnownOpenSSLAlgorithmConstant {
|
||||
string algType;
|
||||
|
||||
KnownOpenSSLCipherAlgorithmConstant() {
|
||||
resolveAlgorithmFromExpr(this, _, algType) and
|
||||
algType.matches("%ENCRYPTION")
|
||||
}
|
||||
|
||||
int getExplicitKeySize() {
|
||||
exists(string name |
|
||||
name = this.getNormalizedName() and
|
||||
resolveAlgorithmFromExpr(this, name, algType) and
|
||||
result = name.regexpCapture(".*-(\\d*)", 1).toInt()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class KnownOpenSSLPaddingAlgorithmConstant extends KnownOpenSSLAlgorithmConstant {
|
||||
KnownOpenSSLPaddingAlgorithmConstant() {
|
||||
exists(string algType |
|
||||
resolveAlgorithmFromExpr(this, _, algType) and
|
||||
algType.matches("%PADDING")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class KnownOpenSSLBlockModeAlgorithmConstant extends KnownOpenSSLAlgorithmConstant {
|
||||
KnownOpenSSLBlockModeAlgorithmConstant() { resolveAlgorithmFromExpr(this, _, "BLOCK_MODE") }
|
||||
}
|
||||
|
||||
class KnownOpenSSLHashAlgorithmConstant extends KnownOpenSSLAlgorithmConstant {
|
||||
KnownOpenSSLHashAlgorithmConstant() { resolveAlgorithmFromExpr(this, _, "HASH") }
|
||||
|
||||
int getExplicitDigestLength() {
|
||||
exists(string name |
|
||||
name = this.getNormalizedName() and
|
||||
resolveAlgorithmFromExpr(this, name, "HASH") and
|
||||
result = name.regexpCapture(".*-(\\d*)$", 1).toInt()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class KnownOpenSSLEllipticCurveAlgorithmConstant extends KnownOpenSSLAlgorithmConstant {
|
||||
KnownOpenSSLEllipticCurveAlgorithmConstant() {
|
||||
resolveAlgorithmFromExpr(this, _, "ELLIPTIC_CURVE")
|
||||
}
|
||||
}
|
||||
|
||||
class KnownOpenSSLSignatureAlgorithmConstant extends KnownOpenSSLAlgorithmConstant {
|
||||
KnownOpenSSLSignatureAlgorithmConstant() { resolveAlgorithmFromExpr(this, _, "SIGNATURE") }
|
||||
}
|
||||
|
||||
class KnownOpenSSLKeyAgreementAlgorithmConstant extends KnownOpenSSLAlgorithmConstant {
|
||||
KnownOpenSSLKeyAgreementAlgorithmConstant() { resolveAlgorithmFromExpr(this, _, "KEY_AGREEMENT") }
|
||||
predicate resolveAlgorithmFromExpr(
|
||||
KnownOpenSslAlgorithmExpr e, string normalizedName, string algType
|
||||
) {
|
||||
normalizedName = e.getNormalizedName() and
|
||||
algType = e.getAlgType()
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a call to a 'direct algorithm getter', e.g., EVP_MD5()
|
||||
* This approach to fetching algorithms was used in OpenSSL 1.0.2.
|
||||
* 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();
|
||||
|
||||
abstract string getAlgType();
|
||||
}
|
||||
|
||||
class OpenSslAlgorithmLiteral extends KnownOpenSslAlgorithmExpr instanceof Literal {
|
||||
string normalizedName;
|
||||
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
|
||||
@@ -81,15 +46,134 @@ class KnownOpenSSLKeyAgreementAlgorithmConstant extends KnownOpenSSLAlgorithmCon
|
||||
* set of aliases. E.g., EVP_dss() and EVP_dss1() needed such mappings
|
||||
* alias = "dss" and target = "dsa"
|
||||
* or
|
||||
* alias = "dss1" and target = "dsaWithSHA1"
|
||||
* 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)
|
||||
)
|
||||
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
|
||||
algType.matches("%ENCRYPTION")
|
||||
}
|
||||
|
||||
int getExplicitKeySize() {
|
||||
exists(string name |
|
||||
name = this.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
|
||||
resolveAlgorithmFromExpr(this, name, algType) and
|
||||
result = name.regexpCapture(".*-(\\d*)", 1).toInt()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class KnownOpenSslPaddingAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr {
|
||||
KnownOpenSslPaddingAlgorithmExpr() {
|
||||
exists(string algType |
|
||||
resolveAlgorithmFromExpr(this, _, algType) and
|
||||
algType.matches("%PADDING")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class KnownOpenSslBlockModeAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr {
|
||||
KnownOpenSslBlockModeAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "BLOCK_MODE") }
|
||||
}
|
||||
|
||||
class KnownOpenSslHashAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr {
|
||||
KnownOpenSslHashAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "HASH") }
|
||||
|
||||
int getExplicitDigestLength() {
|
||||
exists(string name |
|
||||
name = this.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
|
||||
resolveAlgorithmFromExpr(this, name, "HASH") and
|
||||
result = name.regexpCapture(".*-(\\d*)$", 1).toInt()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class KnownOpenSslMacAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr {
|
||||
KnownOpenSslMacAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "MAC") }
|
||||
}
|
||||
|
||||
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 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"
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,13 +182,13 @@ predicate resolveAlgorithmFromCall(Call c, string normalized, string algType) {
|
||||
* 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)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -115,7 +199,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
|
||||
)
|
||||
}
|
||||
|
||||
@@ -138,9 +222,9 @@ predicate customAliases(string target, string alias) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@@ -247,7 +331,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) {
|
||||
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"
|
||||
@@ -886,6 +970,8 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized,
|
||||
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"
|
||||
@@ -1064,8 +1150,12 @@ 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"
|
||||
@@ -1140,10 +1230,14 @@ 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
|
||||
@@ -1153,6 +1247,8 @@ 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
|
||||
@@ -1167,6 +1263,8 @@ 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
|
||||
@@ -1178,6 +1276,8 @@ 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
|
||||
@@ -1187,6 +1287,8 @@ 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
|
||||
@@ -1226,6 +1328,11 @@ 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
|
||||
@@ -1278,6 +1385,11 @@ 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
|
||||
@@ -1291,11 +1403,13 @@ 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
|
||||
@@ -1304,22 +1418,42 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized,
|
||||
name = "id-tc26-hmac-gost-3411-2012-256" and
|
||||
nid = 988 and
|
||||
normalized = "GOST34112012" and
|
||||
algType = "SYMMETRIC_ENCRYPTION"
|
||||
algType = "HASH"
|
||||
or
|
||||
name = "id-tc26-hmac-gost-3411-2012-256" and
|
||||
nid = 988 and
|
||||
normalized = "HMAC" and
|
||||
algType = "MAC"
|
||||
or
|
||||
name = "id-tc26-hmac-gost-3411-2012-512" and
|
||||
nid = 989 and
|
||||
normalized = "GOST34112012" and
|
||||
algType = "SYMMETRIC_ENCRYPTION"
|
||||
algType = "HASH"
|
||||
or
|
||||
name = "id-tc26-hmac-gost-3411-2012-512" and
|
||||
nid = 989 and
|
||||
normalized = "HMAC" and
|
||||
algType = "MAC"
|
||||
or
|
||||
name = "id-tc26-agreement-gost-3410-2012-256" and
|
||||
nid = 992 and
|
||||
normalized = "GOST34102012" and
|
||||
algType = "SYMMETRIC_ENCRYPTION"
|
||||
algType = "ELLIPTIC_CURVE"
|
||||
or
|
||||
name = "id-tc26-agreement-gost-3410-2012-256" and
|
||||
nid = 992 and
|
||||
normalized = "GOST34102012" and
|
||||
algType = "KEY_AGREEMENT"
|
||||
or
|
||||
name = "id-tc26-agreement-gost-3410-2012-512" and
|
||||
nid = 993 and
|
||||
normalized = "GOST34102012" and
|
||||
algType = "SYMMETRIC_ENCRYPTION"
|
||||
algType = "ELLIPTIC_CURVE"
|
||||
or
|
||||
name = "id-tc26-agreement-gost-3410-2012-512" and
|
||||
nid = 993 and
|
||||
normalized = "GOST34102012" and
|
||||
algType = "KEY_AGREEMENT"
|
||||
or
|
||||
name = "id-tc26-gost-3410-2012-512-constants" and
|
||||
nid = 996 and
|
||||
@@ -1407,12 +1541,20 @@ 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"
|
||||
@@ -2180,34 +2322,67 @@ 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
|
||||
@@ -2457,12 +2632,20 @@ 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
|
||||
@@ -2818,93 +3001,93 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized,
|
||||
name = "ripemd160withrsa" and
|
||||
nid = 119 and
|
||||
normalized = "RSA" and
|
||||
algType = "ASYMMETRIC_ENCRYPTION"
|
||||
algType = "SIGNATURE"
|
||||
or
|
||||
name = "ripemd160withrsa" and nid = 119 and normalized = "RIPEMD160" and algType = "HASH"
|
||||
or
|
||||
name = "rsa-md2" and nid = 7 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
|
||||
name = "rsa-md2" and nid = 7 and normalized = "RSA" and algType = "SIGNATURE"
|
||||
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 = "ASYMMETRIC_ENCRYPTION"
|
||||
name = "rsa-md4" and nid = 396 and normalized = "RSA" and algType = "SIGNATURE"
|
||||
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 = "ASYMMETRIC_ENCRYPTION"
|
||||
name = "rsa-md5" and nid = 8 and normalized = "RSA" and algType = "SIGNATURE"
|
||||
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 = "ASYMMETRIC_ENCRYPTION"
|
||||
name = "rsa-mdc2" and nid = 96 and normalized = "RSA" and algType = "SIGNATURE"
|
||||
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 = "ASYMMETRIC_ENCRYPTION"
|
||||
name = "rsa-np-md5" and nid = 104 and normalized = "RSA" and algType = "SIGNATURE"
|
||||
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 = "ASYMMETRIC_ENCRYPTION"
|
||||
name = "rsa-ripemd160" and nid = 119 and normalized = "RSA" and algType = "SIGNATURE"
|
||||
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 = "ASYMMETRIC_ENCRYPTION"
|
||||
name = "rsa-sha" and nid = 42 and normalized = "RSA" and algType = "SIGNATURE"
|
||||
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 = "ASYMMETRIC_ENCRYPTION"
|
||||
name = "rsa-sha1" and nid = 65 and normalized = "RSA" and algType = "SIGNATURE"
|
||||
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 = "ASYMMETRIC_ENCRYPTION"
|
||||
name = "rsa-sha1-2" and nid = 115 and normalized = "RSA" and algType = "SIGNATURE"
|
||||
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 = "ASYMMETRIC_ENCRYPTION"
|
||||
name = "rsa-sha224" and nid = 671 and normalized = "RSA" and algType = "SIGNATURE"
|
||||
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 = "ASYMMETRIC_ENCRYPTION"
|
||||
name = "rsa-sha256" and nid = 668 and normalized = "RSA" and algType = "SIGNATURE"
|
||||
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 = "ASYMMETRIC_ENCRYPTION"
|
||||
name = "rsa-sha3-224" and nid = 1116 and normalized = "RSA" and algType = "SIGNATURE"
|
||||
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 = "ASYMMETRIC_ENCRYPTION"
|
||||
name = "rsa-sha3-256" and nid = 1117 and normalized = "RSA" and algType = "SIGNATURE"
|
||||
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 = "ASYMMETRIC_ENCRYPTION"
|
||||
name = "rsa-sha3-384" and nid = 1118 and normalized = "RSA" and algType = "SIGNATURE"
|
||||
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 = "ASYMMETRIC_ENCRYPTION"
|
||||
name = "rsa-sha3-512" and nid = 1119 and normalized = "RSA" and algType = "SIGNATURE"
|
||||
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 = "ASYMMETRIC_ENCRYPTION"
|
||||
name = "rsa-sha384" and nid = 669 and normalized = "RSA" and algType = "SIGNATURE"
|
||||
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 = "ASYMMETRIC_ENCRYPTION"
|
||||
name = "rsa-sha512" and nid = 670 and normalized = "RSA" and algType = "SIGNATURE"
|
||||
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 = "ASYMMETRIC_ENCRYPTION"
|
||||
algType = "SIGNATURE"
|
||||
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 = "ASYMMETRIC_ENCRYPTION"
|
||||
algType = "SIGNATURE"
|
||||
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 = "ASYMMETRIC_ENCRYPTION"
|
||||
name = "rsa-sm3" and nid = 1144 and normalized = "RSA" and algType = "SIGNATURE"
|
||||
or
|
||||
name = "rsa-sm3" and nid = 1144 and normalized = "SM3" and algType = "HASH"
|
||||
or
|
||||
@@ -2928,52 +3111,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 = "ASYMMETRIC_ENCRYPTION"
|
||||
name = "rsasignature" and nid = 377 and normalized = "RSA" and algType = "SIGNATURE"
|
||||
or
|
||||
name = "rsassa-pss" and nid = 912 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
|
||||
name = "rsassa-pss" and nid = 912 and normalized = "RSA" and algType = "SIGNATURE"
|
||||
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 = "ASYMMETRIC_ENCRYPTION"
|
||||
name = "rsassapss" and nid = 912 and normalized = "RSA" and algType = "SIGNATURE"
|
||||
or
|
||||
name = "rsassapss" and nid = 912 and normalized = "PSS" and algType = "ASYMMETRIC_PADDING"
|
||||
name = "rsassapss" and nid = 912 and normalized = "PSS" and algType = "SIGNATURE"
|
||||
or
|
||||
name = "sha1withrsa" and nid = 115 and normalized = "RSA" and algType = "ASYMMETRIC_ENCRYPTION"
|
||||
name = "sha1withrsa" and nid = 115 and normalized = "RSA" and algType = "SIGNATURE"
|
||||
or
|
||||
name = "sha1withrsa" and nid = 115 and normalized = "SHA1" and algType = "HASH"
|
||||
or
|
||||
name = "sha1withrsaencryption" and
|
||||
nid = 65 and
|
||||
normalized = "RSA" and
|
||||
algType = "ASYMMETRIC_ENCRYPTION"
|
||||
algType = "SIGNATURE"
|
||||
or
|
||||
name = "sha1withrsaencryption" and nid = 65 and normalized = "SHA1" and algType = "HASH"
|
||||
or
|
||||
name = "sha224withrsaencryption" and
|
||||
nid = 671 and
|
||||
normalized = "RSA" and
|
||||
algType = "ASYMMETRIC_ENCRYPTION"
|
||||
algType = "SIGNATURE"
|
||||
or
|
||||
name = "sha224withrsaencryption" and nid = 671 and normalized = "SHA-224" and algType = "HASH"
|
||||
or
|
||||
name = "sha256withrsaencryption" and
|
||||
nid = 668 and
|
||||
normalized = "RSA" and
|
||||
algType = "ASYMMETRIC_ENCRYPTION"
|
||||
algType = "SIGNATURE"
|
||||
or
|
||||
name = "sha256withrsaencryption" and nid = 668 and normalized = "SHA-256" and algType = "HASH"
|
||||
or
|
||||
name = "sha384withrsaencryption" and
|
||||
nid = 669 and
|
||||
normalized = "RSA" and
|
||||
algType = "ASYMMETRIC_ENCRYPTION"
|
||||
algType = "SIGNATURE"
|
||||
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 = "ASYMMETRIC_ENCRYPTION"
|
||||
algType = "SIGNATURE"
|
||||
or
|
||||
name = "sha512-224withrsaencryption" and
|
||||
nid = 1145 and
|
||||
@@ -2983,7 +3166,7 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized,
|
||||
name = "sha512-256withrsaencryption" and
|
||||
nid = 1146 and
|
||||
normalized = "RSA" and
|
||||
algType = "ASYMMETRIC_ENCRYPTION"
|
||||
algType = "SIGNATURE"
|
||||
or
|
||||
name = "sha512-256withrsaencryption" and
|
||||
nid = 1146 and
|
||||
@@ -2993,14 +3176,14 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized,
|
||||
name = "sha512withrsaencryption" and
|
||||
nid = 670 and
|
||||
normalized = "RSA" and
|
||||
algType = "ASYMMETRIC_ENCRYPTION"
|
||||
algType = "SIGNATURE"
|
||||
or
|
||||
name = "sha512withrsaencryption" and nid = 670 and normalized = "SHA-512" and algType = "HASH"
|
||||
or
|
||||
name = "shawithrsaencryption" and
|
||||
nid = 42 and
|
||||
normalized = "RSA" and
|
||||
algType = "ASYMMETRIC_ENCRYPTION"
|
||||
algType = "SIGNATURE"
|
||||
or
|
||||
name = "shawithrsaencryption" and nid = 42 and normalized = "SHA" and algType = "HASH"
|
||||
or
|
||||
@@ -3017,7 +3200,11 @@ predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized,
|
||||
name = "sm3withrsaencryption" and
|
||||
nid = 1144 and
|
||||
normalized = "RSA" and
|
||||
algType = "ASYMMETRIC_ENCRYPTION"
|
||||
algType = "SIGNATURE"
|
||||
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"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
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::TMACType getMacType() {
|
||||
this instanceof KnownOpenSslHMacAlgorithmExpr and result instanceof Crypto::THMAC
|
||||
or
|
||||
this instanceof KnownOpenSslCMacAlgorithmExpr and result instanceof Crypto::TCMAC
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -4,3 +4,5 @@ import PaddingAlgorithmInstance
|
||||
import BlockAlgorithmInstance
|
||||
import HashAlgorithmInstance
|
||||
import EllipticCurveAlgorithmInstance
|
||||
import SignatureAlgorithmInstance
|
||||
import MACAlgorithmInstance
|
||||
|
||||
@@ -17,21 +17,21 @@ private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgor
|
||||
* # 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 `KnownOpenSSLPaddingAlgorithmConstant`, converts this to a padding family type.
|
||||
* Given a `KnownOpenSslPaddingAlgorithmExpr`, converts this to a padding family type.
|
||||
* Does not bind if there is no mapping (no mapping to 'unknown' or 'other').
|
||||
*/
|
||||
predicate knownOpenSSLConstantToPaddingFamilyType(
|
||||
KnownOpenSSLPaddingAlgorithmConstant e, Crypto::TPaddingType type
|
||||
predicate knownOpenSslConstantToPaddingFamilyType(
|
||||
KnownOpenSslPaddingAlgorithmExpr e, Crypto::TPaddingType type
|
||||
) {
|
||||
exists(string name |
|
||||
name = e.getNormalizedName() and
|
||||
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
|
||||
(
|
||||
name.matches("OAEP") and type = Crypto::OAEP()
|
||||
or
|
||||
@@ -44,44 +44,44 @@ predicate knownOpenSSLConstantToPaddingFamilyType(
|
||||
)
|
||||
}
|
||||
|
||||
//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 Literal and
|
||||
this instanceof KnownOpenSSLPaddingAlgorithmConstant and
|
||||
this instanceof OpenSslAlgorithmLiteral and
|
||||
this instanceof KnownOpenSslPaddingAlgorithmExpr and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink |
|
||||
// Sink is an argument to a CipherGetterCall
|
||||
sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and
|
||||
sink = getterCall.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 DirectAlgorithmValueConsumer and
|
||||
this instanceof OpenSslAlgorithmCall and
|
||||
getterCall = this and
|
||||
this instanceof KnownOpenSSLPaddingAlgorithmConstant and
|
||||
this instanceof KnownOpenSslPaddingAlgorithmExpr 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.(OpenSSLAlgorithmValueConsumer).getInputNode() and
|
||||
sink = getterCall.getInputNode() and
|
||||
// Source is `this`
|
||||
src.asExpr() = this and
|
||||
// This traces to a padding-specific consumer
|
||||
@@ -96,7 +96,7 @@ class KnownOpenSSLPaddingConstantAlgorithmInstance extends OpenSSLAlgorithmInsta
|
||||
result = this.(Call).getTarget().getName()
|
||||
}
|
||||
|
||||
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
|
||||
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
|
||||
|
||||
Crypto::TPaddingType getKnownPaddingType() {
|
||||
this.(Literal).getValue().toInt() in [1, 7, 8] and result = Crypto::PKCS1_v1_5()
|
||||
@@ -119,7 +119,7 @@ class KnownOpenSSLPaddingConstantAlgorithmInstance extends OpenSSLAlgorithmInsta
|
||||
)
|
||||
or
|
||||
isPaddingSpecificConsumer = false and
|
||||
knownOpenSSLConstantToPaddingFamilyType(this, result)
|
||||
knownOpenSslConstantToPaddingFamilyType(this, result)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +127,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:
|
||||
@@ -162,7 +162,7 @@ class KnownOpenSSLPaddingConstantAlgorithmInstance extends OpenSSLAlgorithmInsta
|
||||
// }
|
||||
// }
|
||||
class OAEPPaddingAlgorithmInstance extends Crypto::OAEPPaddingAlgorithmInstance,
|
||||
KnownOpenSSLPaddingConstantAlgorithmInstance
|
||||
KnownOpenSslPaddingConstantAlgorithmInstance
|
||||
{
|
||||
OAEPPaddingAlgorithmInstance() {
|
||||
this.(Crypto::PaddingAlgorithmInstance).getPaddingType() = Crypto::OAEP()
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
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::Algorithm 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
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,26 +7,27 @@ private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgor
|
||||
* Cases like EVP_MD5(),
|
||||
* there is no input, rather it directly gets an algorithm
|
||||
* and returns it.
|
||||
* Also includes operations directly using an algorithm
|
||||
* like AES_encrypt().
|
||||
*/
|
||||
class DirectAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer {
|
||||
DataFlow::Node resultNode;
|
||||
Expr resultExpr;
|
||||
|
||||
DirectAlgorithmValueConsumer() {
|
||||
this instanceof KnownOpenSSLAlgorithmConstant and
|
||||
this instanceof Call and
|
||||
resultExpr = this and
|
||||
resultNode.asExpr() = resultExpr
|
||||
}
|
||||
|
||||
class DirectAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer instanceof OpenSslAlgorithmCall
|
||||
{
|
||||
/**
|
||||
* These cases take in no explicit value (the value is implicit)
|
||||
*/
|
||||
override Crypto::ConsumerInputDataFlowNode getInputNode() { none() }
|
||||
|
||||
override DataFlow::Node getResultNode() { result = resultNode }
|
||||
/**
|
||||
* Gets the DataFlow node represeting the output algorithm entity
|
||||
* created as a result of this call.
|
||||
*/
|
||||
override DataFlow::Node getResultNode() {
|
||||
this instanceof OpenSslDirectAlgorithmFetchCall and
|
||||
result.asExpr() = this
|
||||
// NOTE: if instanceof OpenSslDirectAlgorithmOperationCall then there is no algorithm generated
|
||||
// the algorithm is directly used
|
||||
}
|
||||
|
||||
// override DataFlow::Node getOutputNode() { result = resultNode }
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
// Note: algorithm source definitions enforces that
|
||||
// this class will be a known algorithm source
|
||||
|
||||
@@ -4,14 +4,14 @@ private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmCon
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances
|
||||
|
||||
abstract class EllipticCurveValueConsumer extends OpenSSLAlgorithmValueConsumer { }
|
||||
abstract class EllipticCurveValueConsumer extends OpenSslAlgorithmValueConsumer { }
|
||||
|
||||
//https://docs.openssl.org/3.0/man3/EC_KEY_new/#name
|
||||
class EVPEllipticCurveAlgorithmConsumer extends EllipticCurveValueConsumer {
|
||||
class EvpEllipticCurveAlgorithmConsumer extends EllipticCurveValueConsumer {
|
||||
DataFlow::Node valueArgNode;
|
||||
DataFlow::Node resultNode;
|
||||
|
||||
EVPEllipticCurveAlgorithmConsumer() {
|
||||
EvpEllipticCurveAlgorithmConsumer() {
|
||||
resultNode.asExpr() = this.(Call) and // in all cases the result is the return
|
||||
(
|
||||
this.(Call).getTarget().getName() in ["EVP_EC_gen", "EC_KEY_new_by_curve_name"] and
|
||||
@@ -25,7 +25,7 @@ class EVPEllipticCurveAlgorithmConsumer extends EllipticCurveValueConsumer {
|
||||
}
|
||||
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i)
|
||||
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
|
||||
}
|
||||
|
||||
override DataFlow::Node getResultNode() { result = resultNode }
|
||||
|
||||
@@ -4,20 +4,20 @@ private import semmle.code.cpp.dataflow.new.DataFlow
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances
|
||||
|
||||
abstract class HashAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { }
|
||||
abstract class HashAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer { }
|
||||
|
||||
/**
|
||||
* EVP_Q_Digest directly consumes algorithm constant values
|
||||
*/
|
||||
class EVP_Q_Digest_Algorithm_Consumer extends HashAlgorithmValueConsumer {
|
||||
EVP_Q_Digest_Algorithm_Consumer() { this.(Call).getTarget().getName() = "EVP_Q_digest" }
|
||||
class Evp_Q_Digest_Algorithm_Consumer extends HashAlgorithmValueConsumer {
|
||||
Evp_Q_Digest_Algorithm_Consumer() { this.(Call).getTarget().getName() = "EVP_Q_digest" }
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getInputNode() {
|
||||
result.asExpr() = this.(Call).getArgument(1)
|
||||
}
|
||||
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i)
|
||||
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
|
||||
}
|
||||
|
||||
override DataFlow::Node getResultNode() {
|
||||
@@ -27,15 +27,43 @@ class EVP_Q_Digest_Algorithm_Consumer extends HashAlgorithmValueConsumer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An instance from https://docs.openssl.org/3.0/man3/EVP_PKEY_CTX_ctrl/
|
||||
* where the digest is directly consumed by name.
|
||||
* In these cases, the operation is not yet performed, but there is
|
||||
* these functions are treated as 'initializers' and track the algorithm through
|
||||
* `EvpInitializer` mechanics, i.e., the resultNode is considered 'none'
|
||||
*/
|
||||
class EvpPkeySetCtxALgorithmConsumer extends HashAlgorithmValueConsumer {
|
||||
DataFlow::Node valueArgNode;
|
||||
|
||||
EvpPkeySetCtxALgorithmConsumer() {
|
||||
this.(Call).getTarget().getName() in [
|
||||
"EVP_PKEY_CTX_set_rsa_mgf1_md_name", "EVP_PKEY_CTX_set_rsa_oaep_md_name",
|
||||
"EVP_PKEY_CTX_set_dsa_paramgen_md_props"
|
||||
] and
|
||||
valueArgNode.asExpr() = this.(Call).getArgument(1)
|
||||
}
|
||||
|
||||
override DataFlow::Node getResultNode() { none() }
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode }
|
||||
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The EVP digest algorithm getters
|
||||
* https://docs.openssl.org/3.0/man3/EVP_DigestInit/#synopsis
|
||||
* https://docs.openssl.org/3.0/man3/EVP_DigestSignInit/#name
|
||||
*/
|
||||
class EVPDigestAlgorithmValueConsumer extends HashAlgorithmValueConsumer {
|
||||
class EvpDigestAlgorithmValueConsumer extends HashAlgorithmValueConsumer {
|
||||
DataFlow::Node valueArgNode;
|
||||
DataFlow::Node resultNode;
|
||||
|
||||
EVPDigestAlgorithmValueConsumer() {
|
||||
EvpDigestAlgorithmValueConsumer() {
|
||||
resultNode.asExpr() = this and
|
||||
(
|
||||
this.(Call).getTarget().getName() in [
|
||||
@@ -45,6 +73,9 @@ class EVPDigestAlgorithmValueConsumer extends HashAlgorithmValueConsumer {
|
||||
or
|
||||
this.(Call).getTarget().getName() = "EVP_MD_fetch" and
|
||||
valueArgNode.asExpr() = this.(Call).getArgument(1)
|
||||
or
|
||||
this.(Call).getTarget().getName() = "EVP_DigestSignInit_ex" and
|
||||
valueArgNode.asExpr() = this.(Call).getArgument(2)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -53,6 +84,6 @@ class EVPDigestAlgorithmValueConsumer extends HashAlgorithmValueConsumer {
|
||||
override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode }
|
||||
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i)
|
||||
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,13 +4,13 @@ private import semmle.code.cpp.dataflow.new.DataFlow
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances
|
||||
|
||||
abstract class KEMAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { }
|
||||
abstract class KemAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer { }
|
||||
|
||||
class EVPKEMAlgorithmValueConsumer extends KEMAlgorithmValueConsumer {
|
||||
class EvpKemAlgorithmValueConsumer extends KemAlgorithmValueConsumer {
|
||||
DataFlow::Node valueArgNode;
|
||||
DataFlow::Node resultNode;
|
||||
|
||||
EVPKEMAlgorithmValueConsumer() {
|
||||
EvpKemAlgorithmValueConsumer() {
|
||||
resultNode.asExpr() = this and
|
||||
(
|
||||
this.(Call).getTarget().getName() = "EVP_KEM_fetch" and
|
||||
@@ -23,6 +23,6 @@ class EVPKEMAlgorithmValueConsumer extends KEMAlgorithmValueConsumer {
|
||||
override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode }
|
||||
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i)
|
||||
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,13 +4,13 @@ private import semmle.code.cpp.dataflow.new.DataFlow
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances
|
||||
|
||||
abstract class KeyExchangeAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { }
|
||||
abstract class KeyExchangeAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer { }
|
||||
|
||||
class EVPKeyExchangeAlgorithmValueConsumer extends KeyExchangeAlgorithmValueConsumer {
|
||||
class EvpKeyExchangeAlgorithmValueConsumer extends KeyExchangeAlgorithmValueConsumer {
|
||||
DataFlow::Node valueArgNode;
|
||||
DataFlow::Node resultNode;
|
||||
|
||||
EVPKeyExchangeAlgorithmValueConsumer() {
|
||||
EvpKeyExchangeAlgorithmValueConsumer() {
|
||||
resultNode.asExpr() = this and
|
||||
(
|
||||
this.(Call).getTarget().getName() = "EVP_KEYEXCH_fetch" and
|
||||
@@ -23,6 +23,6 @@ class EVPKeyExchangeAlgorithmValueConsumer extends KeyExchangeAlgorithmValueCons
|
||||
override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode }
|
||||
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i)
|
||||
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
private import experimental.quantum.Language
|
||||
|
||||
abstract class OpenSSLAlgorithmValueConsumer extends Crypto::AlgorithmValueConsumer instanceof Call {
|
||||
abstract class OpenSslAlgorithmValueConsumer extends Crypto::AlgorithmValueConsumer instanceof Call {
|
||||
/**
|
||||
* Returns the node representing the resulting algorithm
|
||||
*/
|
||||
|
||||
@@ -5,3 +5,4 @@ import PaddingAlgorithmValueConsumer
|
||||
import HashAlgorithmValueConsumer
|
||||
import EllipticCurveAlgorithmValueConsumer
|
||||
import PKeyAlgorithmValueConsumer
|
||||
import SignatureAlgorithmValueConsumer
|
||||
|
||||
@@ -4,13 +4,13 @@ private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmCon
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances
|
||||
|
||||
abstract class PKeyValueConsumer extends OpenSSLAlgorithmValueConsumer { }
|
||||
abstract class PKeyValueConsumer extends OpenSslAlgorithmValueConsumer { }
|
||||
|
||||
class EVPPKeyAlgorithmConsumer extends PKeyValueConsumer {
|
||||
class EvpPKeyAlgorithmConsumer extends PKeyValueConsumer {
|
||||
DataFlow::Node valueArgNode;
|
||||
DataFlow::Node resultNode;
|
||||
|
||||
EVPPKeyAlgorithmConsumer() {
|
||||
EvpPKeyAlgorithmConsumer() {
|
||||
resultNode.asExpr() = this.(Call) and // in all cases the result is the return
|
||||
(
|
||||
// NOTE: some of these consumers are themselves key gen operations,
|
||||
@@ -23,7 +23,8 @@ class EVPPKeyAlgorithmConsumer extends PKeyValueConsumer {
|
||||
or
|
||||
this.(Call).getTarget().getName() in [
|
||||
"EVP_PKEY_CTX_new_from_name", "EVP_PKEY_new_raw_private_key_ex",
|
||||
"EVP_PKEY_new_raw_public_key_ex", "EVP_PKEY_CTX_ctrl", "EVP_PKEY_CTX_set_group_name"
|
||||
"EVP_PKEY_new_raw_public_key_ex", "EVP_PKEY_CTX_ctrl", "EVP_PKEY_CTX_ctrl_uint64",
|
||||
"EVP_PKEY_CTX_ctrl_str", "EVP_PKEY_CTX_set_group_name"
|
||||
] and
|
||||
valueArgNode.asExpr() = this.(Call).getArgument(1)
|
||||
or
|
||||
@@ -46,7 +47,7 @@ class EVPPKeyAlgorithmConsumer extends PKeyValueConsumer {
|
||||
}
|
||||
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i)
|
||||
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
|
||||
}
|
||||
|
||||
override DataFlow::Node getResultNode() { result = resultNode }
|
||||
|
||||
@@ -4,16 +4,16 @@ private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmCon
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
|
||||
private import OpenSSLAlgorithmValueConsumerBase
|
||||
|
||||
abstract class PaddingAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { }
|
||||
abstract class PaddingAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer { }
|
||||
|
||||
// https://docs.openssl.org/master/man7/EVP_ASYM_CIPHER-RSA/#rsa-asymmetric-cipher-parameters
|
||||
// TODO: need to handle setting padding through EVP_PKEY_CTX_set_params, where modes like "OSSL_PKEY_RSA_PAD_MODE_OAEP"
|
||||
// are set.
|
||||
class EVP_PKEY_CTX_set_rsa_padding_AlgorithmValueConsumer extends PaddingAlgorithmValueConsumer {
|
||||
class Evp_PKey_Ctx_set_rsa_padding_AlgorithmValueConsumer extends PaddingAlgorithmValueConsumer {
|
||||
DataFlow::Node valueArgNode;
|
||||
DataFlow::Node resultNode;
|
||||
|
||||
EVP_PKEY_CTX_set_rsa_padding_AlgorithmValueConsumer() {
|
||||
Evp_PKey_Ctx_set_rsa_padding_AlgorithmValueConsumer() {
|
||||
resultNode.asExpr() = this and
|
||||
this.(Call).getTarget().getName() = "EVP_PKEY_CTX_set_rsa_padding" and
|
||||
valueArgNode.asExpr() = this.(Call).getArgument(1)
|
||||
@@ -25,8 +25,8 @@ class EVP_PKEY_CTX_set_rsa_padding_AlgorithmValueConsumer extends PaddingAlgorit
|
||||
|
||||
// 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.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import cpp
|
||||
private import experimental.quantum.Language
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
|
||||
private import OpenSSLAlgorithmValueConsumerBase
|
||||
private import experimental.quantum.OpenSSL.LibraryDetector
|
||||
|
||||
abstract class SignatureAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer { }
|
||||
|
||||
class EvpSignatureAlgorithmValueConsumer extends SignatureAlgorithmValueConsumer {
|
||||
DataFlow::Node valueArgNode;
|
||||
DataFlow::Node resultNode;
|
||||
|
||||
EvpSignatureAlgorithmValueConsumer() {
|
||||
resultNode.asExpr() = this and
|
||||
(
|
||||
// EVP_SIGNATURE
|
||||
this.(Call).getTarget().getName() = "EVP_SIGNATURE_fetch" and
|
||||
valueArgNode.asExpr() = this.(Call).getArgument(1)
|
||||
// EVP_PKEY_get1_DSA, EVP_PKEY_get1_RSA
|
||||
// DSA_SIG_new, DSA_SIG_get0, RSA_sign ?
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getResultNode() { result = resultNode }
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode }
|
||||
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
|
||||
}
|
||||
}
|
||||
19
cpp/ql/lib/experimental/quantum/OpenSSL/AvcFlow.qll
Normal file
19
cpp/ql/lib/experimental/quantum/OpenSSL/AvcFlow.qll
Normal file
@@ -0,0 +1,19 @@
|
||||
import semmle.code.cpp.dataflow.new.DataFlow
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
|
||||
|
||||
/**
|
||||
* Flows from algorithm values to operations, specific to OpenSsl
|
||||
*/
|
||||
module AvcToCallArgConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
exists(OpenSslAlgorithmValueConsumer c | c.getResultNode() = source)
|
||||
}
|
||||
|
||||
/**
|
||||
* Trace to any call accepting the algorithm.
|
||||
* NOTE: users must restrict this set to the operations they are interested in.
|
||||
*/
|
||||
predicate isSink(DataFlow::Node sink) { exists(Call c | c.getAnArgument() = sink.asExpr()) }
|
||||
}
|
||||
|
||||
module AvcToCallArgFlow = DataFlow::Global<AvcToCallArgConfig>;
|
||||
@@ -28,7 +28,7 @@ import semmle.code.cpp.dataflow.new.DataFlow
|
||||
* - EVP_MD_CTX
|
||||
* - EVP_PKEY_CTX
|
||||
*/
|
||||
private class CtxType extends Type {
|
||||
class CtxType extends Type {
|
||||
CtxType() {
|
||||
// It is possible for users to use the underlying type of the CTX variables
|
||||
// these have a name matching 'evp_%ctx_%st
|
||||
@@ -47,7 +47,7 @@ private class CtxType extends Type {
|
||||
/**
|
||||
* A pointer to a CtxType
|
||||
*/
|
||||
private class CtxPointerExpr extends Expr {
|
||||
class CtxPointerExpr extends Expr {
|
||||
CtxPointerExpr() {
|
||||
this.getType() instanceof CtxType and
|
||||
this.getType() instanceof PointerType
|
||||
@@ -57,12 +57,19 @@ private class CtxPointerExpr extends Expr {
|
||||
/**
|
||||
* A call argument of type CtxPointerExpr.
|
||||
*/
|
||||
private class CtxPointerArgument extends CtxPointerExpr {
|
||||
class CtxPointerArgument extends CtxPointerExpr {
|
||||
CtxPointerArgument() { exists(Call c | c.getAnArgument() = this) }
|
||||
|
||||
Call getCall() { result.getAnArgument() = this }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call returning a CtxPointerExpr.
|
||||
*/
|
||||
private class CtxPointerReturn extends CtxPointerExpr instanceof Call {
|
||||
Call getCall() { result = this }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call whose target contains 'free' or 'reset' and has an argument of type
|
||||
* CtxPointerArgument.
|
||||
@@ -74,66 +81,141 @@ private class CtxClearCall extends Call {
|
||||
}
|
||||
}
|
||||
|
||||
abstract private class CtxPassThroughCall extends Call {
|
||||
abstract DataFlow::Node getNode1();
|
||||
|
||||
abstract DataFlow::Node getNode2();
|
||||
}
|
||||
|
||||
/**
|
||||
* A call whose target contains 'copy' and has an argument of type
|
||||
* CtxPointerArgument.
|
||||
*/
|
||||
private class CtxCopyOutArgCall extends Call {
|
||||
private class CtxCopyOutArgCall extends CtxPassThroughCall {
|
||||
DataFlow::Node n1;
|
||||
DataFlow::Node n2;
|
||||
|
||||
CtxCopyOutArgCall() {
|
||||
this.getTarget().getName().toLowerCase().matches("%copy%") and
|
||||
this.getAnArgument() instanceof CtxPointerArgument
|
||||
n1.asExpr() = this.getAnArgument() and
|
||||
n1.getType() instanceof CtxType and
|
||||
n2.asDefiningArgument() = this.getAnArgument() and
|
||||
n2.getType() instanceof CtxType and
|
||||
n1.asDefiningArgument() != n2.asExpr()
|
||||
}
|
||||
|
||||
override DataFlow::Node getNode1() { result = n1 }
|
||||
|
||||
override DataFlow::Node getNode2() { result = n2 }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call whose target contains 'dup' and has an argument of type
|
||||
* CtxPointerArgument.
|
||||
*/
|
||||
private class CtxCopyReturnCall extends Call, CtxPointerExpr {
|
||||
private class CtxCopyReturnCall extends CtxPassThroughCall, CtxPointerExpr {
|
||||
DataFlow::Node n1;
|
||||
|
||||
CtxCopyReturnCall() {
|
||||
this.getTarget().getName().toLowerCase().matches("%dup%") and
|
||||
this.getAnArgument() instanceof CtxPointerArgument
|
||||
n1.asExpr() = this.getAnArgument() and
|
||||
n1.getType() instanceof CtxType
|
||||
}
|
||||
|
||||
override DataFlow::Node getNode1() { result = n1 }
|
||||
|
||||
override DataFlow::Node getNode2() { result.asExpr() = this }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `EVP_PKEY_paramgen` acts as a kind of pass through.
|
||||
* It's output pkey is eventually used in a new operation generating
|
||||
* a fresh context pointer (e.g., `EVP_PKEY_CTX_new`).
|
||||
* It is easier to model this as a pass through
|
||||
* than to model the flow from the paramgen to the new key generation.
|
||||
*/
|
||||
private class CtxParamGenCall extends CtxPassThroughCall {
|
||||
DataFlow::Node n1;
|
||||
DataFlow::Node n2;
|
||||
|
||||
CtxParamGenCall() {
|
||||
this.getTarget().getName() = "EVP_PKEY_paramgen" and
|
||||
n1.asExpr() = this.getArgument(0) and
|
||||
(
|
||||
n2.asExpr() = this.getArgument(1)
|
||||
or
|
||||
n2.asDefiningArgument() = this.getArgument(1)
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getNode1() { result = n1 }
|
||||
|
||||
override DataFlow::Node getNode2() { result = n2 }
|
||||
}
|
||||
|
||||
/**
|
||||
* If the current node gets is an argument to a function
|
||||
* that returns a pointer type, immediately flow through.
|
||||
* NOTE: this passthrough is required if we allow
|
||||
* intermediate steps to go into variables that are not a CTX type.
|
||||
* See for example `CtxParamGenCall`.
|
||||
*/
|
||||
private class CallArgToCtxRet extends CtxPassThroughCall, CtxPointerExpr {
|
||||
DataFlow::Node n1;
|
||||
DataFlow::Node n2;
|
||||
|
||||
CallArgToCtxRet() {
|
||||
this.getAnArgument() = n1.asExpr() and
|
||||
n2.asExpr() = this
|
||||
}
|
||||
|
||||
override DataFlow::Node getNode1() { result = n1 }
|
||||
|
||||
override DataFlow::Node getNode2() { result = n2 }
|
||||
}
|
||||
|
||||
/**
|
||||
* A source Ctx of interest is any argument or return of type CtxPointerExpr.
|
||||
*/
|
||||
class CtxPointerSource extends CtxPointerExpr {
|
||||
CtxPointerSource() {
|
||||
this instanceof CtxPointerReturn or
|
||||
this instanceof CtxPointerArgument
|
||||
}
|
||||
|
||||
DataFlow::Node asNode() {
|
||||
result.asExpr() = this
|
||||
or
|
||||
result.asDefiningArgument() = this
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flow from any CtxPointerArgument to any other CtxPointerArgument
|
||||
* Flow from any CtxPointerSource to other CtxPointerSource.
|
||||
*/
|
||||
module OpenSSLCtxArgumentFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source.asExpr() instanceof CtxPointerArgument }
|
||||
module OpenSslCtxSourceToSourceFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { exists(CtxPointerSource s | s.asNode() = source) }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof CtxPointerArgument }
|
||||
predicate isSink(DataFlow::Node sink) { exists(CtxPointerSource s | s.asNode() = sink) }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
exists(CtxClearCall c | c.getAnArgument() = node.asExpr())
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(CtxCopyOutArgCall c |
|
||||
c.getAnArgument() = node1.asExpr() and
|
||||
c.getAnArgument() = node2.asExpr() and
|
||||
node1.asExpr() != node2.asExpr() and
|
||||
node2.asExpr().getType() instanceof CtxType
|
||||
)
|
||||
or
|
||||
exists(CtxCopyReturnCall c |
|
||||
c.getAnArgument() = node1.asExpr() and
|
||||
c = node2.asExpr() and
|
||||
node1.asExpr() != node2.asExpr() and
|
||||
node2.asExpr().getType() instanceof CtxType
|
||||
)
|
||||
exists(CtxPassThroughCall c | c.getNode1() = node1 and c.getNode2() = node2)
|
||||
}
|
||||
}
|
||||
|
||||
module OpenSSLCtxArgumentFlow = DataFlow::Global<OpenSSLCtxArgumentFlowConfig>;
|
||||
module OpenSslCtxSourceToArgumentFlow = DataFlow::Global<OpenSslCtxSourceToSourceFlowConfig>;
|
||||
|
||||
/**
|
||||
* Holds if there is a context flow from the source to the sink.
|
||||
*/
|
||||
predicate ctxArgFlowsToCtxArg(CtxPointerArgument source, CtxPointerArgument sink) {
|
||||
predicate ctxSrcToSrcFlow(CtxPointerSource source, CtxPointerSource sink) {
|
||||
exists(DataFlow::Node a, DataFlow::Node b |
|
||||
OpenSSLCtxArgumentFlow::flow(a, b) and
|
||||
a.asExpr() = source and
|
||||
b.asExpr() = sink
|
||||
OpenSslCtxSourceToArgumentFlow::flow(a, b) and
|
||||
a = source.asNode() and
|
||||
b = sink.asNode()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -14,9 +14,9 @@ private class IntLiteral extends Literal {
|
||||
/**
|
||||
* Holds if a StringLiteral could conceivably be used in some way for cryptography.
|
||||
* Note: this predicate should only consider restrictions with respect to strings only.
|
||||
* General restrictions are in the OpenSSLGenericSourceCandidateLiteral class.
|
||||
* General restrictions are in the OpenSslGenericSourceCandidateLiteral class.
|
||||
*/
|
||||
private predicate isOpenSSLStringLiteralGenericSourceCandidate(StringLiteral s) {
|
||||
private predicate isOpenSslStringLiteralGenericSourceCandidate(StringLiteral s) {
|
||||
// 'EC' is a constant that may be used where typical algorithms are specified,
|
||||
// but EC specifically means set up a default curve container, that will later be
|
||||
//specified explicitly (or if not a default) curve is used.
|
||||
@@ -49,9 +49,9 @@ private predicate isOpenSSLStringLiteralGenericSourceCandidate(StringLiteral s)
|
||||
/**
|
||||
* Holds if a StringLiteral could conceivably be used in some way for cryptography.
|
||||
* Note: this predicate should only consider restrictions with respect to integers only.
|
||||
* General restrictions are in the OpenSSLGenericSourceCandidateLiteral class.
|
||||
* General restrictions are in the OpenSslGenericSourceCandidateLiteral class.
|
||||
*/
|
||||
private predicate isOpenSSLIntLiteralGenericSourceCandidate(IntLiteral l) {
|
||||
private predicate isOpenSslIntLiteralGenericSourceCandidate(IntLiteral l) {
|
||||
// Ignore integer values of 0, commonly referring to NULL only (no known algorithm 0)
|
||||
l.getValue().toInt() != 0 and
|
||||
// ASSUMPTION, no negative numbers are allowed
|
||||
@@ -102,11 +102,11 @@ private predicate isOpenSSLIntLiteralGenericSourceCandidate(IntLiteral l) {
|
||||
* "AES" may be a legitimate algorithm literal, but the literal will not be used for an operation directly
|
||||
* since it is in a equality comparison, hence this case would also be filtered.
|
||||
*/
|
||||
class OpenSSLGenericSourceCandidateLiteral extends Literal {
|
||||
OpenSSLGenericSourceCandidateLiteral() {
|
||||
class OpenSslGenericSourceCandidateLiteral extends Literal {
|
||||
OpenSslGenericSourceCandidateLiteral() {
|
||||
(
|
||||
isOpenSSLIntLiteralGenericSourceCandidate(this) or
|
||||
isOpenSSLStringLiteralGenericSourceCandidate(this)
|
||||
isOpenSslIntLiteralGenericSourceCandidate(this) or
|
||||
isOpenSslStringLiteralGenericSourceCandidate(this)
|
||||
) and
|
||||
// ********* General filters beyond what is filtered for strings and ints *********
|
||||
// An algorithm literal in a switch case will not be directly applied to an operation.
|
||||
|
||||
27
cpp/ql/lib/experimental/quantum/OpenSSL/KeyFlow.qll
Normal file
27
cpp/ql/lib/experimental/quantum/OpenSSL/KeyFlow.qll
Normal file
@@ -0,0 +1,27 @@
|
||||
import semmle.code.cpp.dataflow.new.DataFlow
|
||||
private import Operations.OpenSSLOperations
|
||||
private import experimental.quantum.Language
|
||||
|
||||
/**
|
||||
* Flow from key creation to key used in a call
|
||||
*/
|
||||
module OpenSslKeyFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
// NOTE/ASSUMPTION: it is assumed the operation is also an OpenSslOperation.
|
||||
// All operations modeled for openssl should be modeled as OpenSslOperation.
|
||||
exists(Crypto::KeyCreationOperationInstance keygen | keygen.getOutputKeyArtifact() = source)
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { exists(Call call | call.getAnArgument() = sink.asExpr()) }
|
||||
//TODO: consideration for additional flow steps? Can a key be copied for example?
|
||||
}
|
||||
|
||||
module OpenSslKeyFlow = TaintTracking::Global<OpenSslKeyFlowConfig>;
|
||||
|
||||
Crypto::KeyCreationOperationInstance getSourceKeyCreationInstanceFromArg(Expr arg) {
|
||||
exists(DataFlow::Node src, DataFlow::Node sink |
|
||||
OpenSslKeyFlow::flow(src, sink) and
|
||||
result.getOutputKeyArtifact() = src and
|
||||
sink.asExpr() = arg
|
||||
)
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import cpp
|
||||
|
||||
predicate isPossibleOpenSSLFunction(Function f) {
|
||||
isPossibleOpenSSLLocation(f.getADeclarationLocation())
|
||||
predicate isPossibleOpenSslFunction(Function f) {
|
||||
isPossibleOpenSslLocation(f.getADeclarationLocation())
|
||||
}
|
||||
|
||||
predicate isPossibleOpenSSLLocation(Location l) { l.toString().toLowerCase().matches("%openssl%") }
|
||||
predicate isPossibleOpenSslLocation(Location l) { l.toString().toLowerCase().matches("%openssl%") }
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user