@@ -310,3 +310,225 @@ private class ECDsaSigner extends SignerUse {
310310private class RSASigner extends SignerUse {
311311 RSASigner ( ) { this .getQualifier ( ) .getType ( ) instanceof RSAClass }
312312}
313+
314+ class AesMode extends Class {
315+ AesMode ( ) { this .hasFullyQualifiedName ( "System.Security.Cryptography" , [ "AesGcm" , "AesCcm" ] ) }
316+ }
317+
318+ class AesModeCreation extends ObjectCreation {
319+ AesModeCreation ( ) { this .getObjectType ( ) instanceof AesMode }
320+
321+ Expr getKeyArg ( ) { result = this .getArgument ( 0 ) }
322+ }
323+
324+ class AesModeUse extends MethodCall {
325+ AesModeUse ( ) {
326+ this .getQualifier ( ) .getType ( ) instanceof AesMode and
327+ this .getTarget ( ) .hasName ( [ "Encrypt" , "Decrypt" ] )
328+ }
329+
330+ // One-shot API only.
331+ predicate isIntermediate ( ) { none ( ) }
332+
333+ Crypto:: KeyOperationSubtype getKeyOperationSubtype ( ) {
334+ if this .isEncrypt ( )
335+ then result = Crypto:: TEncryptMode ( )
336+ else
337+ if this .isDecrypt ( )
338+ then result = Crypto:: TDecryptMode ( )
339+ else result = Crypto:: TUnknownKeyOperationMode ( )
340+ }
341+
342+ predicate isEncrypt ( ) { this .getTarget ( ) .getName ( ) = "Encrypt" }
343+
344+ predicate isDecrypt ( ) { this .getTarget ( ) .getName ( ) = "Decrypt" }
345+
346+ Expr getNonceArg ( ) { result = this .getArgument ( 0 ) }
347+
348+ Expr getMessageArg ( ) { result = this .getArgument ( 1 ) }
349+
350+ Expr getOutputArg ( ) {
351+ this .isEncrypt ( ) and
352+ result = this .getArgument ( 2 )
353+ or
354+ this .isDecrypt ( ) and
355+ result = this .getArgument ( 3 )
356+ }
357+ }
358+
359+ /**
360+ * A symmetric algorithm class, such as AES or DES.
361+ */
362+ class SymmetricAlgorithm extends Class {
363+ SymmetricAlgorithm ( ) {
364+ this .getABaseType ( ) .hasFullyQualifiedName ( "System.Security.Cryptography" , "SymmetricAlgorithm" )
365+ }
366+
367+ CryptoTransformCreation getCreateTransformCall ( ) { result = this .getAMethod ( ) .getACall ( ) }
368+ }
369+
370+ /**
371+ * A symmetric algorithm creation, such as `Aes.Create()`.
372+ */
373+ class SymmetricAlgorithmCreation extends MethodCall {
374+ SymmetricAlgorithmCreation ( ) {
375+ this .getTarget ( ) .hasName ( "Create" ) and
376+ this .getQualifier ( ) .getType ( ) instanceof SymmetricAlgorithm
377+ }
378+
379+ SymmetricAlgorithm getSymmetricAlgorithm ( ) { result = this .getQualifier ( ) .getType ( ) }
380+ }
381+
382+ class SymmetricAlgorithmUse extends QualifiableExpr {
383+ SymmetricAlgorithmUse ( ) {
384+ this .getQualifier ( ) .getType ( ) instanceof SymmetricAlgorithm and
385+ this .getQualifiedDeclaration ( )
386+ .hasName ( [ "CreateEncryptor" , "CreateDecryptor" , "Key" , "IV" , "Padding" , "Mode" ] )
387+ }
388+
389+ Expr getSymmetricAlgorithm ( ) { result = this .getQualifier ( ) }
390+
391+ predicate isIntermediate ( ) {
392+ not this .getQualifiedDeclaration ( ) .hasName ( [ "CreateEncryptor" , "CreateDecryptor" ] )
393+ }
394+
395+ // The key may be set by assigning it to the `Key` property of the symmetric algorithm.
396+ predicate isKeyConsumer ( ) {
397+ this instanceof PropertyWrite and this .getQualifiedDeclaration ( ) .getName ( ) = "Key"
398+ }
399+
400+ // The IV may be set by assigning it to the `IV` property of the symmetric algorithm.
401+ predicate isIvConsumer ( ) {
402+ this instanceof PropertyWrite and this .getQualifiedDeclaration ( ) .getName ( ) = "IV"
403+ }
404+
405+ // The padding mode may be set by assigning it to the `Padding` property of the symmetric algorithm.
406+ predicate isPaddingConsumer ( ) {
407+ this instanceof PropertyWrite and this .getQualifiedDeclaration ( ) .getName ( ) = "Padding"
408+ }
409+
410+ // The cipher mode may be set by assigning it to the `Mode` property of the symmetric algorithm.
411+ predicate isModeConsumer ( ) {
412+ this instanceof PropertyWrite and this .getQualifiedDeclaration ( ) .getName ( ) = "Mode"
413+ }
414+ }
415+
416+ /**
417+ * A call to `CreateEncryptor` or `CreateDecryptor` on a `SymmetricAlgorithm`.
418+ */
419+ class CryptoTransformCreation extends MethodCall {
420+ CryptoTransformCreation ( ) {
421+ this .getTarget ( ) .hasName ( [ "CreateEncryptor" , "CreateDecryptor" ] ) and
422+ this .getQualifier ( ) .getType ( ) instanceof SymmetricAlgorithm
423+ }
424+
425+ predicate isEncryptor ( ) { this .getTarget ( ) .getName ( ) = "CreateEncryptor" }
426+
427+ predicate isDecryptor ( ) { this .getTarget ( ) .getName ( ) = "CreateDecryptor" }
428+
429+ Expr getKeyArg ( ) { result = this .getArgument ( 0 ) }
430+
431+ Expr getIvArg ( ) { result = this .getArgument ( 1 ) }
432+
433+ SymmetricAlgorithm getSymmetricAlgorithm ( ) { result = this .getQualifier ( ) .getType ( ) }
434+ }
435+
436+ class CryptoStream extends Class {
437+ CryptoStream ( ) { this .hasFullyQualifiedName ( "System.Security.Cryptography" , "CryptoStream" ) }
438+ }
439+
440+ class CryptoStreamMode extends MemberConstant {
441+ CryptoStreamMode ( ) {
442+ this .getDeclaringType ( )
443+ .hasFullyQualifiedName ( "System.Security.Cryptography" , "CryptoStreamMode" )
444+ }
445+
446+ predicate isRead ( ) { this .getName ( ) = "Read" }
447+
448+ predicate isWrite ( ) { this .getName ( ) = "Write" }
449+ }
450+
451+ class PaddingMode extends MemberConstant {
452+ PaddingMode ( ) {
453+ this .getDeclaringType ( ) .hasFullyQualifiedName ( "System.Security.Cryptography" , "PaddingMode" )
454+ }
455+ }
456+
457+ class CipherMode extends MemberConstant {
458+ CipherMode ( ) {
459+ this .getDeclaringType ( ) .hasFullyQualifiedName ( "System.Security.Cryptography" , "CipherMode" )
460+ }
461+ }
462+
463+ class Stream extends Class {
464+ Stream ( ) { this .getABaseType ( ) .hasFullyQualifiedName ( "System.IO" , "Stream" ) }
465+ }
466+
467+ /**
468+ * A `Stream` object creation.
469+ */
470+ class StreamCreation extends ObjectCreation {
471+ StreamCreation ( ) { this .getObjectType ( ) instanceof Stream }
472+
473+ Expr getInputArg ( ) {
474+ result = this .getAnArgument ( ) and
475+ result .getType ( ) .hasFullyQualifiedName ( "System" , "Byte[]" )
476+ }
477+
478+ Expr getStreamArg ( ) {
479+ result = this .getAnArgument ( ) and
480+ result .getType ( ) instanceof Stream
481+ }
482+ }
483+
484+ class StreamUse extends MethodCall {
485+ StreamUse ( ) {
486+ this .getQualifier ( ) .getType ( ) instanceof Stream and
487+ this .getTarget ( ) .hasName ( [ "ToArray" , "Write" ] )
488+ }
489+
490+ predicate isIntermediate ( ) { this .getTarget ( ) .hasName ( "Write" ) }
491+
492+ Expr getInputArg ( ) {
493+ this .isIntermediate ( ) and
494+ result = this .getArgument ( 0 )
495+ }
496+
497+ Expr getOutput ( ) {
498+ not this .isIntermediate ( ) and
499+ result = this
500+ }
501+ }
502+
503+ class CryptoStreamCreation extends ObjectCreation {
504+ CryptoStreamCreation ( ) { this .getObjectType ( ) instanceof CryptoStream }
505+
506+ Expr getStreamArg ( ) { result = this .getArgument ( 0 ) }
507+
508+ Expr getTransformArg ( ) { result = this .getArgument ( 1 ) }
509+
510+ Expr getModeArg ( ) { result = this .getArgument ( 2 ) }
511+
512+ Crypto:: KeyOperationSubtype getKeyOperationSubtype ( ) {
513+ if CryptoTransformFlow:: getCreationFromUse ( this .getTransformArg ( ) ) .isEncryptor ( )
514+ then result = Crypto:: TEncryptMode ( )
515+ else
516+ if CryptoTransformFlow:: getCreationFromUse ( this .getTransformArg ( ) ) .isDecryptor ( )
517+ then result = Crypto:: TDecryptMode ( )
518+ else result = Crypto:: TUnknownKeyOperationMode ( )
519+ }
520+ }
521+
522+ class CryptoStreamUse extends MethodCall {
523+ CryptoStreamUse ( ) {
524+ this .getQualifier ( ) .getType ( ) instanceof CryptoStream and
525+ this .getTarget ( ) .hasName ( [ "Write" , "FlushFinalBlock" , "FlushFinalBlockAsync" , "Close" ] )
526+ }
527+
528+ predicate isIntermediate ( ) { this .getTarget ( ) .getName ( ) = "Write" }
529+
530+ Expr getInputArg ( ) {
531+ this .isIntermediate ( ) and
532+ result = this .getArgument ( 0 )
533+ }
534+ }
0 commit comments