@@ -32,15 +32,15 @@ module Signers {
32
32
* BouncyCastle algorithms are instantiated by calling the constructor of the
33
33
* corresponding class.
34
34
*/
35
- class NewCall = SignatureAlgorithmInstance ;
35
+ private class NewCall = SignatureAlgorithmInstance ;
36
36
37
37
/**
38
38
* The type is instantiated by a constructor call and initialized by a call to
39
39
* `init()` which takes two arguments. The first argument is a flag indicating
40
40
* whether the operation is signing data or verifying a signature, and the
41
41
* second is the key to use.
42
42
*/
43
- class InitCall extends MethodCall {
43
+ private class InitCall extends MethodCall {
44
44
InitCall ( ) { this = any ( Signer signer ) .getAnInitCall ( ) }
45
45
46
46
Expr getForSigningArg ( ) { result = this .getArgument ( 0 ) }
@@ -67,7 +67,7 @@ module Signers {
67
67
* `generateSignature()` or `verifySignature()` methods are used to produce or
68
68
* verify the signature, respectively.
69
69
*/
70
- class UseCall extends MethodCall {
70
+ private class UseCall extends MethodCall {
71
71
UseCall ( ) { this = any ( Signer signer ) .getAUseCall ( ) }
72
72
73
73
predicate isIntermediate ( ) { this .getCallee ( ) .getName ( ) = "update" }
@@ -80,7 +80,7 @@ module Signers {
80
80
/**
81
81
* Instantiate the flow analysis module for the `Signer` class.
82
82
*/
83
- module FlowAnalysis = NewToInitToUseFlowAnalysis< NewCall , InitCall , UseCall > ;
83
+ private module FlowAnalysis = NewToInitToUseFlowAnalysis< NewCall , InitCall , UseCall > ;
84
84
85
85
/**
86
86
* A signing operation instance is a call to either `update()`, `generateSignature()`,
@@ -90,7 +90,7 @@ module Signers {
90
90
SignatureOperationInstance ( ) { not this .isIntermediate ( ) }
91
91
92
92
override Crypto:: AlgorithmValueConsumer getAnAlgorithmValueConsumer ( ) {
93
- result = FlowAnalysis:: getInstantiationFromUse ( this , _, _)
93
+ result = FlowAnalysis:: getNewFromUse ( this , _, _)
94
94
}
95
95
96
96
override Crypto:: KeyOperationSubtype getKeyOperationSubtype ( ) {
@@ -111,16 +111,150 @@ module Signers {
111
111
112
112
override Crypto:: ArtifactOutputDataFlowNode getOutputArtifact ( ) {
113
113
this .getKeyOperationSubtype ( ) = Crypto:: TSignMode ( ) and
114
- not super .isIntermediate ( ) and
115
114
result .asExpr ( ) = super .getOutput ( )
116
115
}
117
116
118
117
InitCall getInitCall ( ) { result = FlowAnalysis:: getInitFromUse ( this , _, _) }
119
118
120
119
UseCall getAnUpdateCall ( ) {
121
- super .isIntermediate ( ) and result = this
122
- or
123
120
result = FlowAnalysis:: getAnIntermediateUseFromFinalUse ( this , _, _)
124
121
}
125
122
}
126
123
}
124
+
125
+ /**
126
+ * Models for the key generation algorithms defined by the `org.bouncycastle.crypto.generators` package.
127
+ */
128
+ module Generators {
129
+ import Language
130
+ import BouncyCastle.FlowAnalysis
131
+ import BouncyCastle.AlgorithmInstances
132
+
133
+ /**
134
+ * A model of the `KeyGenerator` and `KeyPairGenerator` classes in Bouncy Castle.
135
+ */
136
+ class KeyGenerator extends RefType {
137
+ Crypto:: KeyArtifactType type ;
138
+
139
+ KeyGenerator ( ) {
140
+ this .getPackage ( ) .getName ( ) = "org.bouncycastle.crypto.generators" and
141
+ (
142
+ this .getName ( ) .matches ( "%KeyGenerator" ) and type instanceof Crypto:: TSymmetricKeyType
143
+ or
144
+ this .getName ( ) .matches ( "%KeyPairGenerator" ) and type instanceof Crypto:: TAsymmetricKeyType
145
+ )
146
+ }
147
+
148
+ MethodCall getAnInitCall ( ) { result = this .getAMethodCall ( "init" ) }
149
+
150
+ MethodCall getAUseCall ( ) { result = this .getAMethodCall ( [ "generateKey" , "generateKeyPair" ] ) }
151
+
152
+ MethodCall getAMethodCall ( string name ) {
153
+ result
154
+ .getCallee ( )
155
+ .hasQualifiedName ( "org.bouncycastle.crypto.generators" , this .getName ( ) , name )
156
+ }
157
+
158
+ Crypto:: KeyArtifactType getKeyType ( ) { result = type }
159
+
160
+ string getRawAlgorithmName ( ) {
161
+ this .getKeyType ( ) = Crypto:: TSymmetricKeyType ( ) and
162
+ result = this .getName ( ) .splitAt ( "KeyGenerator" , 0 )
163
+ or
164
+ this .getKeyType ( ) = Crypto:: TAsymmetricKeyType ( ) and
165
+ result = this .getName ( ) .splitAt ( "KeyPairGenerator" , 0 )
166
+ }
167
+ }
168
+
169
+ /**
170
+ * This type is used to model data flow from a key pair to the private and
171
+ * public components of the key pair.
172
+ */
173
+ class KeyPair extends RefType {
174
+ KeyPair ( ) {
175
+ this .getPackage ( ) .getName ( ) = "org.bouncycastle.crypto" and
176
+ this .getName ( ) = "%KeyPair" // `AsymmetricCipherKeyPair` or `EphemeralKeyPair`
177
+ }
178
+
179
+ MethodCall getPublicKeyCall ( ) { result = this .getAMethodCall ( "getPublic" ) }
180
+
181
+ MethodCall getPrivateKeyCall ( ) { result = this .getAMethodCall ( "getPrivate" ) }
182
+
183
+ MethodCall getAMethodCall ( string name ) {
184
+ result .getCallee ( ) .hasQualifiedName ( "org.bouncycastle.crypto" , this .getName ( ) , name )
185
+ }
186
+ }
187
+
188
+ /**
189
+ * BouncyCastle algorithms are instantiated by calling the constructor of the
190
+ * corresponding class.
191
+ */
192
+ private class KeyGeneratorNewCall = KeyGenerationAlgorithmInstance ;
193
+
194
+ /**
195
+ * The type is instantiated by a constructor call and initialized by a call to
196
+ * `init()` which takes a single `KeyGenerationParameters` argument.
197
+ */
198
+ private class KeyGeneratorInitCall extends MethodCall {
199
+ KeyGenerator gen ;
200
+
201
+ KeyGeneratorInitCall ( ) { this = gen .getAnInitCall ( ) }
202
+
203
+ // TODO: We may need to model this using the `parameters` argument passed to
204
+ // the `init()` method.
205
+ Crypto:: ConsumerInputDataFlowNode getKeySizeConsumer ( ) { none ( ) }
206
+ }
207
+
208
+ /**
209
+ * The `generateKey()` and `generateKeyPair()` methods are used to generate
210
+ * the resulting key, depending on the type of the generator.
211
+ */
212
+ private class KeyGeneratorUseCall extends MethodCall {
213
+ KeyGenerator gen ;
214
+
215
+ KeyGeneratorUseCall ( ) { this = gen .getAUseCall ( ) }
216
+
217
+ // Since key generators don't have `update()` methods, this is always false.
218
+ predicate isIntermediate ( ) { none ( ) }
219
+
220
+ Crypto:: KeyArtifactType getKeyType ( ) { result = gen .getKeyType ( ) }
221
+
222
+ Expr getOutput ( ) { result = this }
223
+ }
224
+
225
+ private module KeyGeneratorFlow =
226
+ NewToInitToUseFlowAnalysis< KeyGeneratorNewCall , KeyGeneratorInitCall , KeyGeneratorUseCall > ;
227
+
228
+ /**
229
+ * A key generation operation instance is a call to `generateKey()` or
230
+ * `generateKeyPair()` on a key generator defined under
231
+ * `org.bouncycastle.crypto.generators`.
232
+ */
233
+ class KeyGenerationOperationInstance extends Crypto:: KeyGenerationOperationInstance instanceof KeyGeneratorUseCall
234
+ {
235
+ override Crypto:: AlgorithmValueConsumer getAnAlgorithmValueConsumer ( ) {
236
+ result = KeyGeneratorFlow:: getNewFromUse ( this , _, _)
237
+ }
238
+
239
+ override Crypto:: ArtifactOutputDataFlowNode getOutputKeyArtifact ( ) {
240
+ result .asExpr ( ) = super .getOutput ( )
241
+ }
242
+
243
+ override Crypto:: KeyArtifactType getOutputKeyType ( ) { result = super .getKeyType ( ) }
244
+
245
+ override string getKeySizeFixed ( ) {
246
+ result = KeyGeneratorFlow:: getNewFromUse ( this , _, _) .getKeySizeFixed ( )
247
+ }
248
+
249
+ override Crypto:: ConsumerInputDataFlowNode getKeySizeConsumer ( ) {
250
+ result = KeyGeneratorFlow:: getInitFromUse ( this , _, _) .getKeySizeConsumer ( )
251
+ }
252
+ }
253
+
254
+ class KeyGenerationParameters extends RefType {
255
+ KeyGenerationParameters ( ) {
256
+ this .getPackage ( ) .getName ( ) = "org.bouncycastle.crypto.generators" and
257
+ this .getName ( ) .matches ( "%KeyGenerationParameters" )
258
+ }
259
+ }
260
+ }
0 commit comments