1-
21import java
32
43/**
54 * Models for the signature algorithms defined by the `org.bouncycastle.crypto.signers` package.
6- *
75 */
86module Signers {
97 import Language
108 import BouncyCastle.FlowAnalysis
119 import BouncyCastle.AlgorithmInstances
1210
13- abstract class SignatureAlgorithmValueConsumer extends Crypto:: AlgorithmValueConsumer { }
14-
1511 /**
1612 * A model of the `Signer` class in Bouncy Castle.
1713 */
@@ -21,70 +17,49 @@ module Signers {
2117 this .getName ( ) .matches ( "%Signer" )
2218 }
2319
24- MethodCall getAnInitCall ( ) {
25- result = this .getAMethodCall ( "init" )
26- }
20+ MethodCall getAnInitCall ( ) { result = this .getAMethodCall ( "init" ) }
2721
2822 MethodCall getAUseCall ( ) {
2923 result = this .getAMethodCall ( [ "update" , "generateSignature" , "verifySignature" ] )
3024 }
31-
25+
3226 MethodCall getAMethodCall ( string name ) {
3327 result .getCallee ( ) .hasQualifiedName ( "org.bouncycastle.crypto.signers" , this .getName ( ) , name )
3428 }
3529 }
3630
3731 /**
3832 * BouncyCastle algorithms are instantiated by calling the constructor of the
39- * corresponding class. The algorithm is implicitly defined by the constructor
40- * call.
33+ * corresponding class.
4134 */
42- class NewCall extends SignatureAlgorithmValueConsumer instanceof ClassInstanceExpr {
43- NewCall ( ) {
44- this .getConstructedType ( ) instanceof Signer
45- }
46-
47- override Crypto:: AlgorithmInstance getAKnownAlgorithmSource ( ) {
48- result = getSignatureAlgorithmInstanceFromType ( super .getConstructedType ( ) )
49- }
50-
51- // TODO: Since the algorithm is implicitly defined by the constructor, should
52- // the input node be `this`?
53- override Crypto:: ConsumerInputDataFlowNode getInputNode ( ) {
54- result .asExpr ( ) = this
55- }
56- }
35+ class NewCall = SignatureAlgorithmInstance ;
5736
5837 /**
5938 * The type is instantiated by a constructor call and initialized by a call to
6039 * `init()` which takes two arguments. The first argument is a flag indicating
6140 * whether the operation is signing data or verifying a signature, and the
62- * second is the key to use.
41+ * second is the key to use.
6342 */
6443 class InitCall extends MethodCall {
65- InitCall ( ) {
66- this = any ( Signer signer ) .getAnInitCall ( )
67- }
44+ InitCall ( ) { this = any ( Signer signer ) .getAnInitCall ( ) }
6845
6946 Expr getForSigningArg ( ) { result = this .getArgument ( 0 ) }
7047
7148 Expr getKeyArg ( ) { result = this .getArgument ( 1 ) }
7249
73- Crypto:: KeyOperationAlgorithmInstance getAlgorithm ( ) {
74- result = getSignatureAlgorithmInstanceFromType ( this .getReceiverType ( ) )
75- }
76-
50+ // TODO: Support dataflow for the operation sub-type.
7751 Crypto:: KeyOperationSubtype getKeyOperationSubtype ( ) {
78- (
52+ if this .isOperationSubTypeKnown ( )
53+ then
7954 this .getForSigningArg ( ) .( BooleanLiteral ) .getBooleanValue ( ) = true and
8055 result = Crypto:: TSignMode ( )
81- ) or (
56+ or
8257 this .getForSigningArg ( ) .( BooleanLiteral ) .getBooleanValue ( ) = false and
8358 result = Crypto:: TVerifyMode ( )
84- ) or (
85- result = Crypto:: TUnknownKeyOperationMode ( )
86- )
59+ else result = Crypto:: TUnknownKeyOperationMode ( )
8760 }
61+
62+ predicate isOperationSubTypeKnown ( ) { this .getForSigningArg ( ) instanceof BooleanLiteral }
8863 }
8964
9065 /**
@@ -93,19 +68,13 @@ module Signers {
9368 * verify the signature, respectively.
9469 */
9570 class UseCall extends MethodCall {
96- UseCall ( ) {
97- this = any ( Signer signer ) .getAUseCall ( )
98- }
71+ UseCall ( ) { this = any ( Signer signer ) .getAUseCall ( ) }
9972
100- predicate isIntermediate ( ) {
101- this .getCallee ( ) .getName ( ) = "update"
102- }
73+ predicate isIntermediate ( ) { this .getCallee ( ) .getName ( ) = "update" }
10374
10475 Expr getInput ( ) { result = this .getArgument ( 0 ) }
10576
106- Expr getOutput ( ) {
107- result = this
108- }
77+ Expr getOutput ( ) { result = this }
10978 }
11079
11180 /**
@@ -118,10 +87,12 @@ module Signers {
11887 * or `verifySignature()` on a `Signer` instance.
11988 */
12089 class SignatureOperationInstance extends Crypto:: KeyOperationInstance instanceof UseCall {
121-
90+ SignatureOperationInstance ( ) { not this .isIntermediate ( ) }
91+
12292 override Crypto:: AlgorithmValueConsumer getAnAlgorithmValueConsumer ( ) {
123- result = FlowAnalysis:: getInstantiationFromInit ( this . getInitCall ( ) , _, _)
93+ result = FlowAnalysis:: getInstantiationFromUse ( this , _, _)
12494 }
95+
12596 override Crypto:: KeyOperationSubtype getKeyOperationSubtype ( ) {
12697 if FlowAnalysis:: hasInit ( this )
12798 then result = this .getInitCall ( ) .getKeyOperationSubtype ( )
@@ -144,17 +115,12 @@ module Signers {
144115 result .asExpr ( ) = super .getOutput ( )
145116 }
146117
147- InitCall getInitCall ( ) {
148- result = FlowAnalysis:: getInitFromUse ( this , _, _)
149- }
118+ InitCall getInitCall ( ) { result = FlowAnalysis:: getInitFromUse ( this , _, _) }
150119
151120 UseCall getAnUpdateCall ( ) {
152- (
153- super .isIntermediate ( ) and result = this
154- ) or (
155- result = FlowAnalysis:: getAnIntermediateUseFromFinalUse ( this , _, _)
156- )
121+ super .isIntermediate ( ) and result = this
122+ or
123+ result = FlowAnalysis:: getAnIntermediateUseFromFinalUse ( this , _, _)
157124 }
158125 }
159126}
160-
0 commit comments