88private import python
99private import semmle.python.dataflow.new.DataFlow
1010private import semmle.python.Concepts
11+ private import semmle.python.ApiGraphs
1112
1213/**
1314 * Provides models for
@@ -16,286 +17,25 @@ private import semmle.python.Concepts
1617 * See https://pycryptodome.readthedocs.io/en/latest/
1718 */
1819private module CryptodomeModel {
19- // ---------------------------------------------------------------------------
20- // Cryptodome
21- // ---------------------------------------------------------------------------
22- /** Gets a reference to the `Cryptodome`/`Crypto` module. */
23- private DataFlow:: Node cryptodome ( DataFlow:: TypeTracker t ) {
24- t .start ( ) and
25- result = DataFlow:: importNode ( [ "Cryptodome" , "Crypto" ] )
26- or
27- exists ( DataFlow:: TypeTracker t2 | result = cryptodome ( t2 ) .track ( t2 , t ) )
28- }
29-
30- /** Gets a reference to the `Cryptodome`/`Crypto` module. */
31- DataFlow:: Node cryptodome ( ) { result = cryptodome ( DataFlow:: TypeTracker:: end ( ) ) }
32-
33- /** Provides models for the `Cryptodome`/`Crypto` module. */
34- module Cryptodome {
35- /**
36- * Gets a reference to the attribute `attr_name` of the `Cryptodome`/`Crypto` module.
37- * WARNING: Only holds for a few predefined attributes.
38- */
39- private DataFlow:: Node cryptodome_attr ( DataFlow:: TypeTracker t , string attr_name ) {
40- attr_name in [ "PublicKey" ] and
41- (
42- t .start ( ) and
43- result = DataFlow:: importNode ( [ "Cryptodome" , "Crypto" ] + "." + attr_name )
44- or
45- t .startInAttr ( attr_name ) and
46- result = cryptodome ( )
47- )
48- or
49- // Due to bad performance when using normal setup with `cryptodome_attr(t2, attr_name).track(t2, t)`
50- // we have inlined that code and forced a join
51- exists ( DataFlow:: TypeTracker t2 |
52- exists ( DataFlow:: StepSummary summary |
53- cryptodome_attr_first_join ( t2 , attr_name , result , summary ) and
54- t = t2 .append ( summary )
55- )
56- )
57- }
58-
59- pragma [ nomagic]
60- private predicate cryptodome_attr_first_join (
61- DataFlow:: TypeTracker t2 , string attr_name , DataFlow:: Node res , DataFlow:: StepSummary summary
62- ) {
63- DataFlow:: StepSummary:: step ( cryptodome_attr ( t2 , attr_name ) , res , summary )
64- }
65-
66- /**
67- * Gets a reference to the attribute `attr_name` of the `Cryptodome`/`Crypto` module.
68- * WARNING: Only holds for a few predefined attributes.
69- */
70- private DataFlow:: Node cryptodome_attr ( string attr_name ) {
71- result = cryptodome_attr ( DataFlow:: TypeTracker:: end ( ) , attr_name )
72- }
73-
74- // -------------------------------------------------------------------------
75- // Cryptodome.PublicKey
76- // -------------------------------------------------------------------------
77- /** Gets a reference to the `Cryptodome.PublicKey`/`Crypto.PublicKey` module. */
78- DataFlow:: Node publicKey ( ) { result = cryptodome_attr ( "PublicKey" ) }
79-
80- /** Provides models for the `Cryptodome.PublicKey`/`Crypto.PublicKey` module */
81- module PublicKey {
82- /**
83- * Gets a reference to the attribute `attr_name` of the `Cryptodome.PublicKey`/`Crypto.PublicKey` module.
84- * WARNING: Only holds for a few predefined attributes.
85- */
86- private DataFlow:: Node publicKey_attr ( DataFlow:: TypeTracker t , string attr_name ) {
87- attr_name in [ "RSA" , "DSA" , "ECC" ] and
88- (
89- t .start ( ) and
90- result = DataFlow:: importNode ( [ "Cryptodome" , "Crypto" ] + ".PublicKey" + "." + attr_name )
91- or
92- t .startInAttr ( attr_name ) and
93- result = publicKey ( )
94- )
95- or
96- // Due to bad performance when using normal setup with `publicKey_attr(t2, attr_name).track(t2, t)`
97- // we have inlined that code and forced a join
98- exists ( DataFlow:: TypeTracker t2 |
99- exists ( DataFlow:: StepSummary summary |
100- publicKey_attr_first_join ( t2 , attr_name , result , summary ) and
101- t = t2 .append ( summary )
102- )
103- )
104- }
105-
106- pragma [ nomagic]
107- private predicate publicKey_attr_first_join (
108- DataFlow:: TypeTracker t2 , string attr_name , DataFlow:: Node res ,
109- DataFlow:: StepSummary summary
110- ) {
111- DataFlow:: StepSummary:: step ( publicKey_attr ( t2 , attr_name ) , res , summary )
112- }
113-
114- /**
115- * Gets a reference to the attribute `attr_name` of the `Cryptodome.PublicKey`/`Crypto.PublicKey` module.
116- * WARNING: Only holds for a few predefined attributes.
117- */
118- private DataFlow:: Node publicKey_attr ( string attr_name ) {
119- result = publicKey_attr ( DataFlow:: TypeTracker:: end ( ) , attr_name )
120- }
121-
122- // -------------------------------------------------------------------------
123- // Cryptodome.PublicKey.RSA
124- // -------------------------------------------------------------------------
125- /** Gets a reference to the `Cryptodome.PublicKey.RSA`/`Crypto.PublicKey.RSA` module. */
126- DataFlow:: Node rsa ( ) { result = publicKey_attr ( "RSA" ) }
127-
128- /** Provides models for the `Cryptodome.PublicKey.RSA`/`Crypto.PublicKey.RSA` module */
129- module RSA {
130- /**
131- * Gets a reference to the attribute `attr_name` of the `Cryptodome.PublicKey.RSA`/`Crypto.PublicKey.RSA` module.
132- * WARNING: Only holds for a few predefined attributes.
133- */
134- private DataFlow:: Node rsa_attr ( DataFlow:: TypeTracker t , string attr_name ) {
135- attr_name in [ "generate" ] and
136- (
137- t .start ( ) and
138- result =
139- DataFlow:: importNode ( [ "Cryptodome" , "Crypto" ] + ".PublicKey.RSA" + "." + attr_name )
140- or
141- t .startInAttr ( attr_name ) and
142- result = rsa ( )
143- )
144- or
145- // Due to bad performance when using normal setup with `rsa_attr(t2, attr_name).track(t2, t)`
146- // we have inlined that code and forced a join
147- exists ( DataFlow:: TypeTracker t2 |
148- exists ( DataFlow:: StepSummary summary |
149- rsa_attr_first_join ( t2 , attr_name , result , summary ) and
150- t = t2 .append ( summary )
151- )
152- )
153- }
154-
155- pragma [ nomagic]
156- private predicate rsa_attr_first_join (
157- DataFlow:: TypeTracker t2 , string attr_name , DataFlow:: Node res ,
158- DataFlow:: StepSummary summary
159- ) {
160- DataFlow:: StepSummary:: step ( rsa_attr ( t2 , attr_name ) , res , summary )
161- }
162-
163- /**
164- * Gets a reference to the attribute `attr_name` of the `Cryptodome.PublicKey.RSA`/`Crypto.PublicKey.RSA` module.
165- * WARNING: Only holds for a few predefined attributes.
166- */
167- private DataFlow:: Node rsa_attr ( string attr_name ) {
168- result = rsa_attr ( DataFlow:: TypeTracker:: end ( ) , attr_name )
169- }
170-
171- /** Gets a reference to the `Cryptodome.PublicKey.RSA.generate`/`Crypto.PublicKey.RSA.generate` function. */
172- DataFlow:: Node generate ( ) { result = rsa_attr ( "generate" ) }
173- }
174-
175- // -------------------------------------------------------------------------
176- // Cryptodome.PublicKey.DSA
177- // -------------------------------------------------------------------------
178- /** Gets a reference to the `Cryptodome.PublicKey.DSA`/`Crypto.PublicKey.DSA` module. */
179- DataFlow:: Node dsa ( ) { result = publicKey_attr ( "DSA" ) }
180-
181- /** Provides models for the `Cryptodome.PublicKey.DSA`/`Crypto.PublicKey.DSA` module */
182- module DSA {
183- /**
184- * Gets a reference to the attribute `attr_name` of the `Cryptodome.PublicKey.DSA`/`Crypto.PublicKey.DSA` module.
185- * WARNING: Only holds for a few predefined attributes.
186- */
187- private DataFlow:: Node dsa_attr ( DataFlow:: TypeTracker t , string attr_name ) {
188- attr_name in [ "generate" ] and
189- (
190- t .start ( ) and
191- result =
192- DataFlow:: importNode ( [ "Cryptodome" , "Crypto" ] + ".PublicKey.DSA" + "." + attr_name )
193- or
194- t .startInAttr ( attr_name ) and
195- result = dsa ( )
196- )
197- or
198- // Due to bad performance when using normal setup with `dsa_attr(t2, attr_name).track(t2, t)`
199- // we have inlined that code and forced a join
200- exists ( DataFlow:: TypeTracker t2 |
201- exists ( DataFlow:: StepSummary summary |
202- dsa_attr_first_join ( t2 , attr_name , result , summary ) and
203- t = t2 .append ( summary )
204- )
205- )
206- }
207-
208- pragma [ nomagic]
209- private predicate dsa_attr_first_join (
210- DataFlow:: TypeTracker t2 , string attr_name , DataFlow:: Node res ,
211- DataFlow:: StepSummary summary
212- ) {
213- DataFlow:: StepSummary:: step ( dsa_attr ( t2 , attr_name ) , res , summary )
214- }
215-
216- /**
217- * Gets a reference to the attribute `attr_name` of the `Cryptodome.PublicKey.DSA`/`Crypto.PublicKey.DSA` module.
218- * WARNING: Only holds for a few predefined attributes.
219- */
220- private DataFlow:: Node dsa_attr ( string attr_name ) {
221- result = dsa_attr ( DataFlow:: TypeTracker:: end ( ) , attr_name )
222- }
223-
224- /** Gets a reference to the `Cryptodome.PublicKey.DSA.generate`/`Crypto.PublicKey.DSA.generate` function. */
225- DataFlow:: Node generate ( ) { result = dsa_attr ( "generate" ) }
226- }
227-
228- // -------------------------------------------------------------------------
229- // Cryptodome.PublicKey.ECC
230- // -------------------------------------------------------------------------
231- /** Gets a reference to the `Cryptodome.PublicKey.ECC`/`Crypto.PublicKey.ECC` module. */
232- DataFlow:: Node ecc ( ) { result = publicKey_attr ( "ECC" ) }
233-
234- /** Provides models for the `Cryptodome.PublicKey.ECC`/`Crypto.PublicKey.ECC` module */
235- module ECC {
236- /**
237- * Gets a reference to the attribute `attr_name` of the `Cryptodome.PublicKey.ECC`/`Crypto.PublicKey.ECC` module.
238- * WARNING: Only holds for a few predefined attributes.
239- */
240- private DataFlow:: Node ecc_attr ( DataFlow:: TypeTracker t , string attr_name ) {
241- attr_name in [ "generate" ] and
242- (
243- t .start ( ) and
244- result =
245- DataFlow:: importNode ( [ "Cryptodome" , "Crypto" ] + ".PublicKey.ECC" + "." + attr_name )
246- or
247- t .startInAttr ( attr_name ) and
248- result = ecc ( )
249- )
250- or
251- // Due to bad performance when using normal setup with `ecc_attr(t2, attr_name).track(t2, t)`
252- // we have inlined that code and forced a join
253- exists ( DataFlow:: TypeTracker t2 |
254- exists ( DataFlow:: StepSummary summary |
255- ecc_attr_first_join ( t2 , attr_name , result , summary ) and
256- t = t2 .append ( summary )
257- )
258- )
259- }
260-
261- pragma [ nomagic]
262- private predicate ecc_attr_first_join (
263- DataFlow:: TypeTracker t2 , string attr_name , DataFlow:: Node res ,
264- DataFlow:: StepSummary summary
265- ) {
266- DataFlow:: StepSummary:: step ( ecc_attr ( t2 , attr_name ) , res , summary )
267- }
268-
269- /**
270- * Gets a reference to the attribute `attr_name` of the `Cryptodome.PublicKey.ECC`/`Crypto.PublicKey.ECC` module.
271- * WARNING: Only holds for a few predefined attributes.
272- */
273- private DataFlow:: Node ecc_attr ( string attr_name ) {
274- result = ecc_attr ( DataFlow:: TypeTracker:: end ( ) , attr_name )
275- }
276-
277- /** Gets a reference to the `Cryptodome.PublicKey.ECC.generate`/`Crypto.PublicKey.ECC.generate` function. */
278- DataFlow:: Node generate ( ) { result = ecc_attr ( "generate" ) }
279- }
280- }
281- }
282-
28320 // ---------------------------------------------------------------------------
28421 /**
28522 * A call to `Cryptodome.PublicKey.RSA.generate`/`Crypto.PublicKey.RSA.generate`
28623 *
28724 * See https://pycryptodome.readthedocs.io/en/latest/src/public_key/rsa.html#Crypto.PublicKey.RSA.generate
28825 */
28926 class CryptodomePublicKeyRsaGenerateCall extends Cryptography:: PublicKey:: KeyGeneration:: RsaRange ,
290- DataFlow:: CfgNode {
291- override CallNode node ;
292-
27+ DataFlow:: CallCfgNode {
29328 CryptodomePublicKeyRsaGenerateCall ( ) {
294- node .getFunction ( ) = Cryptodome:: PublicKey:: RSA:: generate ( ) .asCfgNode ( )
29+ this =
30+ API:: moduleImport ( [ "Crypto" , "Cryptodome" ] )
31+ .getMember ( "PublicKey" )
32+ .getMember ( "RSA" )
33+ .getMember ( "generate" )
34+ .getACall ( )
29535 }
29636
29737 override DataFlow:: Node getKeySizeArg ( ) {
298- result . asCfgNode ( ) in [ node .getArg ( 0 ) , node .getArgByName ( "bits" ) ]
38+ result in [ this .getArg ( 0 ) , this .getArgByName ( "bits" ) ]
29939 }
30040 }
30141
@@ -305,15 +45,18 @@ private module CryptodomeModel {
30545 * See https://pycryptodome.readthedocs.io/en/latest/src/public_key/dsa.html#Crypto.PublicKey.DSA.generate
30646 */
30747 class CryptodomePublicKeyDsaGenerateCall extends Cryptography:: PublicKey:: KeyGeneration:: DsaRange ,
308- DataFlow:: CfgNode {
309- override CallNode node ;
310-
48+ DataFlow:: CallCfgNode {
31149 CryptodomePublicKeyDsaGenerateCall ( ) {
312- node .getFunction ( ) = Cryptodome:: PublicKey:: DSA:: generate ( ) .asCfgNode ( )
50+ this =
51+ API:: moduleImport ( [ "Crypto" , "Cryptodome" ] )
52+ .getMember ( "PublicKey" )
53+ .getMember ( "DSA" )
54+ .getMember ( "generate" )
55+ .getACall ( )
31356 }
31457
31558 override DataFlow:: Node getKeySizeArg ( ) {
316- result . asCfgNode ( ) in [ node .getArg ( 0 ) , node .getArgByName ( "bits" ) ]
59+ result in [ this .getArg ( 0 ) , this .getArgByName ( "bits" ) ]
31760 }
31861 }
31962
@@ -323,16 +66,20 @@ private module CryptodomeModel {
32366 * See https://pycryptodome.readthedocs.io/en/latest/src/public_key/ecc.html#Crypto.PublicKey.ECC.generate
32467 */
32568 class CryptodomePublicKeyEccGenerateCall extends Cryptography:: PublicKey:: KeyGeneration:: EccRange ,
326- DataFlow:: CfgNode {
327- override CallNode node ;
328-
69+ DataFlow:: CallCfgNode {
32970 CryptodomePublicKeyEccGenerateCall ( ) {
330- node .getFunction ( ) = Cryptodome:: PublicKey:: ECC:: generate ( ) .asCfgNode ( )
71+ this =
72+ API:: moduleImport ( [ "Crypto" , "Cryptodome" ] )
73+ .getMember ( "PublicKey" )
74+ .getMember ( "ECC" )
75+ .getMember ( "generate" )
76+ .getACall ( )
33177 }
33278
33379 /** Gets the argument that specifies the curve to use (a string). */
334- DataFlow:: Node getCurveArg ( ) { result . asCfgNode ( ) in [ node .getArgByName ( "curve" ) ] }
80+ DataFlow:: Node getCurveArg ( ) { result in [ this .getArgByName ( "curve" ) ] }
33581
82+ /** Gets the name of the curve to use, as well as the origin that explains how we obtained this name. */
33683 string getCurveWithOrigin ( DataFlow:: Node origin ) {
33784 exists ( StrConst str | origin = DataFlow:: exprNode ( str ) |
33885 origin .( DataFlow:: LocalSourceNode ) .flowsTo ( this .getCurveArg ( ) ) and
@@ -341,7 +88,7 @@ private module CryptodomeModel {
34188 }
34289
34390 override int getKeySizeWithOrigin ( DataFlow:: Node origin ) {
344- exists ( string curve | curve = getCurveWithOrigin ( origin ) |
91+ exists ( string curve | curve = this . getCurveWithOrigin ( origin ) |
34592 // using list from https://pycryptodome.readthedocs.io/en/latest/src/public_key/ecc.html
34693 curve in [ "NIST P-256" , "p256" , "P-256" , "prime256v1" , "secp256r1" ] and result = 256
34794 or
0 commit comments