@@ -84,7 +84,7 @@ module JCAModel {
8484 predicate isSource ( DataFlow:: Node src ) { src .asExpr ( ) instanceof CipherStringLiteral }
8585
8686 predicate isSink ( DataFlow:: Node sink ) {
87- exists ( CipherGetInstanceCall call | sink . asExpr ( ) = call . getAlgorithmArg ( ) )
87+ exists ( Crypto :: AlgorithmValueConsumer consumer | sink = consumer . getInputNode ( ) )
8888 }
8989 }
9090
@@ -102,13 +102,13 @@ module JCAModel {
102102 class CipherStringLiteralAlgorithmInstance extends Crypto:: CipherAlgorithmInstance ,
103103 Crypto:: ModeOfOperationAlgorithmInstance , Crypto:: PaddingAlgorithmInstance instanceof CipherStringLiteral
104104 {
105- CipherGetInstanceAlgorithmArg consumer ;
105+ Crypto :: AlgorithmValueConsumer consumer ;
106106
107107 CipherStringLiteralAlgorithmInstance ( ) {
108- AlgorithmStringToFetchFlow:: flow ( DataFlow:: exprNode ( this ) , DataFlow :: exprNode ( consumer ) )
108+ AlgorithmStringToFetchFlow:: flow ( DataFlow:: exprNode ( this ) , consumer . getInputNode ( ) )
109109 }
110110
111- CipherGetInstanceAlgorithmArg getConsumer ( ) { result = consumer }
111+ Crypto :: AlgorithmValueConsumer getConsumer ( ) { result = consumer }
112112
113113 override Crypto:: ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm ( ) {
114114 result = this and exists ( this .getRawModeAlgorithmName ( ) ) // TODO: provider defaults
@@ -411,6 +411,19 @@ module JCAModel {
411411 }
412412 }
413413
414+ // e.g., getPublic or getPrivate
415+ class KeyPairGetKeyCall extends MethodCall {
416+ KeyPairGetKeyCall ( ) {
417+ this .getCallee ( ) .hasQualifiedName ( "java.security" , "KeyPair" , "getPublic" )
418+ or
419+ this .getCallee ( ) .hasQualifiedName ( "java.security" , "KeyPair" , "getPrivate" )
420+ }
421+
422+ DataFlow:: Node getInputNode ( ) { result .asExpr ( ) = this .getQualifier ( ) }
423+
424+ DataFlow:: Node getOutputNode ( ) { result .asExpr ( ) = this }
425+ }
426+
414427 predicate additionalFlowSteps ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
415428 exists ( IvParameterSpecGetIvCall m |
416429 node1 .asExpr ( ) = m .getQualifier ( ) and
@@ -421,12 +434,17 @@ module JCAModel {
421434 node1 = n .getInputNode ( ) and
422435 node2 = n .getOutputNode ( )
423436 )
437+ or
438+ exists ( KeyPairGetKeyCall call |
439+ node1 = call .getInputNode ( ) and
440+ node2 = call .getOutputNode ( )
441+ )
424442 }
425443
426- class NonceAdditionalFlowInputStep extends AdditionalFlowInputStep {
444+ class ArtifactAdditionalFlowStep extends AdditionalFlowInputStep {
427445 DataFlow:: Node output ;
428446
429- NonceAdditionalFlowInputStep ( ) { additionalFlowSteps ( this , output ) }
447+ ArtifactAdditionalFlowStep ( ) { additionalFlowSteps ( this , output ) }
430448
431449 override DataFlow:: Node getOutput ( ) { result = output }
432450 }
@@ -605,4 +623,72 @@ module JCAModel {
605623 )
606624 }
607625 }
626+
627+ class KeyGeneratorCallAlgorithmValueConsumer extends Crypto:: AlgorithmValueConsumer {
628+ KeyGeneratorGetInstanceCall call ;
629+
630+ KeyGeneratorCallAlgorithmValueConsumer ( ) { this = call .getAlgorithmArg ( ) }
631+
632+ override DataFlow:: Node getInputNode ( ) { result .asExpr ( ) = this }
633+
634+ override Crypto:: AlgorithmInstance getAKnownAlgorithmSource ( ) {
635+ result .( CipherStringLiteralAlgorithmInstance ) .getConsumer ( ) = this
636+ }
637+ }
638+
639+ // flow from instance created by getInstance to generateKey
640+ module KeyGeneratorGetInstanceToGenerateConfig implements DataFlow:: ConfigSig {
641+ predicate isSource ( DataFlow:: Node src ) {
642+ exists ( KeyGeneratorGetInstanceCall call | src .asExpr ( ) = call )
643+ }
644+
645+ predicate isSink ( DataFlow:: Node sink ) {
646+ exists ( KeyGeneratorGenerateCall call | sink .asExpr ( ) = call .( MethodCall ) .getQualifier ( ) )
647+ }
648+ }
649+
650+ module KeyGeneratorGetInstanceToGenerateFlow =
651+ DataFlow:: Global< KeyGeneratorGetInstanceToGenerateConfig > ;
652+
653+ class KeyGeneratorGetInstanceCall extends MethodCall {
654+ KeyGeneratorGetInstanceCall ( ) {
655+ this .getCallee ( ) .hasQualifiedName ( "javax.crypto" , "KeyGenerator" , "getInstance" )
656+ or
657+ this .getCallee ( ) .hasQualifiedName ( "java.security" , "KeyPairGenerator" , "getInstance" )
658+ }
659+
660+ Expr getAlgorithmArg ( ) { result = super .getArgument ( 0 ) }
661+
662+ predicate flowsTo ( KeyGeneratorGenerateCall sink ) {
663+ KeyGeneratorGetInstanceToGenerateFlow:: flow ( DataFlow:: exprNode ( this ) ,
664+ DataFlow:: exprNode ( sink .( MethodCall ) .getQualifier ( ) ) )
665+ }
666+ }
667+
668+ class KeyGeneratorGenerateCall extends Crypto:: KeyGenerationOperationInstance instanceof MethodCall
669+ {
670+ Crypto:: KeyArtifactType type ;
671+
672+ KeyGeneratorGenerateCall ( ) {
673+ this .getCallee ( ) .hasQualifiedName ( "javax.crypto" , "KeyGenerator" , "generateKey" ) and
674+ type instanceof Crypto:: TSymmetricKeyType
675+ or
676+ this .getCallee ( ) .hasQualifiedName ( "java.security" , "KeyPairGenerator" , "generateKeyPair" ) and
677+ type instanceof Crypto:: TAsymmetricKeyType
678+ }
679+
680+ override DataFlow:: Node getOutputKeyArtifact ( ) { result .asExpr ( ) = this }
681+
682+ override Crypto:: KeyArtifactType getOutputKeyType ( ) { result = type }
683+
684+ override Crypto:: AlgorithmValueConsumer getAnAlgorithmValueConsumer ( ) {
685+ exists ( KeyGeneratorGetInstanceCall getInstance |
686+ getInstance .flowsTo ( this ) and result = getInstance .getAlgorithmArg ( )
687+ )
688+ }
689+
690+ Crypto:: AlgorithmInstance getAKnownAlgorithm ( ) {
691+ result = this .getAnAlgorithmValueConsumer ( ) .getAKnownAlgorithmSource ( )
692+ }
693+ }
608694}
0 commit comments