Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 65c8d96

Browse files
committed
Python: Add CryptographicOperation Concept
I considered using `getInput` like in JS, but things like signature verification has multiple inputs (message and signature). Using getAnInput also aligns better with Decoding/Encoding.
1 parent d18fbb7 commit 65c8d96

2 files changed

Lines changed: 77 additions & 1 deletion

File tree

python/ql/src/semmle/python/Concepts.qll

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,14 @@ module HTTP {
527527
}
528528
}
529529

530-
/** Provides models for cryptographic things. */
530+
/**
531+
* Provides models for cryptographic things.
532+
*
533+
* Note: The `CryptographicAlgorithm` class currently doesn't take weak keys into
534+
* consideration for the `isWeak` member predicate. So RSA is always considered
535+
* secure, although using a low number of bits will actually make it insecure. We plan
536+
* to improve our libraries in the future to more precisely capture this aspect.
537+
*/
531538
module Cryptography {
532539
/** Provides models for public-key cryptography, also called asymmetric cryptography. */
533540
module PublicKey {
@@ -626,4 +633,43 @@ module Cryptography {
626633
}
627634
}
628635
}
636+
637+
import semmle.crypto.Crypto
638+
639+
/**
640+
* A data-flow node that is an application of a cryptographic algorithm. For example,
641+
* encryption, decryption, signature-validation.
642+
*
643+
* Extend this class to refine existing API models. If you want to model new APIs,
644+
* extend `CryptographicOperation::Range` instead.
645+
*/
646+
class CryptographicOperation extends DataFlow::Node {
647+
CryptographicOperation::Range range;
648+
649+
CryptographicOperation() { this = range }
650+
651+
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
652+
CryptographicAlgorithm getAlgorithm() { result = range.getAlgorithm() }
653+
654+
/** Gets an input the algorithm is used on, for example the plain text input to be encrypted. */
655+
DataFlow::Node getAnInput() { result = range.getAnInput() }
656+
}
657+
658+
/** Provides classes for modeling new applications of a cryptographic algorithms. */
659+
module CryptographicOperation {
660+
/**
661+
* A data-flow node that is an application of a cryptographic algorithm. For example,
662+
* encryption, decryption, signature-validation.
663+
*
664+
* Extend this class to model new APIs. If you want to refine existing API models,
665+
* extend `CryptographicOperation` instead.
666+
*/
667+
abstract class Range extends DataFlow::Node {
668+
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
669+
abstract CryptographicAlgorithm getAlgorithm();
670+
671+
/** Gets an input the algorithm is used on, for example the plain text input to be encrypted. */
672+
abstract DataFlow::Node getAnInput();
673+
}
674+
}
629675
}

python/ql/test/experimental/meta/ConceptsTest.qll

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,3 +341,33 @@ class PublicKeyGenerationTest extends InlineExpectationsTest {
341341
)
342342
}
343343
}
344+
345+
class CryptographicOperationTest extends InlineExpectationsTest {
346+
CryptographicOperationTest() { this = "CryptographicOperationTest" }
347+
348+
override string getARelevantTag() {
349+
result in [
350+
"CryptographicOperation", "CryptographicOperationInput", "CryptographicOperationAlgorithm"
351+
]
352+
}
353+
354+
override predicate hasActualResult(Location location, string element, string tag, string value) {
355+
exists(location.getFile().getRelativePath()) and
356+
exists(Cryptography::CryptographicOperation cryptoOperation |
357+
location = cryptoOperation.getLocation() and
358+
(
359+
element = cryptoOperation.toString() and
360+
value = "" and
361+
tag = "CryptographicOperation"
362+
or
363+
element = cryptoOperation.toString() and
364+
value = value_from_expr(cryptoOperation.getAnInput().asExpr()) and
365+
tag = "CryptographicOperationInput"
366+
or
367+
element = cryptoOperation.toString() and
368+
value = cryptoOperation.getAlgorithm().getName() and
369+
tag = "CryptographicOperationAlgorithm"
370+
)
371+
)
372+
}
373+
}

0 commit comments

Comments
 (0)