1
-
2
1
import java
3
2
4
3
/**
5
4
* Models for the signature algorithms defined by the `org.bouncycastle.crypto.signers` package.
6
- *
7
5
*/
8
6
module Signers {
9
7
import Language
10
8
import BouncyCastle.FlowAnalysis
11
9
import BouncyCastle.AlgorithmInstances
12
10
13
- abstract class SignatureAlgorithmValueConsumer extends Crypto:: AlgorithmValueConsumer { }
14
-
15
11
/**
16
12
* A model of the `Signer` class in Bouncy Castle.
17
13
*/
@@ -21,70 +17,49 @@ module Signers {
21
17
this .getName ( ) .matches ( "%Signer" )
22
18
}
23
19
24
- MethodCall getAnInitCall ( ) {
25
- result = this .getAMethodCall ( "init" )
26
- }
20
+ MethodCall getAnInitCall ( ) { result = this .getAMethodCall ( "init" ) }
27
21
28
22
MethodCall getAUseCall ( ) {
29
23
result = this .getAMethodCall ( [ "update" , "generateSignature" , "verifySignature" ] )
30
24
}
31
-
25
+
32
26
MethodCall getAMethodCall ( string name ) {
33
27
result .getCallee ( ) .hasQualifiedName ( "org.bouncycastle.crypto.signers" , this .getName ( ) , name )
34
28
}
35
29
}
36
30
37
31
/**
38
32
* 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.
41
34
*/
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 ;
57
36
58
37
/**
59
38
* The type is instantiated by a constructor call and initialized by a call to
60
39
* `init()` which takes two arguments. The first argument is a flag indicating
61
40
* 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.
63
42
*/
64
43
class InitCall extends MethodCall {
65
- InitCall ( ) {
66
- this = any ( Signer signer ) .getAnInitCall ( )
67
- }
44
+ InitCall ( ) { this = any ( Signer signer ) .getAnInitCall ( ) }
68
45
69
46
Expr getForSigningArg ( ) { result = this .getArgument ( 0 ) }
70
47
71
48
Expr getKeyArg ( ) { result = this .getArgument ( 1 ) }
72
49
73
- Crypto:: KeyOperationAlgorithmInstance getAlgorithm ( ) {
74
- result = getSignatureAlgorithmInstanceFromType ( this .getReceiverType ( ) )
75
- }
76
-
50
+ // TODO: Support dataflow for the operation sub-type.
77
51
Crypto:: KeyOperationSubtype getKeyOperationSubtype ( ) {
78
- (
52
+ if this .isOperationSubTypeKnown ( )
53
+ then
79
54
this .getForSigningArg ( ) .( BooleanLiteral ) .getBooleanValue ( ) = true and
80
55
result = Crypto:: TSignMode ( )
81
- ) or (
56
+ or
82
57
this .getForSigningArg ( ) .( BooleanLiteral ) .getBooleanValue ( ) = false and
83
58
result = Crypto:: TVerifyMode ( )
84
- ) or (
85
- result = Crypto:: TUnknownKeyOperationMode ( )
86
- )
59
+ else result = Crypto:: TUnknownKeyOperationMode ( )
87
60
}
61
+
62
+ predicate isOperationSubTypeKnown ( ) { this .getForSigningArg ( ) instanceof BooleanLiteral }
88
63
}
89
64
90
65
/**
@@ -93,19 +68,13 @@ module Signers {
93
68
* verify the signature, respectively.
94
69
*/
95
70
class UseCall extends MethodCall {
96
- UseCall ( ) {
97
- this = any ( Signer signer ) .getAUseCall ( )
98
- }
71
+ UseCall ( ) { this = any ( Signer signer ) .getAUseCall ( ) }
99
72
100
- predicate isIntermediate ( ) {
101
- this .getCallee ( ) .getName ( ) = "update"
102
- }
73
+ predicate isIntermediate ( ) { this .getCallee ( ) .getName ( ) = "update" }
103
74
104
75
Expr getInput ( ) { result = this .getArgument ( 0 ) }
105
76
106
- Expr getOutput ( ) {
107
- result = this
108
- }
77
+ Expr getOutput ( ) { result = this }
109
78
}
110
79
111
80
/**
@@ -118,10 +87,12 @@ module Signers {
118
87
* or `verifySignature()` on a `Signer` instance.
119
88
*/
120
89
class SignatureOperationInstance extends Crypto:: KeyOperationInstance instanceof UseCall {
121
-
90
+ SignatureOperationInstance ( ) { not this .isIntermediate ( ) }
91
+
122
92
override Crypto:: AlgorithmValueConsumer getAnAlgorithmValueConsumer ( ) {
123
- result = FlowAnalysis:: getInstantiationFromInit ( this . getInitCall ( ) , _, _)
93
+ result = FlowAnalysis:: getInstantiationFromUse ( this , _, _)
124
94
}
95
+
125
96
override Crypto:: KeyOperationSubtype getKeyOperationSubtype ( ) {
126
97
if FlowAnalysis:: hasInit ( this )
127
98
then result = this .getInitCall ( ) .getKeyOperationSubtype ( )
@@ -144,17 +115,12 @@ module Signers {
144
115
result .asExpr ( ) = super .getOutput ( )
145
116
}
146
117
147
- InitCall getInitCall ( ) {
148
- result = FlowAnalysis:: getInitFromUse ( this , _, _)
149
- }
118
+ InitCall getInitCall ( ) { result = FlowAnalysis:: getInitFromUse ( this , _, _) }
150
119
151
120
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 , _, _)
157
124
}
158
125
}
159
126
}
160
-
0 commit comments