@@ -2,7 +2,6 @@ import java
2
2
import semmle.code.java.dataflow.DataFlow
3
3
import semmle.code.java.dataflow.TaintTracking
4
4
import semmle.code.java.controlflow.Dominance
5
- import codeql.util.Option
6
5
7
6
module JCAModel {
8
7
import Language
@@ -354,9 +353,11 @@ module JCAModel {
354
353
else result instanceof KeyOpAlg:: TUnknownKeyOperationAlgorithmType
355
354
}
356
355
357
- override string getKeySize ( ) {
356
+ override string getKeySizeFixed ( ) {
358
357
none ( ) // TODO: implement to handle variants such as AES-128
359
358
}
359
+
360
+ override Crypto:: ConsumerInputDataFlowNode getKeySizeConsumer ( ) { none ( ) }
360
361
}
361
362
362
363
bindingset [ input]
@@ -394,8 +395,6 @@ module JCAModel {
394
395
override Crypto:: HashAlgorithmInstance getOAEPEncodingHashAlgorithm ( ) { result = this }
395
396
396
397
override Crypto:: HashAlgorithmInstance getMGF1HashAlgorithm ( ) { none ( ) } // TODO
397
-
398
- override string getKeySize ( ) { none ( ) }
399
398
}
400
399
401
400
/**
@@ -446,8 +445,6 @@ module JCAModel {
446
445
predicate isIntermediate ( ) ;
447
446
}
448
447
449
- module MethodCallOption = Option< MethodCall > ;
450
-
451
448
/**
452
449
* An generic analysis module for analyzing the `getInstance` to `initialize` to `doOperation` pattern in the JCA.
453
450
*
@@ -568,6 +565,14 @@ module JCAModel {
568
565
GetInstanceToInitToUseFlow:: flowPath ( src , sink )
569
566
}
570
567
568
+ GetInstance getInstantiationFromInit (
569
+ Init init , GetInstanceToInitToUseFlow:: PathNode src , GetInstanceToInitToUseFlow:: PathNode sink
570
+ ) {
571
+ src .getNode ( ) .asExpr ( ) = result and
572
+ sink .getNode ( ) .asExpr ( ) = init .( MethodCall ) .getQualifier ( ) and
573
+ GetInstanceToInitToUseFlow:: flowPath ( src , sink )
574
+ }
575
+
571
576
Init getInitFromUse (
572
577
Use use , GetInstanceToInitToUseFlow:: PathNode src , GetInstanceToInitToUseFlow:: PathNode sink
573
578
) {
@@ -829,6 +834,9 @@ module JCAModel {
829
834
}
830
835
}
831
836
837
+ module MessageDigestFlowAnalysisImpl =
838
+ GetInstanceInitUseFlowAnalysis< MessageDigestGetInstanceCall , DUMMY_UNUSED_METHODCALL , DigestCall > ;
839
+
832
840
class MessageDigestGetInstanceAlgorithmValueConsumer extends HashAlgorithmValueConsumer {
833
841
MessageDigestGetInstanceCall call ;
834
842
@@ -849,17 +857,18 @@ module JCAModel {
849
857
}
850
858
851
859
Expr getAlgorithmArg ( ) { result = this .getArgument ( 0 ) }
852
-
853
- DigestHashOperation getDigestCall ( ) {
854
- DigestGetInstanceToDigestFlow:: flow ( DataFlow:: exprNode ( this ) ,
855
- DataFlow:: exprNode ( result .( DigestCall ) .getQualifier ( ) ) )
856
- }
857
860
}
858
861
859
862
class DigestCall extends MethodCall {
860
- DigestCall ( ) { this .getCallee ( ) .hasQualifiedName ( "java.security" , "MessageDigest" , "digest" ) }
863
+ DigestCall ( ) {
864
+ this .getCallee ( ) .hasQualifiedName ( "java.security" , "MessageDigest" , [ "update" , "digest" ] )
865
+ }
861
866
862
867
Expr getDigestArtifactOutput ( ) { result = this }
868
+
869
+ Expr getInputArg ( ) { result = this .getArgument ( 0 ) }
870
+
871
+ predicate isIntermediate ( ) { this .getMethod ( ) .getName ( ) = "update" }
863
872
}
864
873
865
874
// flow config from MessageDigest.getInstance to MessageDigest.digest
@@ -873,23 +882,22 @@ module JCAModel {
873
882
874
883
module DigestGetInstanceToDigestFlow = DataFlow:: Global< DigestGetInstanceToDigestConfig > ;
875
884
876
- class DigestArtifact extends Crypto:: DigestArtifactInstance {
877
- DigestArtifact ( ) { this = any ( DigestCall call ) .getDigestArtifactOutput ( ) }
878
-
879
- override DataFlow:: Node getOutputNode ( ) { result .asExpr ( ) = this }
880
- }
881
-
882
885
class DigestHashOperation extends Crypto:: HashOperationInstance instanceof DigestCall {
883
- override Crypto:: DigestArtifactInstance getDigestArtifact ( ) {
884
- result = this .( DigestCall ) .getDigestArtifactOutput ( )
886
+ DigestHashOperation ( ) { not super .isIntermediate ( ) }
887
+
888
+ override Crypto:: ArtifactOutputDataFlowNode getOutputArtifact ( ) {
889
+ result .asExpr ( ) = super .getDigestArtifactOutput ( )
885
890
}
886
891
887
892
override Crypto:: AlgorithmValueConsumer getAnAlgorithmValueConsumer ( ) {
888
- exists ( MessageDigestGetInstanceCall getInstanceCall |
889
- getInstanceCall .getDigestCall ( ) = this and
890
- getInstanceCall =
891
- result .( MessageDigestGetInstanceAlgorithmValueConsumer ) .getInstantiationCall ( )
892
- )
893
+ MessageDigestFlowAnalysisImpl:: getInstantiationFromUse ( this , _, _) =
894
+ result .( MessageDigestGetInstanceAlgorithmValueConsumer ) .getInstantiationCall ( )
895
+ }
896
+
897
+ override Crypto:: ConsumerInputDataFlowNode getInputConsumer ( ) {
898
+ result .asExpr ( ) = super .getInputArg ( ) or
899
+ result .asExpr ( ) =
900
+ MessageDigestFlowAnalysisImpl:: getAnIntermediateUseFromFinalUse ( this , _, _) .getInputArg ( )
893
901
}
894
902
}
895
903
@@ -997,6 +1005,7 @@ module JCAModel {
997
1005
or
998
1006
// However, for general elliptic curves, getInstance("EC") is used
999
1007
// and java.security.spec.ECGenParameterSpec("<CURVE NAME>") is what sets the specific curve.
1008
+ // If init is not specified, the default (P-)
1000
1009
// The result of ECGenParameterSpec is passed to KeyPairGenerator.initialize
1001
1010
// If the curve is not specified, the default is used.
1002
1011
// We would trace the use of this inside a KeyPairGenerator.initialize
@@ -1096,6 +1105,30 @@ module JCAModel {
1096
1105
override string getKeySizeFixed ( ) { none ( ) }
1097
1106
}
1098
1107
1108
+ class KeyGeneratorCipherAlgorithm extends CipherStringLiteralAlgorithmInstance {
1109
+ KeyGeneratorCipherAlgorithm ( ) { consumer instanceof KeyGenerationAlgorithmValueConsumer }
1110
+
1111
+ override Crypto:: ConsumerInputDataFlowNode getKeySizeConsumer ( ) {
1112
+ exists ( KeyGeneratorGetInstanceCall getInstance , KeyGeneratorInitCall init |
1113
+ getInstance =
1114
+ this .getConsumer ( ) .( KeyGenerationAlgorithmValueConsumer ) .getInstantiationCall ( ) and
1115
+ getInstance = KeyGeneratorFlowAnalysisImpl:: getInstantiationFromInit ( init , _, _) and
1116
+ init .getKeySizeArg ( ) = result .asExpr ( )
1117
+ )
1118
+ }
1119
+
1120
+ predicate isOnlyConsumedByKeyGen ( ) {
1121
+ forall ( Crypto:: AlgorithmValueConsumer c |
1122
+ c = this .getConsumer ( ) and
1123
+ c instanceof KeyGenerationAlgorithmValueConsumer
1124
+ )
1125
+ }
1126
+
1127
+ override predicate shouldHaveModeOfOperation ( ) { this .isOnlyConsumedByKeyGen ( ) }
1128
+
1129
+ override predicate shouldHavePaddingScheme ( ) { this .isOnlyConsumedByKeyGen ( ) }
1130
+ }
1131
+
1099
1132
/*
1100
1133
* Key Derivation Functions (KDFs)
1101
1134
*/
0 commit comments