@@ -26,6 +26,7 @@ class SymmetricSource extends InsufficientKeySizeSource {
2626 SymmetricSource ( ) { getNodeIntValue ( this ) < 128 }
2727}
2828
29+ // TODO: use `typeFlag` like with sinks below to include the size numbers in this predicate?
2930private int getNodeIntValue ( DataFlow:: Node node ) {
3031 result = node .asExpr ( ) .( IntegerLiteral ) .getIntValue ( )
3132}
@@ -43,19 +44,13 @@ private int getECKeySize(string algorithm) {
4344 result = algorithm .regexpCapture ( ".*[a-zA-Z](\\d+)[a-zA-Z].*" , 1 ) .toInt ( )
4445}
4546
47+ // TODO: Consider if below 3 sinks should be private and if it's possible to only use InsufficientKeySizeSink in the configs
48+ // TODO: add QLDocs if keeping non-private
4649class AsymmetricNonECSink extends InsufficientKeySizeSink {
4750 AsymmetricNonECSink ( ) {
48- exists ( MethodAccess ma , JavaSecurityKeyPairGenerator jpg |
49- ma .getMethod ( ) instanceof KeyPairGeneratorInitMethod and
50- jpg .getAlgoSpec ( ) .( StringLiteral ) .getValue ( ) .toUpperCase ( ) .matches ( [ "RSA" , "DSA" , "DH" ] ) and
51- DataFlow:: localExprFlow ( jpg , ma .getQualifier ( ) ) and
52- this .asExpr ( ) = ma .getArgument ( 0 )
53- )
51+ hasKeySizeInInitMethod ( this , "asymmetric-non-ec" )
5452 or
55- exists ( ClassInstanceExpr genParamSpec |
56- genParamSpec .getConstructedType ( ) instanceof AsymmetricNonECSpec and
57- this .asExpr ( ) = genParamSpec .getArgument ( 0 )
58- )
53+ hasKeySizeInSpec ( this , "asymmetric-non-ec" )
5954 }
6055}
6156
@@ -70,31 +65,60 @@ private class AsymmetricNonECSpec extends RefType {
7065
7166class AsymmetricECSink extends InsufficientKeySizeSink {
7267 AsymmetricECSink ( ) {
73- exists ( MethodAccess ma , JavaSecurityKeyPairGenerator jpg |
74- ma .getMethod ( ) instanceof KeyPairGeneratorInitMethod and
75- jpg .getAlgoSpec ( ) .( StringLiteral ) .getValue ( ) .toUpperCase ( ) .matches ( "EC%" ) and
76- DataFlow:: localExprFlow ( jpg , ma .getQualifier ( ) ) and
77- this .asExpr ( ) = ma .getArgument ( 0 )
78- )
68+ hasKeySizeInInitMethod ( this , "asymmetric-ec" )
7969 or
80- exists ( ClassInstanceExpr ecGenParamSpec |
81- ecGenParamSpec .getConstructedType ( ) instanceof EcGenParameterSpec and
82- this .asExpr ( ) = ecGenParamSpec .getArgument ( 0 )
83- )
70+ hasKeySizeInSpec ( this , "asymmetric-ec" )
8471 }
8572}
8673
8774class SymmetricSink extends InsufficientKeySizeSink {
88- SymmetricSink ( ) {
89- exists ( MethodAccess ma , JavaxCryptoKeyGenerator jcg |
90- ma .getMethod ( ) instanceof KeyGeneratorInitMethod and
91- jcg .getAlgoSpec ( ) .( StringLiteral ) .getValue ( ) .toUpperCase ( ) = "AES" and
92- DataFlow:: localExprFlow ( jcg , ma .getQualifier ( ) ) and
93- this .asExpr ( ) = ma .getArgument ( 0 )
94- )
95- }
75+ SymmetricSink ( ) { hasKeySizeInInitMethod ( this , "symmetric" ) }
76+ }
77+
78+ // TODO: rethink the predicate name; also think about whether this could/should be a class instead; or a predicate within the sink class so can do sink.predicate()...
79+ // TODO: can prbly re-work way using the typeFlag to be better and less repetitive
80+ private predicate hasKeySizeInInitMethod ( DataFlow:: Node node , string typeFlag ) {
81+ exists ( MethodAccess ma , JavaxCryptoAlgoSpec jcaSpec |
82+ (
83+ ma .getMethod ( ) instanceof KeyGeneratorInitMethod and typeFlag = "symmetric"
84+ or
85+ ma .getMethod ( ) instanceof KeyPairGeneratorInitMethod and typeFlag .matches ( "asymmetric%" )
86+ ) and
87+ (
88+ jcaSpec instanceof JavaxCryptoKeyGenerator and typeFlag = "symmetric"
89+ or
90+ jcaSpec instanceof JavaSecurityKeyPairGenerator and typeFlag .matches ( "asymmetric%" )
91+ ) and
92+ (
93+ jcaSpec .getAlgoSpec ( ) .( StringLiteral ) .getValue ( ) .toUpperCase ( ) = "AES" and
94+ typeFlag = "symmetric"
95+ or
96+ jcaSpec .getAlgoSpec ( ) .( StringLiteral ) .getValue ( ) .toUpperCase ( ) .matches ( [ "RSA" , "DSA" , "DH" ] ) and
97+ typeFlag = "asymmetric-non-ec"
98+ or
99+ jcaSpec .getAlgoSpec ( ) .( StringLiteral ) .getValue ( ) .toUpperCase ( ) .matches ( "EC%" ) and
100+ typeFlag = "asymmetric-ec"
101+ ) and
102+ DataFlow:: localExprFlow ( jcaSpec , ma .getQualifier ( ) ) and
103+ node .asExpr ( ) = ma .getArgument ( 0 )
104+ )
105+ }
106+
107+ // TODO: rethink the predicate name; also think about whether this could/should be a class instead; or a predicate within the sink class so can do sink.predicate()...
108+ // TODO: can prbly re-work way using the typeFlag to be better and less repetitive
109+ private predicate hasKeySizeInSpec ( DataFlow:: Node node , string typeFlag ) {
110+ exists ( ClassInstanceExpr paramSpec |
111+ (
112+ paramSpec .getConstructedType ( ) instanceof AsymmetricNonECSpec and
113+ typeFlag = "asymmetric-non-ec"
114+ or
115+ paramSpec .getConstructedType ( ) instanceof EcGenParameterSpec and
116+ typeFlag = "asymmetric-ec"
117+ ) and
118+ node .asExpr ( ) = paramSpec .getArgument ( 0 )
119+ )
96120}
97121// TODO:
98122// todo #0: look into use of specs without keygen objects; should spec not be a sink in these cases?
99123// todo #3: make list of algo names more easily reusable (either as constant-type variable at top of file, or model as own class to share, etc.)
100- // todo #5:
124+ // todo #4: use flowstate (or even just result predicate) to pass source int size to sink?
0 commit comments