@@ -352,3 +352,231 @@ private class ECDsaSigner extends SignerUse {
352352private class RSASigner extends SignerUse {
353353 RSASigner ( ) { this .getQualifier ( ) .getType ( ) instanceof RSAClass }
354354}
355+
356+ /**
357+ * An AEAD class, such as `AesGcm`, `AesCcm`, or `ChaCha20Poly1305`.
358+ */
359+ class Aead extends Class {
360+ Aead ( ) {
361+ this .hasFullyQualifiedName ( "System.Security.Cryptography" ,
362+ [ "AesGcm" , "AesCcm" , "ChaCha20Poly1305" ] )
363+ }
364+ }
365+
366+ class AeadCreation extends ObjectCreation {
367+ AeadCreation ( ) { this .getObjectType ( ) instanceof Aead }
368+
369+ Expr getKeyArg ( ) { result = this .getArgument ( 0 ) }
370+ }
371+
372+ class AeadUse extends MethodCall {
373+ AeadUse ( ) {
374+ this .getQualifier ( ) .getType ( ) instanceof Aead and
375+ this .getTarget ( ) .hasName ( [ "Encrypt" , "Decrypt" ] )
376+ }
377+
378+ // One-shot API only.
379+ predicate isIntermediate ( ) { none ( ) }
380+
381+ Crypto:: KeyOperationSubtype getKeyOperationSubtype ( ) {
382+ if this .isEncrypt ( )
383+ then result = Crypto:: TEncryptMode ( )
384+ else
385+ if this .isDecrypt ( )
386+ then result = Crypto:: TDecryptMode ( )
387+ else result = Crypto:: TUnknownKeyOperationMode ( )
388+ }
389+
390+ predicate isEncrypt ( ) { this .getTarget ( ) .getName ( ) = "Encrypt" }
391+
392+ predicate isDecrypt ( ) { this .getTarget ( ) .getName ( ) = "Decrypt" }
393+
394+ Expr getNonceArg ( ) { result = this .getArgument ( 0 ) }
395+
396+ Expr getMessageArg ( ) { result = this .getArgument ( 1 ) }
397+
398+ Expr getOutputArg ( ) {
399+ this .isEncrypt ( ) and
400+ result = this .getArgument ( 2 )
401+ or
402+ this .isDecrypt ( ) and
403+ result = this .getArgument ( 3 )
404+ }
405+ }
406+
407+ /**
408+ * A symmetric algorithm class, such as AES or DES.
409+ */
410+ class SymmetricAlgorithm extends Class {
411+ SymmetricAlgorithm ( ) {
412+ this .getABaseType ( ) .hasFullyQualifiedName ( "System.Security.Cryptography" , "SymmetricAlgorithm" )
413+ }
414+
415+ CryptoTransformCreation getCreateTransformCall ( ) { result = this .getAMethod ( ) .getACall ( ) }
416+ }
417+
418+ /**
419+ * A symmetric algorithm creation, such as `Aes.Create()`.
420+ */
421+ class SymmetricAlgorithmCreation extends MethodCall {
422+ SymmetricAlgorithmCreation ( ) {
423+ this .getTarget ( ) .hasName ( "Create" ) and
424+ this .getQualifier ( ) .getType ( ) instanceof SymmetricAlgorithm
425+ }
426+
427+ SymmetricAlgorithm getSymmetricAlgorithm ( ) { result = this .getQualifier ( ) .getType ( ) }
428+ }
429+
430+ class SymmetricAlgorithmUse extends QualifiableExpr {
431+ SymmetricAlgorithmUse ( ) {
432+ this .getQualifier ( ) .getType ( ) instanceof SymmetricAlgorithm and
433+ this .getQualifiedDeclaration ( )
434+ .hasName ( [ "CreateEncryptor" , "CreateDecryptor" , "Key" , "IV" , "Padding" , "Mode" ] )
435+ }
436+
437+ Expr getSymmetricAlgorithm ( ) { result = this .getQualifier ( ) }
438+
439+ predicate isIntermediate ( ) {
440+ not this .getQualifiedDeclaration ( ) .hasName ( [ "CreateEncryptor" , "CreateDecryptor" ] )
441+ }
442+
443+ // The key may be set by assigning it to the `Key` property of the symmetric algorithm.
444+ predicate isKeyConsumer ( ) {
445+ this instanceof PropertyWrite and this .getQualifiedDeclaration ( ) .getName ( ) = "Key"
446+ }
447+
448+ // The IV may be set by assigning it to the `IV` property of the symmetric algorithm.
449+ predicate isIvConsumer ( ) {
450+ this instanceof PropertyWrite and this .getQualifiedDeclaration ( ) .getName ( ) = "IV"
451+ }
452+
453+ // The padding mode may be set by assigning it to the `Padding` property of the symmetric algorithm.
454+ predicate isPaddingConsumer ( ) {
455+ this instanceof PropertyWrite and this .getQualifiedDeclaration ( ) .getName ( ) = "Padding"
456+ }
457+
458+ // The cipher mode may be set by assigning it to the `Mode` property of the symmetric algorithm.
459+ predicate isModeConsumer ( ) {
460+ this instanceof PropertyWrite and this .getQualifiedDeclaration ( ) .getName ( ) = "Mode"
461+ }
462+ }
463+
464+ /**
465+ * A call to `CreateEncryptor` or `CreateDecryptor` on a `SymmetricAlgorithm`.
466+ */
467+ class CryptoTransformCreation extends MethodCall {
468+ CryptoTransformCreation ( ) {
469+ this .getTarget ( ) .hasName ( [ "CreateEncryptor" , "CreateDecryptor" ] ) and
470+ this .getQualifier ( ) .getType ( ) instanceof SymmetricAlgorithm
471+ }
472+
473+ predicate isEncryptor ( ) { this .getTarget ( ) .getName ( ) = "CreateEncryptor" }
474+
475+ predicate isDecryptor ( ) { this .getTarget ( ) .getName ( ) = "CreateDecryptor" }
476+
477+ Expr getKeyArg ( ) { result = this .getArgument ( 0 ) }
478+
479+ Expr getIvArg ( ) { result = this .getArgument ( 1 ) }
480+
481+ SymmetricAlgorithm getSymmetricAlgorithm ( ) { result = this .getQualifier ( ) .getType ( ) }
482+ }
483+
484+ class CryptoStream extends Class {
485+ CryptoStream ( ) { this .hasFullyQualifiedName ( "System.Security.Cryptography" , "CryptoStream" ) }
486+ }
487+
488+ class CryptoStreamMode extends MemberConstant {
489+ CryptoStreamMode ( ) {
490+ this .getDeclaringType ( )
491+ .hasFullyQualifiedName ( "System.Security.Cryptography" , "CryptoStreamMode" )
492+ }
493+
494+ predicate isRead ( ) { this .getName ( ) = "Read" }
495+
496+ predicate isWrite ( ) { this .getName ( ) = "Write" }
497+ }
498+
499+ class PaddingMode extends MemberConstant {
500+ PaddingMode ( ) {
501+ this .getDeclaringType ( ) .hasFullyQualifiedName ( "System.Security.Cryptography" , "PaddingMode" )
502+ }
503+ }
504+
505+ class CipherMode extends MemberConstant {
506+ CipherMode ( ) {
507+ this .getDeclaringType ( ) .hasFullyQualifiedName ( "System.Security.Cryptography" , "CipherMode" )
508+ }
509+ }
510+
511+ class Stream extends Class {
512+ Stream ( ) { this .getABaseType ( ) .hasFullyQualifiedName ( "System.IO" , "Stream" ) }
513+ }
514+
515+ /**
516+ * A `Stream` object creation.
517+ */
518+ class StreamCreation extends ObjectCreation {
519+ StreamCreation ( ) { this .getObjectType ( ) instanceof Stream }
520+
521+ Expr getInputArg ( ) {
522+ result = this .getAnArgument ( ) and
523+ result .getType ( ) .hasFullyQualifiedName ( "System" , "Byte[]" )
524+ }
525+
526+ Expr getStreamArg ( ) {
527+ result = this .getAnArgument ( ) and
528+ result .getType ( ) instanceof Stream
529+ }
530+ }
531+
532+ class StreamUse extends MethodCall {
533+ StreamUse ( ) {
534+ this .getQualifier ( ) .getType ( ) instanceof Stream and
535+ this .getTarget ( ) .hasName ( [ "ToArray" , "Write" ] )
536+ }
537+
538+ predicate isIntermediate ( ) { this .getTarget ( ) .hasName ( "Write" ) }
539+
540+ Expr getInputArg ( ) {
541+ this .isIntermediate ( ) and
542+ result = this .getArgument ( 0 )
543+ }
544+
545+ Expr getOutput ( ) {
546+ not this .isIntermediate ( ) and
547+ result = this
548+ }
549+ }
550+
551+ class CryptoStreamCreation extends ObjectCreation {
552+ CryptoStreamCreation ( ) { this .getObjectType ( ) instanceof CryptoStream }
553+
554+ Expr getStreamArg ( ) { result = this .getArgument ( 0 ) }
555+
556+ Expr getTransformArg ( ) { result = this .getArgument ( 1 ) }
557+
558+ Expr getModeArg ( ) { result = this .getArgument ( 2 ) }
559+
560+ Crypto:: KeyOperationSubtype getKeyOperationSubtype ( ) {
561+ if CryptoTransformFlow:: getCreationFromUse ( this .getTransformArg ( ) ) .isEncryptor ( )
562+ then result = Crypto:: TEncryptMode ( )
563+ else
564+ if CryptoTransformFlow:: getCreationFromUse ( this .getTransformArg ( ) ) .isDecryptor ( )
565+ then result = Crypto:: TDecryptMode ( )
566+ else result = Crypto:: TUnknownKeyOperationMode ( )
567+ }
568+ }
569+
570+ class CryptoStreamUse extends MethodCall {
571+ CryptoStreamUse ( ) {
572+ this .getQualifier ( ) .getType ( ) instanceof CryptoStream and
573+ this .getTarget ( ) .hasName ( [ "Write" , "FlushFinalBlock" , "FlushFinalBlockAsync" , "Close" ] )
574+ }
575+
576+ predicate isIntermediate ( ) { this .getTarget ( ) .getName ( ) = "Write" }
577+
578+ Expr getInputArg ( ) {
579+ this .isIntermediate ( ) and
580+ result = this .getArgument ( 0 )
581+ }
582+ }
0 commit comments