@@ -84,7 +84,7 @@ module JCAModel {
84
84
predicate isSource ( DataFlow:: Node src ) { src .asExpr ( ) instanceof CipherStringLiteral }
85
85
86
86
predicate isSink ( DataFlow:: Node sink ) {
87
- exists ( CipherGetInstanceCall call | sink . asExpr ( ) = call . getAlgorithmArg ( ) )
87
+ exists ( Crypto :: AlgorithmValueConsumer consumer | sink = consumer . getInputNode ( ) )
88
88
}
89
89
}
90
90
@@ -102,13 +102,13 @@ module JCAModel {
102
102
class CipherStringLiteralAlgorithmInstance extends Crypto:: CipherAlgorithmInstance ,
103
103
Crypto:: ModeOfOperationAlgorithmInstance , Crypto:: PaddingAlgorithmInstance instanceof CipherStringLiteral
104
104
{
105
- CipherGetInstanceAlgorithmArg consumer ;
105
+ Crypto :: AlgorithmValueConsumer consumer ;
106
106
107
107
CipherStringLiteralAlgorithmInstance ( ) {
108
- AlgorithmStringToFetchFlow:: flow ( DataFlow:: exprNode ( this ) , DataFlow :: exprNode ( consumer ) )
108
+ AlgorithmStringToFetchFlow:: flow ( DataFlow:: exprNode ( this ) , consumer . getInputNode ( ) )
109
109
}
110
110
111
- CipherGetInstanceAlgorithmArg getConsumer ( ) { result = consumer }
111
+ Crypto :: AlgorithmValueConsumer getConsumer ( ) { result = consumer }
112
112
113
113
override Crypto:: ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm ( ) {
114
114
result = this and exists ( this .getRawModeAlgorithmName ( ) ) // TODO: provider defaults
@@ -411,6 +411,19 @@ module JCAModel {
411
411
}
412
412
}
413
413
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
+
414
427
predicate additionalFlowSteps ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
415
428
exists ( IvParameterSpecGetIvCall m |
416
429
node1 .asExpr ( ) = m .getQualifier ( ) and
@@ -421,12 +434,17 @@ module JCAModel {
421
434
node1 = n .getInputNode ( ) and
422
435
node2 = n .getOutputNode ( )
423
436
)
437
+ or
438
+ exists ( KeyPairGetKeyCall call |
439
+ node1 = call .getInputNode ( ) and
440
+ node2 = call .getOutputNode ( )
441
+ )
424
442
}
425
443
426
- class NonceAdditionalFlowInputStep extends AdditionalFlowInputStep {
444
+ class ArtifactAdditionalFlowStep extends AdditionalFlowInputStep {
427
445
DataFlow:: Node output ;
428
446
429
- NonceAdditionalFlowInputStep ( ) { additionalFlowSteps ( this , output ) }
447
+ ArtifactAdditionalFlowStep ( ) { additionalFlowSteps ( this , output ) }
430
448
431
449
override DataFlow:: Node getOutput ( ) { result = output }
432
450
}
@@ -605,4 +623,72 @@ module JCAModel {
605
623
)
606
624
}
607
625
}
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
+ }
608
694
}
0 commit comments