@@ -526,3 +526,116 @@ module HTTP {
526526 }
527527 }
528528}
529+
530+ /** Provides models for cryptographic things. */
531+ module Cryptography {
532+ /** Provides models for public-key cryptography, also called asymmetric cryptography. */
533+ module PublicKey {
534+ /**
535+ * A data-flow node that generates a new key-pair for use with public-key cryptography.
536+ *
537+ * Extend this class to refine existing API models. If you want to model new APIs,
538+ * extend `KeyGeneration::Range` instead.
539+ */
540+ class KeyGeneration extends DataFlow:: Node {
541+ KeyGeneration:: Range range ;
542+
543+ KeyGeneration ( ) { this = range }
544+
545+ /** Gets the name of the cryptographic algorithm (for example `"RSA"` or `"AES"`). */
546+ string getName ( ) { result = range .getName ( ) }
547+
548+ /** Gets the argument that specifies the size of the key in bits, if available. */
549+ DataFlow:: Node getKeySizeArg ( ) { result = range .getKeySizeArg ( ) }
550+
551+ /**
552+ * Gets the size of the key generated (in bits), as well as the `origin` that
553+ * explains how we obtained this specific key size.
554+ */
555+ int getKeySizeWithOrigin ( DataFlow:: Node origin ) {
556+ result = range .getKeySizeWithOrigin ( origin )
557+ }
558+
559+ /** Gets the minimum key size (in bits) for this algorithm to be considered secure. */
560+ int minimumSecureKeySize ( ) { result = range .minimumSecureKeySize ( ) }
561+ }
562+
563+ /** Provides classes for modeling new key-pair generation APIs. */
564+ module KeyGeneration {
565+ /** Gets a back-reference to the keysize argument `arg` that was used to generate a new key-pair. */
566+ DataFlow:: LocalSourceNode keysizeBacktracker ( DataFlow:: TypeBackTracker t , DataFlow:: Node arg ) {
567+ t .start ( ) and
568+ arg = any ( KeyGeneration:: Range r ) .getKeySizeArg ( ) and
569+ result = arg .getALocalSource ( )
570+ or
571+ // Due to bad performance when using normal setup with we have inlined that code and forced a join
572+ exists ( DataFlow:: TypeBackTracker t2 |
573+ exists ( DataFlow:: StepSummary summary |
574+ keysizeBacktracker_first_join ( t2 , arg , result , summary ) and
575+ t = t2 .prepend ( summary )
576+ )
577+ )
578+ }
579+
580+ pragma [ nomagic]
581+ private predicate keysizeBacktracker_first_join (
582+ DataFlow:: TypeBackTracker t2 , DataFlow:: Node arg , DataFlow:: Node res ,
583+ DataFlow:: StepSummary summary
584+ ) {
585+ DataFlow:: StepSummary:: step ( res , keysizeBacktracker ( t2 , arg ) , summary )
586+ }
587+
588+ /** Gets a back-reference to the keysize argument `arg` that was used to generate a new key-pair. */
589+ DataFlow:: LocalSourceNode keysizeBacktracker ( DataFlow:: Node arg ) {
590+ result = keysizeBacktracker ( DataFlow:: TypeBackTracker:: end ( ) , arg )
591+ }
592+
593+ /**
594+ * A data-flow node that generates a new key-pair for use with public-key cryptography.
595+ *
596+ * Extend this class to model new APIs. If you want to refine existing API models,
597+ * extend `KeyGeneration` instead.
598+ */
599+ abstract class Range extends DataFlow:: Node {
600+ /** Gets the name of the cryptographic algorithm (for example `"RSA"`). */
601+ abstract string getName ( ) ;
602+
603+ /** Gets the argument that specifies the size of the key in bits, if available. */
604+ abstract DataFlow:: Node getKeySizeArg ( ) ;
605+
606+ /**
607+ * Gets the size of the key generated (in bits), as well as the `origin` that
608+ * explains how we obtained this specific key size.
609+ */
610+ int getKeySizeWithOrigin ( DataFlow:: Node origin ) {
611+ origin = keysizeBacktracker ( this .getKeySizeArg ( ) ) and
612+ result = origin .asExpr ( ) .( IntegerLiteral ) .getValue ( )
613+ }
614+
615+ /** Gets the minimum key size (in bits) for this algorithm to be considered secure. */
616+ abstract int minimumSecureKeySize ( ) ;
617+ }
618+
619+ /** A data-flow node that generates a new RSA key-pair. */
620+ abstract class RsaRange extends Range {
621+ final override string getName ( ) { result = "RSA" }
622+
623+ final override int minimumSecureKeySize ( ) { result = 2048 }
624+ }
625+
626+ /** A data-flow node that generates a new DSA key-pair. */
627+ abstract class DsaRange extends Range {
628+ final override string getName ( ) { result = "DSA" }
629+
630+ final override int minimumSecureKeySize ( ) { result = 2048 }
631+ }
632+
633+ /** A data-flow node that generates a new ECC key-pair. */
634+ abstract class EccRange extends Range {
635+ final override string getName ( ) { result = "ECC" }
636+
637+ final override int minimumSecureKeySize ( ) { result = 224 }
638+ }
639+ }
640+ }
641+ }
0 commit comments