Skip to content

Commit 46bb247

Browse files
committed
ruby: add BlockMode concept
1 parent d531631 commit 46bb247

3 files changed

Lines changed: 36 additions & 13 deletions

File tree

ruby/ql/lib/codeql/ruby/Concepts.qll

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,13 @@ module Cryptography {
844844

845845
/** Holds if this encryption operation is known to be weak. */
846846
predicate isWeak() { super.isWeak() }
847+
848+
/**
849+
* Gets the block mode used to perform this cryptographic operation.
850+
* This may have no result - for example if the `CryptographicAlgorithm` used
851+
* is a stream cipher rather than a block cipher.
852+
*/
853+
BlockMode getBlockMode() { result = super.getBlockMode() }
847854
}
848855

849856
/** Provides classes for modeling new applications of a cryptographic algorithms. */
@@ -864,6 +871,24 @@ module Cryptography {
864871

865872
/** Holds if this encryption operation is known to be weak. */
866873
abstract predicate isWeak();
874+
875+
/**
876+
* Gets the block mode used to perform this cryptographic operation.
877+
* This may have no result - for example if the `CryptographicAlgorithm` used
878+
* is a stream cipher rather than a block cipher.
879+
*/
880+
abstract BlockMode getBlockMode();
867881
}
868882
}
883+
884+
/**
885+
* A cryptographic block cipher mode of operation. This can be used to encrypt
886+
* data of arbitrary length using a block encryption algorithm.
887+
*/
888+
class BlockMode extends string {
889+
BlockMode() { this = ["ECB", "CBC", "GCM", "CCM", "CFB", "OFB", "CTR"] }
890+
891+
/** Holds if this block mode is considered to be insecure. */
892+
predicate isWeak() { this = "ECB" }
893+
}
869894
}

ruby/ql/lib/codeql/ruby/security/OpenSSL.qll

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ private string rankedInsecureAlgorithm(int i) {
2929
// weak hash algorithms and block modes as well.
3030
result =
3131
rank[i](string s |
32-
isWeakEncryptionAlgorithm(s) or isWeakHashingAlgorithm(s) or isWeakBlockMode(s)
32+
isWeakEncryptionAlgorithm(s) or
33+
isWeakHashingAlgorithm(s) or
34+
s.(Cryptography::BlockMode).isWeak()
3335
)
3436
}
3537

@@ -329,21 +331,18 @@ private API::Node cipherApi() {
329331
result = API::getTopLevelMember("OpenSSL").getMember("Cipher").getMember("Cipher")
330332
}
331333

332-
private class BlockMode extends string {
333-
BlockMode() { this = ["ECB", "CBC", "GCM", "CCM", "CFB", "OFB", "CTR"] }
334-
}
335-
336334
private newtype TCipherMode =
337335
TStreamCipher() or
338-
TBlockMode(BlockMode blockMode)
336+
TBlockMode(Cryptography::BlockMode blockMode)
339337

340338
/**
341339
* Represents the mode used by this stream cipher.
342340
* If this cipher uses a block encryption algorithm, then this is a specific
343341
* block mode.
344342
*/
345343
private class CipherMode extends TCipherMode {
346-
private BlockMode getBlockMode() { this = TBlockMode(result) }
344+
/** Gets the underlying block mode, if any. */
345+
Cryptography::BlockMode getBlockMode() { this = TBlockMode(result) }
347346

348347
/** Gets a textual representation of this node. */
349348
string toString() {
@@ -360,7 +359,7 @@ private class CipherMode extends TCipherMode {
360359
predicate isBlockMode(string s) { this.getBlockMode() = s.toUpperCase() }
361360

362361
/** Holds if this cipher mode is a weak block mode. */
363-
predicate isWeak() { isWeakBlockMode(this.getBlockMode()) }
362+
predicate isWeak() { this.getBlockMode().isWeak() }
364363
}
365364

366365
private string getStringArgument(DataFlow::CallNode call, int i) {
@@ -549,4 +548,8 @@ private class CipherOperation extends Cryptography::CryptographicOperation::Rang
549548
cipherNode.getCipher().isWeak() or
550549
cipherNode.getCipherMode().isWeak()
551550
}
551+
552+
override Cryptography::BlockMode getBlockMode() {
553+
result = cipherNode.getCipherMode().getBlockMode()
554+
}
552555
}

ruby/ql/lib/codeql/ruby/security/internal/CryptoAlgorithmNames.qll

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,3 @@ predicate isStrongPasswordHashingAlgorithm(string name) {
6565
* Holds if `name` corresponds to a weak password hashing algorithm.
6666
*/
6767
predicate isWeakPasswordHashingAlgorithm(string name) { name = "EVPKDF" }
68-
69-
/**
70-
* Holds if `name` corresponds to a weak block cipher mode of operation.
71-
*/
72-
predicate isWeakBlockMode(string name) { name = "ECB" }

0 commit comments

Comments
 (0)