@@ -32,15 +32,15 @@ module Signers {
3232 * BouncyCastle algorithms are instantiated by calling the constructor of the
3333 * corresponding class.
3434 */
35- class NewCall = SignatureAlgorithmInstance ;
35+ private class NewCall = SignatureAlgorithmInstance ;
3636
3737 /**
3838 * The type is instantiated by a constructor call and initialized by a call to
3939 * `init()` which takes two arguments. The first argument is a flag indicating
4040 * whether the operation is signing data or verifying a signature, and the
4141 * second is the key to use.
4242 */
43- class InitCall extends MethodCall {
43+ private class InitCall extends MethodCall {
4444 InitCall ( ) { this = any ( Signer signer ) .getAnInitCall ( ) }
4545
4646 Expr getForSigningArg ( ) { result = this .getArgument ( 0 ) }
@@ -67,7 +67,7 @@ module Signers {
6767 * `generateSignature()` or `verifySignature()` methods are used to produce or
6868 * verify the signature, respectively.
6969 */
70- class UseCall extends MethodCall {
70+ private class UseCall extends MethodCall {
7171 UseCall ( ) { this = any ( Signer signer ) .getAUseCall ( ) }
7272
7373 predicate isIntermediate ( ) { this .getCallee ( ) .getName ( ) = "update" }
@@ -80,7 +80,7 @@ module Signers {
8080 /**
8181 * Instantiate the flow analysis module for the `Signer` class.
8282 */
83- module FlowAnalysis = NewToInitToUseFlowAnalysis< NewCall , InitCall , UseCall > ;
83+ private module FlowAnalysis = NewToInitToUseFlowAnalysis< NewCall , InitCall , UseCall > ;
8484
8585 /**
8686 * A signing operation instance is a call to either `update()`, `generateSignature()`,
@@ -90,7 +90,7 @@ module Signers {
9090 SignatureOperationInstance ( ) { not this .isIntermediate ( ) }
9191
9292 override Crypto:: AlgorithmValueConsumer getAnAlgorithmValueConsumer ( ) {
93- result = FlowAnalysis:: getInstantiationFromUse ( this , _, _)
93+ result = FlowAnalysis:: getNewFromUse ( this , _, _)
9494 }
9595
9696 override Crypto:: KeyOperationSubtype getKeyOperationSubtype ( ) {
@@ -111,16 +111,150 @@ module Signers {
111111
112112 override Crypto:: ArtifactOutputDataFlowNode getOutputArtifact ( ) {
113113 this .getKeyOperationSubtype ( ) = Crypto:: TSignMode ( ) and
114- not super .isIntermediate ( ) and
115114 result .asExpr ( ) = super .getOutput ( )
116115 }
117116
118117 InitCall getInitCall ( ) { result = FlowAnalysis:: getInitFromUse ( this , _, _) }
119118
120119 UseCall getAnUpdateCall ( ) {
121- super .isIntermediate ( ) and result = this
122- or
123120 result = FlowAnalysis:: getAnIntermediateUseFromFinalUse ( this , _, _)
124121 }
125122 }
126123}
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