@@ -2,7 +2,6 @@ import java
22import semmle.code.java.dataflow.DataFlow
33import semmle.code.java.dataflow.TaintTracking
44import semmle.code.java.controlflow.Dominance
5- import codeql.util.Option
65
76module JCAModel {
87 import Language
@@ -354,9 +353,11 @@ module JCAModel {
354353 else result instanceof KeyOpAlg:: TUnknownKeyOperationAlgorithmType
355354 }
356355
357- override string getKeySize ( ) {
356+ override string getKeySizeFixed ( ) {
358357 none ( ) // TODO: implement to handle variants such as AES-128
359358 }
359+
360+ override Crypto:: ConsumerInputDataFlowNode getKeySizeConsumer ( ) { none ( ) }
360361 }
361362
362363 bindingset [ input]
@@ -394,8 +395,6 @@ module JCAModel {
394395 override Crypto:: HashAlgorithmInstance getOAEPEncodingHashAlgorithm ( ) { result = this }
395396
396397 override Crypto:: HashAlgorithmInstance getMGF1HashAlgorithm ( ) { none ( ) } // TODO
397-
398- override string getKeySize ( ) { none ( ) }
399398 }
400399
401400 /**
@@ -446,8 +445,6 @@ module JCAModel {
446445 predicate isIntermediate ( ) ;
447446 }
448447
449- module MethodCallOption = Option< MethodCall > ;
450-
451448 /**
452449 * An generic analysis module for analyzing the `getInstance` to `initialize` to `doOperation` pattern in the JCA.
453450 *
@@ -568,6 +565,14 @@ module JCAModel {
568565 GetInstanceToInitToUseFlow:: flowPath ( src , sink )
569566 }
570567
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+
571576 Init getInitFromUse (
572577 Use use , GetInstanceToInitToUseFlow:: PathNode src , GetInstanceToInitToUseFlow:: PathNode sink
573578 ) {
@@ -829,6 +834,9 @@ module JCAModel {
829834 }
830835 }
831836
837+ module MessageDigestFlowAnalysisImpl =
838+ GetInstanceInitUseFlowAnalysis< MessageDigestGetInstanceCall , DUMMY_UNUSED_METHODCALL , DigestCall > ;
839+
832840 class MessageDigestGetInstanceAlgorithmValueConsumer extends HashAlgorithmValueConsumer {
833841 MessageDigestGetInstanceCall call ;
834842
@@ -849,17 +857,18 @@ module JCAModel {
849857 }
850858
851859 Expr getAlgorithmArg ( ) { result = this .getArgument ( 0 ) }
852-
853- DigestHashOperation getDigestCall ( ) {
854- DigestGetInstanceToDigestFlow:: flow ( DataFlow:: exprNode ( this ) ,
855- DataFlow:: exprNode ( result .( DigestCall ) .getQualifier ( ) ) )
856- }
857860 }
858861
859862 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+ }
861866
862867 Expr getDigestArtifactOutput ( ) { result = this }
868+
869+ Expr getInputArg ( ) { result = this .getArgument ( 0 ) }
870+
871+ predicate isIntermediate ( ) { this .getMethod ( ) .getName ( ) = "update" }
863872 }
864873
865874 // flow config from MessageDigest.getInstance to MessageDigest.digest
@@ -873,23 +882,22 @@ module JCAModel {
873882
874883 module DigestGetInstanceToDigestFlow = DataFlow:: Global< DigestGetInstanceToDigestConfig > ;
875884
876- class DigestArtifact extends Crypto:: DigestArtifactInstance {
877- DigestArtifact ( ) { this = any ( DigestCall call ) .getDigestArtifactOutput ( ) }
878-
879- override DataFlow:: Node getOutputNode ( ) { result .asExpr ( ) = this }
880- }
881-
882885 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 ( )
885890 }
886891
887892 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 ( )
893901 }
894902 }
895903
@@ -997,6 +1005,7 @@ module JCAModel {
9971005 or
9981006 // However, for general elliptic curves, getInstance("EC") is used
9991007 // and java.security.spec.ECGenParameterSpec("<CURVE NAME>") is what sets the specific curve.
1008+ // If init is not specified, the default (P-)
10001009 // The result of ECGenParameterSpec is passed to KeyPairGenerator.initialize
10011010 // If the curve is not specified, the default is used.
10021011 // We would trace the use of this inside a KeyPairGenerator.initialize
@@ -1096,6 +1105,30 @@ module JCAModel {
10961105 override string getKeySizeFixed ( ) { none ( ) }
10971106 }
10981107
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+
10991132 /*
11001133 * Key Derivation Functions (KDFs)
11011134 */
0 commit comments