diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index c10c4db7d09..cbd118ca5fa 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -13,3 +13,5 @@ University of Alabama in Huntsville (UAH)
Rockwell Collins
- Java files in alisa/org.osate.smaccm.stubs
+Friedrich Schiller University Jena
+ - Security and Confidentiality Analysis (implementation)
\ No newline at end of file
diff --git a/analyses/org.osate.analysis.security.ui/.classpath b/analyses/org.osate.analysis.security.ui/.classpath
new file mode 100644
index 00000000000..eca7bdba8f0
--- /dev/null
+++ b/analyses/org.osate.analysis.security.ui/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/analyses/org.osate.analysis.security.ui/.gitignore b/analyses/org.osate.analysis.security.ui/.gitignore
new file mode 100644
index 00000000000..ca1937f4a75
--- /dev/null
+++ b/analyses/org.osate.analysis.security.ui/.gitignore
@@ -0,0 +1,3 @@
+/bin/
+/target/
+*.jar
diff --git a/analyses/org.osate.analysis.security.ui/.project b/analyses/org.osate.analysis.security.ui/.project
new file mode 100644
index 00000000000..64fb6c0bf3e
--- /dev/null
+++ b/analyses/org.osate.analysis.security.ui/.project
@@ -0,0 +1,91 @@
+
+
+ org.osate.analysis.security.ui
+
+
+
+
+
+ org.eclipse.xtext.ui.shared.xtextBuilder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+ org.eclipse.pde.api.tools.apiAnalysisBuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+ org.eclipse.oomph.version.VersionBuilder
+
+
+ check.feature.closure.completeness
+ true
+
+
+ check.feature.closure.content
+ true
+
+
+ check.maven.pom
+ true
+
+
+ ignore.feature.content.redundancy
+ true
+
+
+ ignore.lower.bound.dependency.ranges
+ false
+
+
+ ignore.schema.builder
+ true
+
+
+ release.path
+ /releng/version-management/release.xml
+
+
+
+
+
+ org.eclipse.xtext.ui.shared.xtextNature
+ org.eclipse.m2e.core.maven2Nature
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+ org.eclipse.pde.api.tools.apiAnalysisNature
+ org.eclipse.oomph.version.VersionNature
+
+
+
+ 1702127013282
+
+ 30
+
+ org.eclipse.core.resources.regexFilterMatcher
+ node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__
+
+
+
+
diff --git a/analyses/org.osate.analysis.security.ui/.settings/org.eclipse.core.resources.prefs b/analyses/org.osate.analysis.security.ui/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 00000000000..99f26c0203a
--- /dev/null
+++ b/analyses/org.osate.analysis.security.ui/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
diff --git a/analyses/org.osate.analysis.security.ui/.settings/org.eclipse.xtend.core.Xtend.prefs b/analyses/org.osate.analysis.security.ui/.settings/org.eclipse.xtend.core.Xtend.prefs
new file mode 100644
index 00000000000..9682a4c0a11
--- /dev/null
+++ b/analyses/org.osate.analysis.security.ui/.settings/org.eclipse.xtend.core.Xtend.prefs
@@ -0,0 +1,7 @@
+//outlet.DEFAULT_OUTPUT.sourceFolder.src/main/java.directory=xtend-gen
+//outlet.DEFAULT_OUTPUT.sourceFolder.src/test/java.directory=src/test/generated-sources/xtend
+BuilderConfiguration.is_project_specific=true
+eclipse.preferences.version=1
+outlet.DEFAULT_OUTPUT.hideLocalSyntheticVariables=true
+outlet.DEFAULT_OUTPUT.installDslAsPrimarySource=false
+outlet.DEFAULT_OUTPUT.userOutputPerSourceFolder=true
diff --git a/analyses/org.osate.analysis.security.ui/META-INF/MANIFEST.MF b/analyses/org.osate.analysis.security.ui/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..75c15d143bd
--- /dev/null
+++ b/analyses/org.osate.analysis.security.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,14 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Ui
+Bundle-SymbolicName: org.osate.analysis.security.ui;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.osate.analysis.security.ui.Activator
+Require-Bundle: org.osate.aadl2;bundle-version="[5.0.0,6.0.0)",
+ org.osate.aadl2.modelsupport;bundle-version="[7.0.0,8.0.0)",
+ org.osate.ui;bundle-version="[6.3.0,7.0.0)",
+ org.osate.analysis.security;bundle-version="[1.0.0,2.0.0)",
+ org.osate.results;bundle-version="[3.0.0,4.0.0)"
+Automatic-Module-Name: org.osate.analysis.security.ui
+Bundle-ActivationPolicy: lazy
+Export-Package: org.osate.analysis.security.ui.handlers;version="1.0.0"
diff --git a/analyses/org.osate.analysis.security.ui/build.properties b/analyses/org.osate.analysis.security.ui/build.properties
new file mode 100644
index 00000000000..f684985c15f
--- /dev/null
+++ b/analyses/org.osate.analysis.security.ui/build.properties
@@ -0,0 +1,30 @@
+###############################################################################
+# Copyright (c) 2004-2023 Carnegie Mellon University and others. (see Contributors file).
+# All Rights Reserved.
+#
+# NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
+# KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
+# OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
+# MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
+#
+# This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
+# which is available at https://www.eclipse.org/legal/epl-2.0/
+# SPDX-License-Identifier: EPL-2.0
+#
+# Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
+#
+# This program includes and/or can make use of certain third party source code, object code, documentation and other
+# files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
+# configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
+# conditions contained in any such Third Party Software or separate license file distributed with such Third Party
+# Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party beneficiaries
+# to this license with respect to the terms applicable to their Third Party Software. Third Party Software licenses
+# only apply to the Third Party Software and not any other portion of this program or this program as a whole.
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ icons/,\
+ plugin.xml
+src.includes = icons/
diff --git a/analyses/org.osate.analysis.security.ui/icons/checkSecurity.gif b/analyses/org.osate.analysis.security.ui/icons/checkSecurity.gif
new file mode 100644
index 00000000000..4b7bd1dae17
Binary files /dev/null and b/analyses/org.osate.analysis.security.ui/icons/checkSecurity.gif differ
diff --git a/analyses/org.osate.analysis.security.ui/icons/noCheckSecurity.gif b/analyses/org.osate.analysis.security.ui/icons/noCheckSecurity.gif
new file mode 100644
index 00000000000..99ddcb78f8f
Binary files /dev/null and b/analyses/org.osate.analysis.security.ui/icons/noCheckSecurity.gif differ
diff --git a/analyses/org.osate.analysis.security.ui/plugin.properties b/analyses/org.osate.analysis.security.ui/plugin.properties
new file mode 100644
index 00000000000..13586a9cc76
--- /dev/null
+++ b/analyses/org.osate.analysis.security.ui/plugin.properties
@@ -0,0 +1,36 @@
+###############################################################################
+# Copyright (c) 2000, 2021 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+#
+# Contributors:
+# Carnegie Mellon University - initial API and implementation
+###############################################################################
+#
+# Resource strings for Security Checker
+#
+pluginName=Security Checker
+providerName = sei.cmu.edu
+
+#
+# Menu labels
+#
+menu.analyses.label = Analyses
+menu.security.label = Security
+menu.osate.label = OSATE
+
+popupMenu.aadl.label = OSATE
+popupMenu.analyses.label = AADL Analyses
+popupMenu.Security.label = Security
+
+#
+# Action labels & tooltips
+#
+actionSet.label = OSATE Security Analyses
+
+CheckSecurity.label = &Check Security Levels
+CheckSecurity.toolTip = Check Security
+CheckSecurity.icon = icons/checkSecurity.gif
+CheckSecurity.disabledIcon = icons/noCheckSecurity.gif
diff --git a/analyses/org.osate.analysis.security.ui/plugin.xml b/analyses/org.osate.analysis.security.ui/plugin.xml
new file mode 100644
index 00000000000..2419c10f3f5
--- /dev/null
+++ b/analyses/org.osate.analysis.security.ui/plugin.xml
@@ -0,0 +1,140 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/analyses/org.osate.analysis.security.ui/pom.xml b/analyses/org.osate.analysis.security.ui/pom.xml
new file mode 100644
index 00000000000..fbe87674ce1
--- /dev/null
+++ b/analyses/org.osate.analysis.security.ui/pom.xml
@@ -0,0 +1,43 @@
+
+
+
+
+ 4.0.0
+
+
+ org.osate
+ analyses.parent
+ 2.14.0-SNAPSHOT
+
+
+ org.osate
+ org.osate.analysis.security.ui
+ 1.0.0-SNAPSHOT
+ eclipse-plugin
+
+
diff --git a/analyses/org.osate.analysis.security.ui/src/org/osate/analysis/security/ui/Activator.java b/analyses/org.osate.analysis.security.ui/src/org/osate/analysis/security/ui/Activator.java
new file mode 100644
index 00000000000..303c9365d74
--- /dev/null
+++ b/analyses/org.osate.analysis.security.ui/src/org/osate/analysis/security/ui/Activator.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2004-2023 Carnegie Mellon University and others. (see Contributors file).
+ * All Rights Reserved.
+ *
+ * NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
+ * OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
+ * MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
+ *
+ * This program includes and/or can make use of certain third party source code, object code, documentation and other
+ * files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
+ * configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
+ * conditions contained in any such Third Party Software or separate license file distributed with such Third Party
+ * Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party beneficiaries
+ * to this license with respect to the terms applicable to their Third Party Software. Third Party Software licenses
+ * only apply to the Third Party Software and not any other portion of this program or this program as a whole.
+ *******************************************************************************/
+package org.osate.analysis.security.ui;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.osate.analysis.security.ui"; //$NON-NLS-1$
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/analyses/org.osate.analysis.security.ui/src/org/osate/analysis/security/ui/handlers/SecurityChecker.java b/analyses/org.osate.analysis.security.ui/src/org/osate/analysis/security/ui/handlers/SecurityChecker.java
new file mode 100644
index 00000000000..784db67cc9a
--- /dev/null
+++ b/analyses/org.osate.analysis.security.ui/src/org/osate/analysis/security/ui/handlers/SecurityChecker.java
@@ -0,0 +1,108 @@
+/*
+ *
+ *
+ * Copyright 2004, 2021 by Carnegie Mellon University, all rights reserved.
+ *
+ * Use of the Open Source AADL Tool Environment (OSATE) is subject to the terms of the license set forth
+ * at http://www.eclipse.org/legal/cpl-v10.html.
+ *
+ * NO WARRANTY
+ *
+ * ANY INFORMATION, MATERIALS, SERVICES, INTELLECTUAL PROPERTY OR OTHER PROPERTY OR RIGHTS GRANTED OR PROVIDED BY
+ * CARNEGIE MELLON UNIVERSITY PURSUANT TO THIS LICENSE (HEREINAFTER THE "DELIVERABLES") ARE ON AN "AS-IS" BASIS.
+ * CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED AS TO ANY MATTER INCLUDING,
+ * BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, INFORMATIONAL CONTENT,
+ * NONINFRINGEMENT, OR ERROR-FREE OPERATION. CARNEGIE MELLON UNIVERSITY SHALL NOT BE LIABLE FOR INDIRECT, SPECIAL OR
+ * CONSEQUENTIAL DAMAGES, SUCH AS LOSS OF PROFITS OR INABILITY TO USE SAID INTELLECTUAL PROPERTY, UNDER THIS LICENSE,
+ * REGARDLESS OF WHETHER SUCH PARTY WAS AWARE OF THE POSSIBILITY OF SUCH DAMAGES. LICENSEE AGREES THAT IT WILL NOT
+ * MAKE ANY WARRANTY ON BEHALF OF CARNEGIE MELLON UNIVERSITY, EXPRESS OR IMPLIED, TO ANY PERSON CONCERNING THE
+ * APPLICATION OF OR THE RESULTS TO BE OBTAINED WITH THE DELIVERABLES UNDER THIS LICENSE.
+ *
+ * Licensee hereby agrees to defend, indemnify, and hold harmless Carnegie Mellon University, its trustees, officers,
+ * employees, and agents from all claims or demands made against them (and any related losses, expenses, or
+ * attorney's fees) arising out of, or relating to Licensee's and/or its sub licensees' negligent use or willful
+ * misuse of or negligent conduct or willful misconduct regarding the Software, facilities, or other rights or
+ * assistance granted by Carnegie Mellon University under this License, including, but not limited to, any claims of
+ * product liability, personal injury, death, damage to property, or violation of any laws or regulations.
+ *
+ * Carnegie Mellon University Software Engineering Institute authored documents are sponsored by the U.S. Department
+ * of Defense under Contract F19628-00-C-0003. Carnegie Mellon University retains copyrights in all material produced
+ * under this contract. The U.S. Government retains a non-exclusive, royalty-free license to publish or reproduce these
+ * documents, or allow others to do so, for U.S. Government purposes only pursuant to the copyright license
+ * under the contract clause at 252.227.7013.
+ *
+ *
+ *
+ *
+ * %W%
+ * @version %I% %H%
+ */
+package org.osate.analysis.security.ui.handlers;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.osate.aadl2.Element;
+import org.osate.aadl2.instance.SystemInstance;
+import org.osate.aadl2.instance.SystemOperationMode;
+import org.osate.aadl2.modelsupport.errorreporting.AnalysisErrorReporterManager;
+import org.osate.analysis.security.SecurityLabelChecker;
+import org.osate.result.AnalysisResult;
+import org.osate.result.Diagnostic;
+import org.osate.result.DiagnosticType;
+import org.osate.result.Result;
+import org.osate.ui.handlers.AbstractInstanceOrDeclarativeModelReadOnlyHandler;
+
+public final class SecurityChecker extends AbstractInstanceOrDeclarativeModelReadOnlyHandler {
+
+ @Override
+ public String getMarkerType() {
+ return "org.osate.analysis.security.ui.SecurityLabelMarker";
+ }
+
+ @Override
+ protected String getActionName() {
+ return "Check security labels";
+ }
+
+ public void invoke(IProgressMonitor monitor, SystemInstance root, SystemOperationMode som) {
+ invoke(monitor, null, root, som);
+ }
+
+ public void invoke(final IProgressMonitor monitor, final AnalysisErrorReporterManager errManager,
+ final SystemInstance root, final SystemOperationMode som) {
+ this.errManager = errManager != null ? errManager
+ : new AnalysisErrorReporterManager(getAnalysisErrorReporterFactory());
+ analyzeInstanceModel(monitor, this.errManager, root, som);
+ }
+
+ @Override
+ protected boolean canAnalyzeDeclarativeModels() {
+ return false;
+ }
+
+ @Override
+ protected void analyzeDeclarativeModel(IProgressMonitor monitor, AnalysisErrorReporterManager errManager,
+ Element declarativeObject) {
+ }
+
+ @Override
+ protected void analyzeInstanceModel(IProgressMonitor monitor, AnalysisErrorReporterManager errManager,
+ SystemInstance root, SystemOperationMode som) {
+ monitor.beginTask(getActionName(), IProgressMonitor.UNKNOWN);
+
+ final SecurityLabelChecker checker = new SecurityLabelChecker(som);
+ AnalysisResult analysisResult = checker.invoke(root);
+
+ for (Result result : analysisResult.getResults()) {
+ for (Diagnostic diag : result.getDiagnostics()) {
+ if (diag.getDiagnosticType() == DiagnosticType.ERROR) {
+ error((Element) diag.getModelElement(), diag.getMessage());
+ } else if (diag.getDiagnosticType() == DiagnosticType.WARNING) {
+ warning((Element) diag.getModelElement(), diag.getMessage());
+ } else if (diag.getDiagnosticType() == DiagnosticType.INFO) {
+ info((Element) diag.getModelElement(), diag.getMessage());
+ }
+ }
+ }
+ monitor.done();
+ }
+}
\ No newline at end of file
diff --git a/analyses/org.osate.analysis.security/.classpath b/analyses/org.osate.analysis.security/.classpath
new file mode 100644
index 00000000000..eca7bdba8f0
--- /dev/null
+++ b/analyses/org.osate.analysis.security/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/analyses/org.osate.analysis.security/.gitignore b/analyses/org.osate.analysis.security/.gitignore
new file mode 100644
index 00000000000..dcca6a5961c
--- /dev/null
+++ b/analyses/org.osate.analysis.security/.gitignore
@@ -0,0 +1,3 @@
+/bin
+target/
+*.jar
diff --git a/analyses/org.osate.analysis.security/.project b/analyses/org.osate.analysis.security/.project
new file mode 100644
index 00000000000..1c7e7aee3a5
--- /dev/null
+++ b/analyses/org.osate.analysis.security/.project
@@ -0,0 +1,85 @@
+
+
+ org.osate.analysis.security
+
+
+
+
+
+ org.eclipse.xtext.ui.shared.xtextBuilder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+ org.eclipse.oomph.version.VersionBuilder
+
+
+ check.feature.closure.completeness
+ true
+
+
+ check.feature.closure.content
+ true
+
+
+ check.maven.pom
+ true
+
+
+ ignore.feature.content.redundancy
+ true
+
+
+ ignore.lower.bound.dependency.ranges
+ false
+
+
+ ignore.schema.builder
+ true
+
+
+ release.path
+ /releng/version-management/release.xml
+
+
+
+
+
+ org.eclipse.xtext.ui.shared.xtextNature
+ org.eclipse.m2e.core.maven2Nature
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+ org.eclipse.oomph.version.VersionNature
+
+
+
+ 1702127013262
+
+ 30
+
+ org.eclipse.core.resources.regexFilterMatcher
+ node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__
+
+
+
+
diff --git a/analyses/org.osate.analysis.security/.settings/org.eclipse.core.resources.prefs b/analyses/org.osate.analysis.security/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 00000000000..99f26c0203a
--- /dev/null
+++ b/analyses/org.osate.analysis.security/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
diff --git a/analyses/org.osate.analysis.security/.settings/org.eclipse.xtend.core.Xtend.prefs b/analyses/org.osate.analysis.security/.settings/org.eclipse.xtend.core.Xtend.prefs
new file mode 100644
index 00000000000..9682a4c0a11
--- /dev/null
+++ b/analyses/org.osate.analysis.security/.settings/org.eclipse.xtend.core.Xtend.prefs
@@ -0,0 +1,7 @@
+//outlet.DEFAULT_OUTPUT.sourceFolder.src/main/java.directory=xtend-gen
+//outlet.DEFAULT_OUTPUT.sourceFolder.src/test/java.directory=src/test/generated-sources/xtend
+BuilderConfiguration.is_project_specific=true
+eclipse.preferences.version=1
+outlet.DEFAULT_OUTPUT.hideLocalSyntheticVariables=true
+outlet.DEFAULT_OUTPUT.installDslAsPrimarySource=false
+outlet.DEFAULT_OUTPUT.userOutputPerSourceFolder=true
diff --git a/analyses/org.osate.analysis.security/META-INF/MANIFEST.MF b/analyses/org.osate.analysis.security/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..dfd7b00771c
--- /dev/null
+++ b/analyses/org.osate.analysis.security/META-INF/MANIFEST.MF
@@ -0,0 +1,22 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.osate.analysis.security;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-ClassPath: .
+Bundle-Activator: org.osate.analysis.security.SecurityPlugin
+Bundle-Vendor: CMU-SEI
+Bundle-Localization: plugin
+Export-Package: org.osate.analysis.security;version="1.0.0"
+Require-Bundle: org.osate.aadl2;bundle-version="[5.0.0,6.0.0)",
+ org.osate.ui;bundle-version="[6.3.0,7.0.0)",
+ org.osate.aadl2.modelsupport;bundle-version="[7.0.0,8.0.0)",
+ org.osate.xtext.aadl2.properties;bundle-version="[3.1.0,4.0.0)",
+ org.osate.results;bundle-version="[3.0.0,4.0.0)",
+ org.osate.security.contributions;bundle-version="[1.0.0,2.0.0)"
+Bundle-ActivationPolicy: lazy
+Import-Package: org.eclipse.e4.core.services.log,
+ org.osate.aadl2.contrib.aadlproject,
+ org.osate.aadl2.contrib.deployment,
+ org.osate.security.contributions;version="[1.0.0,2.0.0)"
+Automatic-Module-Name: org.osate.analysis.security
diff --git a/analyses/org.osate.analysis.security/build.properties b/analyses/org.osate.analysis.security/build.properties
new file mode 100644
index 00000000000..946344c21d7
--- /dev/null
+++ b/analyses/org.osate.analysis.security/build.properties
@@ -0,0 +1,28 @@
+###############################################################################
+# Copyright (c) 2004-2023 Carnegie Mellon University and others. (see Contributors file).
+# All Rights Reserved.
+#
+# NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
+# KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
+# OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
+# MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
+#
+# This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
+# which is available at https://www.eclipse.org/legal/epl-2.0/
+# SPDX-License-Identifier: EPL-2.0
+#
+# Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
+#
+# This program includes and/or can make use of certain third party source code, object code, documentation and other
+# files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
+# configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
+# conditions contained in any such Third Party Software or separate license file distributed with such Third Party
+# Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party beneficiaries
+# to this license with respect to the terms applicable to their Third Party Software. Third Party Software licenses
+# only apply to the Third Party Software and not any other portion of this program or this program as a whole.
+###############################################################################
+bin.includes = META-INF/,\
+ .
+jars.compile.order = .
+source.. = src/
+output.. = bin/
diff --git a/analyses/org.osate.analysis.security/pom.xml b/analyses/org.osate.analysis.security/pom.xml
new file mode 100644
index 00000000000..9509665c1f0
--- /dev/null
+++ b/analyses/org.osate.analysis.security/pom.xml
@@ -0,0 +1,43 @@
+
+
+
+
+ 4.0.0
+
+
+ org.osate
+ analyses.parent
+ 2.14.0-SNAPSHOT
+
+
+ org.osate
+ org.osate.analysis.security
+ 1.0.0-SNAPSHOT
+ eclipse-plugin
+
+
diff --git a/analyses/org.osate.analysis.security/src/org/osate/analysis/security/LabelPropagator.java b/analyses/org.osate.analysis.security/src/org/osate/analysis/security/LabelPropagator.java
new file mode 100644
index 00000000000..14a69e63dc2
--- /dev/null
+++ b/analyses/org.osate.analysis.security/src/org/osate/analysis/security/LabelPropagator.java
@@ -0,0 +1,295 @@
+/*******************************************************************************
+ * Copyright (c) 2004-2023 Carnegie Mellon University and others. (see Contributors file).
+ * All Rights Reserved.
+ *
+ * NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
+ * OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
+ * MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
+ *
+ * This program includes and/or can make use of certain third party source code, object code, documentation and other
+ * files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
+ * configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
+ * conditions contained in any such Third Party Software or separate license file distributed with such Third Party
+ * Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party beneficiaries
+ * to this license with respect to the terms applicable to their Third Party Software. Third Party Software licenses
+ * only apply to the Third Party Software and not any other portion of this program or this program as a whole.
+ *******************************************************************************/
+package org.osate.analysis.security;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.Optional;
+
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.xtext.xbase.lib.Pair;
+import org.osate.aadl2.Aadl2Package;
+import org.osate.aadl2.Element;
+import org.osate.aadl2.Property;
+import org.osate.aadl2.contrib.deployment.DeploymentProperties;
+import org.osate.aadl2.impl.BooleanLiteralImpl;
+import org.osate.aadl2.instance.ComponentInstance;
+import org.osate.aadl2.instance.ConnectionInstance;
+import org.osate.aadl2.instance.ConnectionInstanceEnd;
+import org.osate.aadl2.instance.ConnectionReference;
+import org.osate.aadl2.instance.FeatureInstance;
+import org.osate.aadl2.instance.FlowSpecificationInstance;
+import org.osate.aadl2.instance.InstanceObject;
+import org.osate.aadl2.instance.SystemInstance;
+import org.osate.aadl2.instance.SystemOperationMode;
+import org.osate.aadl2.instance.util.InstanceSwitch;
+import org.osate.aadl2.modelsupport.scoping.Aadl2GlobalScopeUtil;
+
+/**
+ * Propagates a model instance and ensures that all features and components have an associated min/max/current
+ * {@link SecurityLabel}.
+ *
+ */
+@SuppressWarnings("restriction")
+class LabelPropagator extends InstanceSwitch {
+
+ /// Property name used for trusted flow paths
+ public static final String TRUSTED_PROPERTY_NAME = "SecurityClassificationProperties::Trusted";
+
+ private Logger logger = PlatformUI.getWorkbench().getService(org.eclipse.e4.core.services.log.Logger.class);
+
+ /// Operation mode used during this analysis
+ final private SystemOperationMode som;
+
+ LabelPropagator(SystemOperationMode som) {
+ this.som = som;
+ }
+
+ /**
+ * Propagates the security Labels on a System instance.
+ *
+ * @param ci System instance (root)
+ */
+ void propagate(SystemInstance ci) {
+ propagate(ci, Optional.empty());
+ propagateHighestBindings(ci);
+ }
+
+ /**
+ * Propagates component and feature instances contained in the provided instance and determines the {@code upperLimit}, {@code highestChildLabel} and {@code current} security labels.
+ * All three levels will be associated with the current {@code ci}, using the {@link LabelUtil} functionality.
+ *
+ * The current (or default label) is the one associated with the component in the AADL description.
+ * This includes inherited property associations.
+ *
+ * The highestChildLabel is the lowest required security label, based on sub components and features and their respective security labels.
+ *
+ * The upperLimit label is the highest allowed security label which is determined by the encapsulating parent component or {@code ci}'s property association.
+ *
+ * @param ci Propagation starting point
+ * @param parentmax Highest security level of the encapsulating parent component.
+ * @return Security level of {@code ci}, if present
+ */
+ private Optional propagate(ComponentInstance ci, Optional parentmax) {
+ if (!ci.getInModes().isEmpty() && !ci.isActive(som)) {
+ return Optional.empty();
+ }
+
+ Optional current = SecurityLabel.of(ci);
+
+ Optional upperLimit = current.isPresent() ? current : parentmax;
+ Optional highestChild = Optional.empty();
+ highestChild = ci.getComponentInstances()
+ .stream()
+ .reduce(highestChild, (l, c) -> LabelUtil.join(l, propagate(c, upperLimit)), LabelUtil::join);
+ highestChild = ci.getFeatureInstances()
+ .stream()
+ .reduce(highestChild, (l, f) -> LabelUtil.join(l, propagate(f, upperLimit)), LabelUtil::join);
+
+ LabelUtil.setLabel(ci, current);
+ LabelUtil.setHighestChildLabel(ci, highestChild);
+ LabelUtil.setUpperLabelLimit(ci, parentmax);
+ Pair pairStats = countFlows(ci);
+ LabelUtil.setFlowStats(ci, pairStats != null ? Optional.of(pairStats) : Optional.empty());
+
+ logger.info("component " + ci.getName() + ": " + highestChild + " <= " + current + " <= " + parentmax);
+ return current;
+ }
+
+ /**
+ * Propagates feature instances contained in the provided instance and determines the {@code upperLimit}, {@code highestChildLabel} and {@code current} security labels.
+ * All three levels will be associated with the current {@code fi}, using the {@link LabelUtil} functionality.
+ *
+ * The current (or default label) is the one associated with the feature in the AADL description.
+ * This includes inherited property associations.
+ *
+ * The highestChildLabel is the lowest required security label, based on child-features and their respective security labels.
+ *
+ * The upperLimit label is the highest allowed security label which is determined by the encapsulating parent component or {@code fi}'s property association.
+ *
+ * @param fi Propagation starting point
+ * @param parentmax Highest security level of the encapsulating parent component.
+ * @return Security level of {@code fi}, if present
+ */
+ private Optional propagate(FeatureInstance fi, Optional parentmax) {
+ if (!fi.isActive(som)) {
+ return Optional.empty();
+ }
+ Optional current = SecurityLabel.of(fi);
+
+ Optional upperLimit = current.isPresent() ? current : parentmax;
+ Optional highestChild = Optional.empty();
+ highestChild = fi.getFeatureInstances()
+ .stream()
+ .reduce(highestChild, (l, f) -> LabelUtil.join(l, propagate(f, upperLimit)), LabelUtil::join);
+
+ // Propagate Data types
+ if (fi.getType() != null) {
+ highestChild = LabelUtil.join(highestChild, propagate(fi.getType(), upperLimit));
+ }
+
+ LabelUtil.setLabel(fi, current);
+ LabelUtil.setHighestChildLabel(fi, highestChild);
+ LabelUtil.setUpperLabelLimit(fi, parentmax);
+
+ logger.info("feature " + fi.getName() + ": " + highestChild + " <= " + current + " <= " + parentmax);
+ return current;
+ }
+
+ /**
+ * Counts the number of flows and trusted flows for a given component and it's children.
+ *
+ * @param ci Root component
+ * @return Pair of total and trusted components
+ */
+ private Pair countFlows(ComponentInstance ci) {
+ int flows = 0;
+ int trustedFlows = 0;
+ for (FlowSpecificationInstance fsi : ci.getFlowSpecifications()) {
+ // skip all flows which are not active in the current mode
+ if (!fsi.isActive(som)) {
+ continue;
+ }
+ // Skip sinks and sources
+ if (fsi.getSource() == null || fsi.getDestination() == null) {
+ continue;
+ }
+ flows++;
+ trustedFlows += LabelPropagator.isTrusted(fsi, som) ? 1 : 0;
+ }
+
+ // Pair containing total and trusted flow count
+ Pair stats = new Pair<>(flows, trustedFlows);
+
+ for (ComponentInstance instance : ci.getComponentInstances()) {
+ if (!ci.getInModes().isEmpty() && !ci.isActive(som)) {
+ continue;
+ }
+ stats = addFlowStats(stats, countFlows(instance));
+ }
+
+ return stats;
+ }
+
+ /**
+ * Adds two pairs element wise.
+ * @param pair1 First pair
+ * @param pair2 Second pair
+ * @return New pair with element wise added key and value
+ */
+ private Pair addFlowStats(Pair pair1, Pair pair2) {
+ return new Pair<>(pair1.getKey() + pair2.getKey(), pair1.getValue() + pair2.getValue());
+ }
+
+ /**
+ * Traverses the root instance objects and updates all referenced elements (via bindings),
+ * such that they hold the highest bound label.
+ *
+ * @param root element for which binding labels are updated
+ */
+ private void propagateHighestBindings(InstanceObject root) {
+ TreeIterator iter = EcoreUtil.getAllContents(root.eResource(), true);
+ iter.forEachRemaining(e -> instanceSwitch.doSwitch(e));
+ }
+
+ private InstanceSwitch instanceSwitch = new InstanceSwitch() {
+
+ /**
+ * Updates the max binding label in bound elements
+ */
+ @Override
+ public Void caseInstanceObject(InstanceObject io) {
+ if (io instanceof ComponentInstance) {
+ ComponentInstance ci = (ComponentInstance) io;
+ if (!ci.getInModes().isEmpty() && !ci.isActive(som)) {
+ return null;
+ }
+ } else {
+ if (!io.isActive(som)) {
+ return null;
+ }
+ }
+
+ Optional componentLabel = LabelUtil.getLabel(io) != null ? LabelUtil.getLabel(io)
+ : Optional.empty();
+ LinkedList bindings = new LinkedList<>();
+
+ // Add processor, memory, connection and subprogram call bindings
+ bindings.addAll(DeploymentProperties.getActualProcessorBinding(io).orElse(Collections.emptyList()));
+ bindings.addAll(DeploymentProperties.getActualMemoryBinding(io).orElse(Collections.emptyList()));
+ bindings.addAll(DeploymentProperties.getActualConnectionBinding(io).orElse(Collections.emptyList()));
+ bindings.addAll(DeploymentProperties.getActualSubprogramCallBinding(io).orElse(Collections.emptyList()));
+
+ // Go through all bindings and update their highest binding label to incorporate the one of this(current) component
+ for (InstanceObject binding : bindings) {
+ if (!binding.isActive(som)) {
+ continue;
+ }
+ Optional highestBindingLabel = LabelUtil.getHighestBindingLabel(binding) != null
+ ? LabelUtil.getHighestBindingLabel(binding)
+ : Optional.empty();
+
+ if (io instanceof ConnectionInstance || io instanceof ConnectionReference) {
+ // use source, since destination must have a matching label
+ ConnectionInstanceEnd src = (io instanceof ConnectionInstance)
+ ? ((ConnectionInstance) io).getSource()
+ : ((ConnectionReference) io).getSource();
+
+ componentLabel = LabelUtil.getLabel(src) != null ? LabelUtil.getLabel(src) : Optional.empty();
+ }
+ highestBindingLabel = LabelUtil.join(highestBindingLabel, componentLabel);
+ LabelUtil.setHighestBindingLabel(binding, highestBindingLabel);
+ }
+ return null;
+ }
+
+ };
+
+ /**
+ * Retrieves the value of the trusted flag for the provided component.
+ *
+ * @param ci Component for which the trusted property is checked
+ * @return True if the component has the Trusted property and it is set to true
+ */
+ public static boolean isTrusted(InstanceObject io, SystemOperationMode som) {
+ if (!io.isActive(som)) {
+ return false;
+ }
+ Property trustedProperty = Aadl2GlobalScopeUtil.get(io, Aadl2Package.eINSTANCE.getProperty(),
+ TRUSTED_PROPERTY_NAME);
+
+ try {
+ BooleanLiteralImpl booleanImpl = (BooleanLiteralImpl) io.getSimplePropertyValue(trustedProperty);
+ if (booleanImpl != null) {
+ return booleanImpl.getValue();
+ }
+ } catch (Exception e) {
+ return false;
+ }
+ return false;
+ }
+}
diff --git a/analyses/org.osate.analysis.security/src/org/osate/analysis/security/LabelUtil.java b/analyses/org.osate.analysis.security/src/org/osate/analysis/security/LabelUtil.java
new file mode 100644
index 00000000000..86f7f51a3a8
--- /dev/null
+++ b/analyses/org.osate.analysis.security/src/org/osate/analysis/security/LabelUtil.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2004-2023 Carnegie Mellon University and others. (see Contributors file).
+ * All Rights Reserved.
+ *
+ * NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
+ * OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
+ * MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
+ *
+ * This program includes and/or can make use of certain third party source code, object code, documentation and other
+ * files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
+ * configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
+ * conditions contained in any such Third Party Software or separate license file distributed with such Third Party
+ * Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party beneficiaries
+ * to this license with respect to the terms applicable to their Third Party Software. Third Party Software licenses
+ * only apply to the Third Party Software and not any other portion of this program or this program as a whole.
+ *******************************************************************************/
+package org.osate.analysis.security;
+
+import java.util.Optional;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.xtext.xbase.lib.Pair;
+import org.osate.aadl2.instance.InstanceObject;
+
+/**
+ * Utility class for Security labels. This class contains wrapping Functions for easy access to labels of instance objects.
+ *
+ */
+final class LabelUtil {
+
+ private LabelUtil() {
+ }
+
+ private static AdapterFactory adapterFactory = SecurityCheckAdapterFactory.INSTANCE;
+
+ static void setLabel(InstanceObject io, Optional label) {
+ SecurityCheckData data = (SecurityCheckData) adapterFactory.adapt(io, SecurityCheckData.class);
+ data.setLabel(label);
+ }
+
+ static Optional getLabel(InstanceObject io) {
+ SecurityCheckData data = (SecurityCheckData) adapterFactory.adapt(io, SecurityCheckData.class);
+ return data.getLabel();
+ }
+
+ static void setHighestChildLabel(InstanceObject io, Optional label) {
+ SecurityCheckData data = (SecurityCheckData) adapterFactory.adapt(io, SecurityCheckData.class);
+ data.setHighestChildLabel(label);
+ }
+
+ static Optional getHighestChildLabel(InstanceObject io) {
+ SecurityCheckData data = (SecurityCheckData) adapterFactory.adapt(io, SecurityCheckData.class);
+ return data.getHighestChildLabel();
+ }
+
+ static void setHighestBindingLabel(InstanceObject io, Optional label) {
+ SecurityCheckData data = (SecurityCheckData) adapterFactory.adapt(io, SecurityCheckData.class);
+ data.setHighestBindingLabel(label);
+ }
+
+ static Optional getHighestBindingLabel(InstanceObject io) {
+ SecurityCheckData data = (SecurityCheckData) adapterFactory.adapt(io, SecurityCheckData.class);
+ return data.getHighestBindingLabel();
+ }
+
+ static void setUpperLabelLimit(InstanceObject io, Optional label) {
+ SecurityCheckData data = (SecurityCheckData) adapterFactory.adapt(io, SecurityCheckData.class);
+ data.setUpperLabelLimit(label);
+ }
+
+ static Optional getUpperLabelLimit(InstanceObject io) {
+ SecurityCheckData data = (SecurityCheckData) adapterFactory.adapt(io, SecurityCheckData.class);
+ return data.getUpperLabelLimit();
+ }
+
+ static void setFlowStats(InstanceObject io, Optional> stats) {
+ SecurityCheckData data = (SecurityCheckData) adapterFactory.adapt(io, SecurityCheckData.class);
+ data.setFlowStats(stats);
+ }
+
+ static Optional> getFlowStats(InstanceObject io) {
+ SecurityCheckData data = (SecurityCheckData) adapterFactory.adapt(io, SecurityCheckData.class);
+ return data.getFlowStats();
+ }
+
+ /**
+ * Meets two {@link Optional} security labels, according to {@link SecurityLabel#meet(Optional)}.
+ *
+ * @param l1 First security label
+ * @param l2 Second security label
+ * @return
+ */
+ static Optional meet(Optional l1, Optional l2) {
+ if (l1.isPresent() && l2.isPresent()) {
+ return Optional.of(l1.get().meet(l2.get()));
+ }
+ if (l1.isPresent()) {
+ return l1;
+ }
+ if (l2.isPresent()) {
+ return l2;
+ }
+ return Optional.empty();
+ }
+
+ /**
+ * Joins two {@link Optional} security labels together according to {@link SecurityLabel#join(SecurityLabel)}
+ *
+ * @param l1 First security label
+ * @param l2 Second security label
+ * @return combined security label, may be empty if both {@code l1} and {@code l2} are empty
+ */
+ static Optional join(Optional l1, Optional l2) {
+ if (l1.isPresent() && l2.isPresent()) {
+ return Optional.of(l1.get().join(l2.get()));
+ }
+ if (l1.isPresent()) {
+ return l1;
+ }
+ if (l2.isPresent()) {
+ return l2;
+ }
+ return Optional.empty();
+ }
+
+}
diff --git a/analyses/org.osate.analysis.security/src/org/osate/analysis/security/SecurityCheckAdapter.java b/analyses/org.osate.analysis.security/src/org/osate/analysis/security/SecurityCheckAdapter.java
new file mode 100644
index 00000000000..204ad2b1465
--- /dev/null
+++ b/analyses/org.osate.analysis.security/src/org/osate/analysis/security/SecurityCheckAdapter.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2004-2023 Carnegie Mellon University and others. (see Contributors file).
+ * All Rights Reserved.
+ *
+ * NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
+ * OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
+ * MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
+ *
+ * This program includes and/or can make use of certain third party source code, object code, documentation and other
+ * files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
+ * configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
+ * conditions contained in any such Third Party Software or separate license file distributed with such Third Party
+ * Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party beneficiaries
+ * to this license with respect to the terms applicable to their Third Party Software. Third Party Software licenses
+ * only apply to the Third Party Software and not any other portion of this program or this program as a whole.
+ *******************************************************************************/
+package org.osate.analysis.security;
+
+import java.util.Optional;
+
+import org.eclipse.emf.common.notify.impl.AdapterImpl;
+import org.eclipse.xtext.xbase.lib.Pair;
+
+class SecurityCheckAdapter extends AdapterImpl implements SecurityCheckData {
+
+ protected Optional current;
+
+ protected Optional highestChildLabel;
+
+ protected Optional upperLabelLimit;
+
+ protected Optional highestBindingLabel;
+
+ protected Optional> flowStats;
+
+ @Override
+ public void setLabel(Optional label) {
+ current = label;
+ }
+
+ @Override
+ public Optional getLabel() {
+ return current;
+ }
+
+ @Override
+ public void setHighestChildLabel(Optional label) {
+ highestChildLabel = label;
+ }
+
+ @Override
+ public void setFlowStats(Optional> stats) {
+ flowStats = stats;
+ }
+
+ @Override
+ public void setUpperLabelLimit(Optional label) {
+ upperLabelLimit = label;
+ }
+
+ @Override
+ public void setHighestBindingLabel(Optional label) {
+ highestBindingLabel = label;
+ }
+
+ @Override
+ public Optional getHighestChildLabel() {
+ return highestChildLabel;
+ }
+
+ @Override
+ public Optional getUpperLabelLimit() {
+ return upperLabelLimit;
+ }
+
+ @Override
+ public Optional getHighestBindingLabel() {
+ return highestBindingLabel;
+ }
+
+ @Override
+ public Optional> getFlowStats() {
+ return flowStats;
+ }
+
+ @Override
+ public boolean isAdapterForType(Object type) {
+ return type == SecurityCheckData.class;
+ }
+}
\ No newline at end of file
diff --git a/analyses/org.osate.analysis.security/src/org/osate/analysis/security/SecurityCheckAdapterFactory.java b/analyses/org.osate.analysis.security/src/org/osate/analysis/security/SecurityCheckAdapterFactory.java
new file mode 100644
index 00000000000..8aad0f80b8c
--- /dev/null
+++ b/analyses/org.osate.analysis.security/src/org/osate/analysis/security/SecurityCheckAdapterFactory.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2004-2023 Carnegie Mellon University and others. (see Contributors file).
+ * All Rights Reserved.
+ *
+ * NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
+ * OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
+ * MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
+ *
+ * This program includes and/or can make use of certain third party source code, object code, documentation and other
+ * files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
+ * configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
+ * conditions contained in any such Third Party Software or separate license file distributed with such Third Party
+ * Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party beneficiaries
+ * to this license with respect to the terms applicable to their Third Party Software. Third Party Software licenses
+ * only apply to the Third Party Software and not any other portion of this program or this program as a whole.
+ *******************************************************************************/
+package org.osate.analysis.security;
+
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl;
+
+public class SecurityCheckAdapterFactory extends AdapterFactoryImpl {
+
+ public static final AdapterFactory INSTANCE = new SecurityCheckAdapterFactory();
+
+ @Override
+ public boolean isFactoryForType(Object type) {
+ return type == SecurityCheckData.class;
+ }
+
+ @Override
+ protected Adapter createAdapter(Notifier target) {
+ return new SecurityCheckAdapter();
+ }
+}
diff --git a/analyses/org.osate.analysis.security/src/org/osate/analysis/security/SecurityCheckData.java b/analyses/org.osate.analysis.security/src/org/osate/analysis/security/SecurityCheckData.java
new file mode 100644
index 00000000000..5758ff6b2e5
--- /dev/null
+++ b/analyses/org.osate.analysis.security/src/org/osate/analysis/security/SecurityCheckData.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2004-2023 Carnegie Mellon University and others. (see Contributors file).
+ * All Rights Reserved.
+ *
+ * NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
+ * OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
+ * MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
+ *
+ * This program includes and/or can make use of certain third party source code, object code, documentation and other
+ * files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
+ * configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
+ * conditions contained in any such Third Party Software or separate license file distributed with such Third Party
+ * Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party beneficiaries
+ * to this license with respect to the terms applicable to their Third Party Software. Third Party Software licenses
+ * only apply to the Third Party Software and not any other portion of this program or this program as a whole.
+ *******************************************************************************/
+package org.osate.analysis.security;
+
+import java.util.Optional;
+
+import org.eclipse.xtext.xbase.lib.Pair;
+
+interface SecurityCheckData {
+
+ void setLabel(Optional label);
+
+ Optional getLabel();
+
+ void setHighestChildLabel(Optional label);
+
+ Optional getHighestChildLabel();
+
+ void setUpperLabelLimit(Optional label);
+
+ Optional getUpperLabelLimit();
+
+ void setHighestBindingLabel(Optional label);
+
+ Optional getHighestBindingLabel();
+
+ void setFlowStats(Optional> stats);
+
+ Optional> getFlowStats();
+}
\ No newline at end of file
diff --git a/analyses/org.osate.analysis.security/src/org/osate/analysis/security/SecurityLabel.java b/analyses/org.osate.analysis.security/src/org/osate/analysis/security/SecurityLabel.java
new file mode 100644
index 00000000000..17cf78676b3
--- /dev/null
+++ b/analyses/org.osate.analysis.security/src/org/osate/analysis/security/SecurityLabel.java
@@ -0,0 +1,322 @@
+/*******************************************************************************
+ * Copyright (c) 2004-2023 Carnegie Mellon University and others. (see Contributors file).
+ * All Rights Reserved.
+ *
+ * NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
+ * OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
+ * MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
+ *
+ * This program includes and/or can make use of certain third party source code, object code, documentation and other
+ * files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
+ * configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
+ * conditions contained in any such Third Party Software or separate license file distributed with such Third Party
+ * Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party beneficiaries
+ * to this license with respect to the terms applicable to their Third Party Software. Third Party Software licenses
+ * only apply to the Third Party Software and not any other portion of this program or this program as a whole.
+ *******************************************************************************/
+package org.osate.analysis.security;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+
+import org.osate.aadl2.Aadl2Package;
+import org.osate.aadl2.EnumerationLiteral;
+import org.osate.aadl2.EnumerationType;
+import org.osate.aadl2.ListType;
+import org.osate.aadl2.ListValue;
+import org.osate.aadl2.NamedElement;
+import org.osate.aadl2.NamedValue;
+import org.osate.aadl2.Property;
+import org.osate.aadl2.PropertyExpression;
+import org.osate.aadl2.modelsupport.scoping.Aadl2GlobalScopeUtil;
+
+public class SecurityLabel {
+
+ /// lowest possible security label
+ public static final SecurityLabel MIN = new SecurityLabel(1, Collections.emptySet());
+
+ /// Property name used for security levels
+ public static final String LEVEL_PROPERTY_NAME = "SecurityClassificationProperties::Security_Level";
+
+ /// Property name used for security categories
+ public static final String CATEGORY_PROPERTY_NAME = "SecurityClassificationProperties::Security_Level_Caveats";
+
+ /// Available security levels, based on the user-provided configuration
+ private static Property levelProperty = null;
+
+ /// Available security categories, based on the user-provided configuration
+ private static Property categoryProperty = null;
+
+ /// Lookup map from literals to levels
+ private static Map literal2level = new HashMap();
+
+ /// Lookup map from integer levels to literals
+ private static Map level2literal = new HashMap();
+
+ /// Set of available categories
+ private static Set maxCategories = new HashSet();
+
+ /// Level of this security label object
+ private Integer level;
+
+ /// categories used by this security label object
+ private Set categories;
+
+ /**
+ * Constructs a {@link SecurityLabel} based on the given level and categories
+ *
+ * @param level level of this label
+ * @param catgories categories of this label
+ */
+ public SecurityLabel(Integer level, Set categories) {
+ this.level = level;
+ this.categories = new TreeSet((e1, e2) -> e1.getName().compareToIgnoreCase(e2.getName()));
+ this.categories.addAll(categories);
+ }
+
+ /**
+ * Determines the Security label of the named element in relation to the first seen level/category definition.
+ *
+ * @param ne Element for which the security level will be determined
+ * @return Security label held by the element or empty if not
+ */
+ public static Optional of(NamedElement ne) {
+ init(ne);
+
+ int level = -1;
+ try {
+ NamedValue levelValue = (NamedValue) ne.getSimplePropertyValue(levelProperty);
+ EnumerationLiteral levelLiteral = (EnumerationLiteral) levelValue.getNamedValue();
+ level = literal2level.get(levelLiteral);
+ } catch (Exception e) {
+ return Optional.empty();
+ }
+ try {
+ Set tags = new HashSet();
+ ListValue caveatsValue = (ListValue) ne.getSimplePropertyValue(categoryProperty);
+ List lelems = caveatsValue.getOwnedListElements();
+ for (PropertyExpression nv : lelems) {
+ EnumerationLiteral literal = (EnumerationLiteral) ((NamedValue) nv).getNamedValue();
+ tags.add(literal);
+ }
+ return Optional.of(new SecurityLabel(level, tags));
+ } catch (Exception e) {
+ return Optional.empty();
+ }
+ }
+
+ /**
+ * Initializes {@link SecurityLabel#levelProperty} and {@link SecurityLabel#categoryProperty} based on the provided element.
+ * Updates the {@link SecurityLabel#literal2level} and {@link SecurityLabel#level2literal} lookup tables based on aforementioned values.
+ *
+ * @param ne Element used for initialization
+ */
+ private static void init(NamedElement ne) {
+ Property newLevelProperty = Aadl2GlobalScopeUtil.get(ne, Aadl2Package.eINSTANCE.getProperty(),
+ LEVEL_PROPERTY_NAME);
+ Property newCategoryProperty = Aadl2GlobalScopeUtil.get(ne, Aadl2Package.eINSTANCE.getProperty(),
+ CATEGORY_PROPERTY_NAME);
+
+ // Update the reference property level/category in case they changed or are unknown
+ if (levelProperty != newLevelProperty || categoryProperty != newCategoryProperty) {
+ levelProperty = newLevelProperty;
+ categoryProperty = newCategoryProperty;
+
+ literal2level.clear();
+ level2literal.clear();
+ EnumerationType levelType = (EnumerationType) levelProperty.getOwnedPropertyType();
+ List literals = levelType.getOwnedLiterals();
+ for (int i = 0; i < literals.size(); i += 1) {
+ // enumeration is ordered from high to low security
+ int index = literals.size() - i;
+ literal2level.put(literals.get(i), index);
+ level2literal.put(index, literals.get(i));
+ }
+
+ // Get all existing categories
+ ListType categoryType = (ListType) categoryProperty.getOwnedPropertyType();
+ EnumerationType categoryElements = (EnumerationType) categoryType.getOwnedElementType();
+ List categories = categoryElements.getOwnedLiterals();
+
+ maxCategories.clear();
+ maxCategories.addAll(categories);
+ }
+ }
+
+ /**
+ * Gets the security level of this {@link SecurityLabel}
+ *
+ * @return Level of this {@link SecurityLabel}
+ */
+ public Integer getLevel() {
+ return level;
+ }
+
+ /**
+ * Sets the security level of this {@link SecurityLabel}.
+ * Level must be in range of {@link SecurityLabel#level2literal}.
+ *
+ * @param new security level
+ */
+ public void setLevel(Integer level) throws IllegalArgumentException {
+ if (!level2literal.containsKey(level)) {
+ throw new IllegalArgumentException("Security level: " + level + "is not defined.");
+ }
+ this.level = level;
+ }
+
+ /**
+ * Gets the security categories of this {@link SecurityLabel}.
+ *
+ * @return Categories used in this label
+ */
+ public Set getCategories() {
+ return categories;
+ }
+
+ /**
+ * Sets the categories used in this {@link SecurityLabel}.
+ * All categories passed must be in {@link SecurityLabel#categoryProperty}
+ *
+ * @param new categories
+ */
+ public void setTags(Set categories) {
+ if (!maxCategories.containsAll(categories)) {
+ throw new IllegalArgumentException(
+ "Security categories: " + categories + " are not compliant with property set definitions.");
+ }
+
+ this.categories = categories;
+ }
+
+ @Override
+ public String toString() {
+ return "SecurityLabel [" + level2literal.get(level).getName() + ", "
+ + categories.stream().map(EnumerationLiteral::getName).collect(Collectors.joining(", ", "{", "}"))
+ + "]";
+ }
+
+ /**
+ * Combined HashCode based on level and categories
+ */
+ @Override
+ public int hashCode() {
+ return Objects.hash(level, categories);
+ }
+
+ /**
+ * Checks if two {@link SecurityLabel}s are identical. (same level and categories)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ SecurityLabel other = (SecurityLabel) obj;
+ if (level != other.level) {
+ return false;
+ }
+ if (categories == null) {
+ if (categories != null) {
+ return false;
+ }
+ } else if (!categories.equals(other.categories)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Checks if {@code this} {@link SecurityLabel} dominated {@code that}.
+ * Note: A security labels dominates another security label, if and only if, it has the same or a higher level
+ * and contains all categories of the other security label.
+ *
+ * @param that Other security label
+ * @return True if {@code this} dominates {@code that}
+ */
+ public boolean dominates(SecurityLabel that) {
+ return this.level >= that.level && categories.containsAll(that.categories);
+ }
+
+ /**
+ * Checks if one Security level is greater than the other.
+ * This check returns false, if both have the same security requirements.
+ *
+ * @param that Other security label
+ * @return True if {@code this} has a higher Security level than {@code that}.
+ */
+ public boolean greaterThan(SecurityLabel that) {
+ return this.dominates(that) && !this.equals(that);
+ }
+
+ /**
+ * Checks if one Security level is lower than the other.
+ * This check return false, if both have the same security requirement.
+ *
+ * @param that Other security label
+ * @return True {@code this} has a lower Security Level than {@code that}.
+ */
+ public boolean lessThan(SecurityLabel that) {
+ return that.dominates(this) && !this.equals(that);
+ }
+
+ /**
+ * Joins this Security label with {@code that}. The result of this operation is a Security label
+ * with the larger level of the two inputs and the combined set of categories.
+ *
+ * @param that Other security label
+ * @return security label with least highest combined privileges
+ */
+ public SecurityLabel join(SecurityLabel that) {
+ HashSet allCategories = new HashSet<>(categories);
+ allCategories.addAll(that.categories);
+ return new SecurityLabel(Math.max(this.level, that.level), allCategories);
+ }
+
+ /**
+ * {@link SecurityLabel#meet(SecurityLabel)}s two Security labels, if that is present.
+ * @param that Optional other security label
+ * @return Result of {@link #meet(SecurityLabel)} if {@code that} is present
+ */
+ public SecurityLabel meet(Optional that) {
+ if (that.isPresent()) {
+ return meet(that.get());
+ }
+ return this;
+ }
+
+ /**
+ * Returns the lower bound of {@code this} and {@code that} security label.
+ * The result of this operation is a security label with the lower security level and categories, which are only accessible by both labels.
+ *
+ * @param that Other security label
+ * @return new security label containing the lower level and common categories
+ */
+ public SecurityLabel meet(SecurityLabel that) {
+ HashSet commonCategories = new HashSet<>(categories);
+ commonCategories.removeAll(that.categories);
+ return new SecurityLabel(Math.min(this.level, that.level), commonCategories);
+ }
+
+}
diff --git a/analyses/org.osate.analysis.security/src/org/osate/analysis/security/SecurityLabelChecker.java b/analyses/org.osate.analysis.security/src/org/osate/analysis/security/SecurityLabelChecker.java
new file mode 100644
index 00000000000..d03f1283c2c
--- /dev/null
+++ b/analyses/org.osate.analysis.security/src/org/osate/analysis/security/SecurityLabelChecker.java
@@ -0,0 +1,779 @@
+/*******************************************************************************
+ * Copyright (c) 2004-2023 Carnegie Mellon University and others. (see Contributors file).
+ * All Rights Reserved.
+ *
+ * NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
+ * OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
+ * MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
+ *
+ * This program includes and/or can make use of certain third party source code, object code, documentation and other
+ * files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
+ * configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
+ * conditions contained in any such Third Party Software or separate license file distributed with such Third Party
+ * Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party beneficiaries
+ * to this license with respect to the terms applicable to their Third Party Software. Third Party Software licenses
+ * only apply to the Third Party Software and not any other portion of this program or this program as a whole.
+ *******************************************************************************/
+package org.osate.analysis.security;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.xtext.xbase.lib.Pair;
+import org.osate.aadl2.Classifier;
+import org.osate.aadl2.DirectionType;
+import org.osate.aadl2.Element;
+import org.osate.aadl2.Feature;
+import org.osate.aadl2.NamedElement;
+import org.osate.aadl2.PropertyAssociation;
+import org.osate.aadl2.contrib.deployment.DeploymentProperties;
+import org.osate.aadl2.instance.AnnexInstance;
+import org.osate.aadl2.instance.ComponentInstance;
+import org.osate.aadl2.instance.ConnectionInstance;
+import org.osate.aadl2.instance.ConnectionInstanceEnd;
+import org.osate.aadl2.instance.ConnectionReference;
+import org.osate.aadl2.instance.FeatureInstance;
+import org.osate.aadl2.instance.FlowSpecificationInstance;
+import org.osate.aadl2.instance.InstanceObject;
+import org.osate.aadl2.instance.SystemInstance;
+import org.osate.aadl2.instance.SystemOperationMode;
+import org.osate.aadl2.instance.util.InstanceSwitch;
+import org.osate.result.AnalysisResult;
+import org.osate.result.Result;
+import org.osate.result.util.ResultUtil;
+
+@SuppressWarnings("restriction")
+public class SecurityLabelChecker {
+
+ private Logger logger = PlatformUI.getWorkbench().getService(org.eclipse.e4.core.services.log.Logger.class);
+
+ private static final Boolean DONE = Boolean.TRUE;
+
+ private static final Boolean PRUNE = Boolean.FALSE;
+
+ Result result;
+
+ /// Operation mode used during this analysis
+ final private SystemOperationMode som;
+
+ public SecurityLabelChecker(SystemOperationMode som) {
+ this.som = som;
+ }
+
+ public AnalysisResult invoke(SystemInstance root) {
+ AnalysisResult analysisResult = ResultUtil.createAnalysisResult("Security", root);
+
+ if (som.getCurrentModes().size() > 0) {
+ for (ComponentInstance ci : root.getAllComponentInstances()) {
+ ci.setCurrentMode(som.getCurrentModes().get(0));
+ }
+ root.setCurrentSystemOperationMode(som);
+ }
+
+ LabelPropagator propagator = new LabelPropagator(som);
+ propagator.propagate(root);
+ result = ResultUtil.createResult("", root);
+ analysisResult.getResults().add(result);
+
+ for (TreeIterator iter = EcoreUtil.getAllContents(root.eResource(), true); iter.hasNext();) {
+ Element elem = iter.next();
+ if (instanceSwitch.doSwitch(elem) == PRUNE) {
+ iter.prune();
+ }
+ }
+
+ return analysisResult;
+ }
+
+ private InstanceSwitch instanceSwitch = new InstanceSwitch() {
+
+ /**
+ * Check if component containment complies with the security policy.
+ * Compare component's security label with the label of its container.
+ */
+ @Override
+ public Boolean caseComponentInstance(ComponentInstance ci) {
+ if (!ci.getInModes().isEmpty() && !ci.isActive(som)) {
+ return PRUNE;
+ }
+
+ // Annotate flow statistics
+ Optional> flowStats = LabelUtil.getFlowStats(ci) != null ? LabelUtil.getFlowStats(ci)
+ : Optional.empty();
+ flowStats.ifPresent(stats -> {
+ if (stats.getKey() > 0) {
+ String msg = "Component has " + stats.getKey() + " (nested) flows of which " + stats.getValue()
+ + " are trusted.";
+ logger.info("Componet " + ci.getName() + msg);
+ result.getDiagnostics().add(ResultUtil.createInfoDiagnostic(msg, ci));
+ }
+ });
+
+ checkValidContainment(ci);
+ checkBindingLeastPrivileges(ci);
+ checkValidBindings(ci);
+ findHiddenFlows(ci);
+ return DONE;
+ }
+
+ /**
+ * Check feature for security policy compliance:
+ * Security labels of feature and associated data type must conform
+ * to policy.
+ */
+ @Override
+ public Boolean caseFeatureInstance(FeatureInstance fi) {
+ if (!fi.isActive(som)) {
+ return PRUNE;
+ }
+
+ checkFeatureClassifierLabelEquality(fi);
+ checkValidContainment(fi);
+ checkBindingLeastPrivileges(fi);
+ checkValidBindings(fi);
+ return DONE;
+ }
+
+ /**
+ * Check connection instance for security policy compliance:
+ * Data flow from source and destination label must conform to policy.
+ */
+ @Override
+ public Boolean caseConnectionInstance(final ConnectionInstance conni) {
+ if (!conni.isActive(som)) {
+ return PRUNE;
+ }
+ ConnectionInstanceEnd src = conni.getSource();
+ ConnectionInstanceEnd dst = conni.getDestination();
+
+ checkSameLabel(conni, src, dst);
+ checkBindingLeastPrivileges(conni);
+ checkValidBindings(conni);
+ return DONE;
+ }
+
+ /**
+ * Check connection reference for security policy compliance:
+ * Data flow from source and destination label must be identical
+ */
+ @Override
+ public Boolean caseConnectionReference(ConnectionReference cref) {
+ if (!cref.isActive(som)) {
+ return PRUNE;
+ }
+ ConnectionInstanceEnd src = cref.getSource();
+ ConnectionInstanceEnd dst = cref.getDestination();
+
+ checkSameLabel(cref, src, dst);
+ checkBindingLeastPrivileges(cref);
+ checkValidBindings(cref);
+ return PRUNE;
+ }
+
+ @Override
+ public Boolean caseEndToEndFlowInstance(org.osate.aadl2.instance.EndToEndFlowInstance object) {
+ return PRUNE;
+ };
+
+ @Override
+ public Boolean caseSystemOperationMode(org.osate.aadl2.instance.SystemOperationMode object) {
+ return DONE;
+ };
+
+ @Override
+ public Boolean caseAnnexInstance(AnnexInstance object) {
+ return PRUNE;
+ }
+
+ @Override
+ public Boolean casePropertyAssociation(PropertyAssociation object) {
+ return PRUNE;
+ }
+
+ /**
+ * Check flow specification for security policy compliance:
+ * Data flow from source and destination label must conform to policy.
+ */
+ @Override
+ public Boolean caseFlowSpecificationInstance(FlowSpecificationInstance fsi) {
+ if (!fsi.isActive(som)) {
+ return PRUNE;
+ }
+ NamedElement src = fsi.getSource();
+ NamedElement dst = fsi.getDestination();
+
+ return checkValidFlow(fsi, src, dst);
+ }
+
+ };
+
+ /**
+ * Checks if the classifier related to a feature instance has the same security label.
+ * If not a warning is added to the feature instance.
+ *
+ * @param fi Feature instance on which the classifier label equality property will be checked.
+ */
+ private void checkFeatureClassifierLabelEquality(FeatureInstance fi) {
+ if (!fi.isActive(som)) {
+ return;
+ }
+ Optional label = LabelUtil.getLabel(fi) != null ? LabelUtil.getLabel(fi) : Optional.empty();
+
+ // Check feature equality
+ Feature feature = fi.getFeature();
+ if (feature != null) {
+ Classifier classifier = feature.getClassifier();
+ if (classifier != null) {
+ Optional classifierLabel = SecurityLabel.of(classifier);
+
+ if (label.isPresent() && classifierLabel.isPresent()) {
+ if (!label.get().equals(classifierLabel.get())) {
+ String msg = "Security label of feature " + fi.getName() + " " + label.get()
+ + " and it's feature classifier " + classifierLabel.get() + " must be equal.";
+ result.getDiagnostics().add(ResultUtil.createErrorDiagnostic(msg, fi));
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks if the relation between components, parents and children are valid.
+ *
+ * @param io Object to evaluate.
+ */
+ private void checkValidContainment(InstanceObject io) {
+ // Skip inactive objects
+ if (!isActiveInstanceObject(io)) {
+ return;
+ }
+ Optional childLimit = LabelUtil.getHighestChildLabel(io) != null
+ ? LabelUtil.getHighestChildLabel(io)
+ : Optional.empty();
+ Optional upperLimit = LabelUtil.getUpperLabelLimit(io) != null ? LabelUtil.getUpperLabelLimit(io)
+ : Optional.empty();
+ Optional label = LabelUtil.getLabel(io) != null ? LabelUtil.getLabel(io) : Optional.empty();
+
+ if (upperLimit.isPresent() && childLimit.isPresent() && !(upperLimit.get()).dominates(childLimit.get())) {
+ String msg = "Inconsistent security labels: " + io.getQualifiedName() + " has no valid security label. "
+ + "Has children requiring label: " + childLimit.get() + ". Parent requires: " + upperLimit.get()
+ + ".";
+ result.getDiagnostics().add(ResultUtil.createErrorDiagnostic(msg, io));
+ }
+ upperLimit.ifPresent(limit -> {
+ if (label.isPresent()) {
+ SecurityLabel l = label.get();
+
+ if (!limit.dominates(l)) {
+ String msg = "Security label not dominated by " + limit.toString() + " of containing element";
+ result.getDiagnostics().add(ResultUtil.createErrorDiagnostic(msg, io));
+ }
+ } else {
+ String msg = "Missing security label, must be dominated by " + limit.toString();
+ result.getDiagnostics().add(ResultUtil.createWarningDiagnostic(msg, io));
+ }
+ });
+ childLimit.ifPresent(limit -> {
+ if (label.isPresent()) {
+ SecurityLabel l = label.get();
+
+ if (!l.dominates(limit)) {
+ String msg = "Security label does not dominate " + limit.toString();
+ result.getDiagnostics().add(ResultUtil.createErrorDiagnostic(msg, io));
+ } else if (l.greaterThan(limit)) {
+ String msg = "Least privilege violation: Label should be " + limit.toString();
+ result.getDiagnostics().add(ResultUtil.createWarningDiagnostic(msg, io));
+ }
+ } else {
+ String msg = "Missing security label: should be " + childLimit.toString();
+ result.getDiagnostics().add(ResultUtil.createWarningDiagnostic(msg, io));
+ }
+ });
+ }
+
+ /**
+ * Check if connection instances have valid security labels on both ends.
+ *
+ * @param conn connection instance
+ * @param src connection source
+ * @param dst connection destination
+ */
+ private void checkSameLabel(InstanceObject conn, ConnectionInstanceEnd src, ConnectionInstanceEnd dst) {
+ if (!conn.isActive(som)) {
+ return;
+ }
+ Optional srcLabel = LabelUtil.getLabel(src) != null ? LabelUtil.getLabel(src) : Optional.empty();
+ Optional dstLabel = LabelUtil.getLabel(dst) != null ? LabelUtil.getLabel(dst) : Optional.empty();
+
+ if (!srcLabel.isPresent() && !dstLabel.isPresent()) {
+ String msg = "Missing security labels on connection ends";
+ result.getDiagnostics().add(ResultUtil.createInfoDiagnostic(msg, conn));
+ } else {
+ if (srcLabel.isPresent()) {
+ SecurityLabel sl = srcLabel.get();
+ if (dstLabel.isPresent()) {
+ SecurityLabel dl = dstLabel.get();
+
+ if (!sl.equals(dl)) {
+ String msg = "Source security label " + sl.toString() + " does not match destination "
+ + dl.toString();
+ result.getDiagnostics().add(ResultUtil.createErrorDiagnostic(msg, conn));
+ }
+ } else {
+ String msg = "Missing security label on destination end: should be " + sl.toString();
+ result.getDiagnostics().add(ResultUtil.createWarningDiagnostic(msg, conn));
+ }
+ } else {
+ dstLabel.ifPresent(dl -> {
+ String msg = "Missing security label on source end: should be " + dl.toString();
+ result.getDiagnostics().add(ResultUtil.createWarningDiagnostic(msg, conn));
+ });
+ }
+ }
+ }
+
+ /**
+ * Checks for least privilege violation in binding references.
+ *
+ * @param io Component referenced in binding
+ */
+ private void checkBindingLeastPrivileges(InstanceObject io) {
+ // Skip inactive objects
+ if (!isActiveInstanceObject(io)) {
+ return;
+ }
+
+ // Retrieve component label and it's highest binding label
+ Optional componentLabel = LabelUtil.getLabel(io) != null ? LabelUtil.getLabel(io)
+ : Optional.empty();
+ Optional highestBindingLabel = LabelUtil.getHighestBindingLabel(io) != null
+ ? LabelUtil.getHighestBindingLabel(io)
+ : Optional.empty();
+
+ if (componentLabel.isPresent() && highestBindingLabel.isPresent()) {
+ SecurityLabel label = componentLabel.get();
+ SecurityLabel bindingLabel = highestBindingLabel.get();
+
+ // Check for lest privilege violation
+ if (label.greaterThan(bindingLabel)) {
+ String msg = "Least privilege violation(Binding): Label should be " + bindingLabel.toString();
+ result.getDiagnostics().add(ResultUtil.createWarningDiagnostic(msg, io));
+ }
+ } else if (!componentLabel.isPresent() && highestBindingLabel.isPresent()) {
+ // Missing label warning on bound component
+ SecurityLabel bindingLabel = highestBindingLabel.get();
+ String msg = "Missing security label: should be " + bindingLabel.toString();
+ result.getDiagnostics().add(ResultUtil.createWarningDiagnostic(msg, io));
+ }
+
+ }
+
+ /**
+ * Checks if software-hardware bindings are valid.
+ * The hardware component to which some other software component is bound must dominate the label of the software component.
+ *
+ * @param io Object to check binding for
+ */
+ private void checkValidBindings(InstanceObject io) {
+ if (!isActiveInstanceObject(io)) {
+ return;
+ }
+ Optional label;
+
+ // Retrieve indirect label from connection data
+ if (io instanceof ConnectionInstance || io instanceof ConnectionReference) {
+ ConnectionInstanceEnd src = (io instanceof ConnectionInstance) ? ((ConnectionInstance) io).getSource()
+ : ((ConnectionReference) io).getSource();
+
+ // use source, since destination must have a matching label
+ label = LabelUtil.getLabel(src) != null ? LabelUtil.getLabel(src) : Optional.empty();
+ } else {
+ // Retrieve label from instance object
+ label = LabelUtil.getLabel(io) != null ? LabelUtil.getLabel(io) : Optional.empty();
+ }
+
+ LinkedList bindings = new LinkedList<>();
+
+ // Add processor, memory, connection and subprogram call bindings
+ bindings.addAll(DeploymentProperties.getActualProcessorBinding(io).orElse(Collections.emptyList()));
+ bindings.addAll(DeploymentProperties.getActualMemoryBinding(io).orElse(Collections.emptyList()));
+ bindings.addAll(DeploymentProperties.getActualConnectionBinding(io).orElse(Collections.emptyList()));
+ bindings.addAll(DeploymentProperties.getActualSubprogramCallBinding(io).orElse(Collections.emptyList()));
+
+ // Add warnings/errors if bindings are present
+ if (!bindings.isEmpty()) {
+ if (label.isPresent()) {
+ for (InstanceObject binding : bindings) {
+ if (!binding.isActive(som)) {
+ continue;
+ }
+ Optional boundLabel = LabelUtil.getLabel(binding) != null
+ ? LabelUtil.getLabel(binding)
+ : Optional.empty();
+
+ if (boundLabel.isPresent()) {
+ if (!boundLabel.get().dominates(label.get())) {
+ String msg = "Security label " + label.get() + " not dominated by "
+ + boundLabel.get().toString() + " of bound component " + binding.getFullName();
+ result.getDiagnostics().add(ResultUtil.createErrorDiagnostic(msg, io));
+ }
+ }
+ // Missing labels are reported in checkBindingLeastPrivileges as the highest security label is not known here
+ }
+
+ } else {
+ Optional maxLabel = Optional.empty();
+ for (InstanceObject binding : bindings) {
+ if (!binding.isActive(som)) {
+ return;
+ }
+ Optional boundLabel = LabelUtil.getLabel(binding) != null
+ ? LabelUtil.getLabel(binding)
+ : Optional.empty();
+
+ if (boundLabel.isPresent()) {
+ maxLabel = LabelUtil.join(maxLabel, boundLabel);
+ }
+ }
+
+ if (maxLabel.isPresent()) {
+ // Add warning if the component to which a binding is applies is missing a Security Label
+ String msg = "Missing security label on bound component: should be " + maxLabel.get().toString();
+ result.getDiagnostics().add(ResultUtil.createWarningDiagnostic(msg, io));
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks the star property for flow paths.
+ *
+ * @param fsi flow path
+ * @param src source of flow path
+ * @param dst destination of flow path
+ * @return
+ */
+ protected Boolean checkValidFlow(FlowSpecificationInstance fsi, NamedElement src, NamedElement dst) {
+ // skip all flows which are not active in the current mode
+ if (!fsi.isActive(som)) {
+ return PRUNE;
+ }
+
+ // Skip sinks and sources
+ if (src == null || dst == null) {
+ return DONE;
+ }
+
+ // Retrieve label from flow ends
+ Optional srcLabel = SecurityLabel.of(src) != null ? SecurityLabel.of(src) : Optional.empty();
+ Optional dstLabel = SecurityLabel.of(dst) != null ? SecurityLabel.of(dst) : Optional.empty();
+
+ if (srcLabel.isPresent() && dstLabel.isPresent()) {
+
+ // Skip trusted flows
+ if (LabelPropagator.isTrusted(fsi, som)) {
+ if (dstLabel.get().dominates(srcLabel.get())) {
+ result.getDiagnostics()
+ .add(ResultUtil.createWarningDiagnostic(
+ "Suspicious flow: marked as Trusted but not required to be trusted.", fsi));
+ }
+
+ result.getDiagnostics().add(ResultUtil.createInfoDiagnostic("Flow marked as Trusted.", fsi));
+ return DONE;
+ }
+
+ // Assert destination dominates source
+ if (!dstLabel.get().dominates(srcLabel.get())) {
+ String msg = "Security policy violation: Flow from " + srcLabel.get().toString() + " to "
+ + dstLabel.get().toString();
+ result.getDiagnostics().add(ResultUtil.createErrorDiagnostic(msg, fsi));
+ }
+
+ } else {
+ // Add warnings for missing label specification on src/dst
+ if (!srcLabel.isPresent() && dstLabel.isPresent()) {
+ String msg = "Missing security label for (part of flow path): " + src.getQualifiedName();
+ result.getDiagnostics().add(ResultUtil.createErrorDiagnostic(msg, src));
+ }
+ if (srcLabel.isPresent() && !dstLabel.isPresent()) {
+ String msg = "Missing security label for (part of flow path): " + dst.getQualifiedName();
+ result.getDiagnostics().add(ResultUtil.createErrorDiagnostic(msg, dst));
+ }
+
+ }
+
+ return DONE;
+ }
+
+ /**
+ * Finds hidden/implicit flows in the given component instance.
+ * Implicit flows are discovered using the following technique:
+ * Starting at each IN-Port of the component, the path along related connections is followed (this includes flow paths inside of subcomponents).
+ * If the end of such a path is reached and it is an OUT-port on {@code this} component instance, an error is added to the model.
+ * If the end of the path is a flow sink inside of a subcomponent an error is raised and a similar sink should be added to this component instance.
+ *
+ * Similarly hidden sources are detected (inverse operation)
+ *
+ * @param ci Component Instance on which hidden flows are detected.
+ */
+ void findHiddenFlows(ComponentInstance ci) {
+ if (!ci.getInModes().isEmpty() && !ci.isActive(som)) {
+ return;
+ }
+
+ EList features = ci.getFeatureInstances();
+
+ // Get missing flows in both directions and combine them into a set
+ Set> missingFlows = new HashSet<>();
+ for (FeatureInstance feature : features) {
+ if (!feature.isActive(som)) {
+ continue;
+ }
+ if (feature.getDirection() != null && feature.getDirection() == DirectionType.IN) {
+ List destinations = getDestinations(ci, feature);
+ for (FeatureInstance destination : destinations) {
+ if (destination != null && !destination.isActive(som)) {
+ continue;
+ }
+ missingFlows.add(new Pair<>(feature, destination));
+ }
+ } else if (feature.getDirection() != null && feature.getDirection() == DirectionType.OUT) {
+ List sources = getSources(ci, feature);
+ for (FeatureInstance source : sources) {
+ if (source != null && !source.isActive(som)) {
+ continue;
+ }
+ missingFlows.add(new Pair<>(source, feature));
+ }
+ }
+ }
+
+ // Annotate missing sources
+ for (Pair missingFlow : missingFlows) {
+ FeatureInstance sourceFeature = missingFlow.getKey();
+ FeatureInstance destinationFeature = missingFlow.getValue();
+
+ // Check if equivalent flow/sink exists
+ boolean exists = false;
+ for (FlowSpecificationInstance fsi : ci.getFlowSpecifications()) {
+ // skip all flows which are not active in the current mode
+ if (!fsi.isActive(som)) {
+ continue;
+ }
+ if (fsi.getSource() == sourceFeature && fsi.getDestination() == destinationFeature) {
+ exists = true;
+ }
+ }
+
+ // Add error to model
+ if (!exists) {
+ if (sourceFeature != null && destinationFeature != null) {
+ // Flow in this component
+ String msg = "Missing flow declaration from " + sourceFeature.getFullName() + " to "
+ + destinationFeature.getFullName();
+ result.getDiagnostics().add(ResultUtil.createErrorDiagnostic(msg, ci));
+ } else if (destinationFeature == null) {
+ // Flow sink in subcomponent
+ String msg = "Missing flow sink declaration for " + sourceFeature.getFullName();
+ result.getDiagnostics().add(ResultUtil.createErrorDiagnostic(msg, ci));
+ } else if (sourceFeature == null) {
+ // Flow source in subcomponent
+ String msg = "Missing flow source declaration for " + destinationFeature.getFullName();
+ result.getDiagnostics().add(ResultUtil.createErrorDiagnostic(msg, ci));
+ }
+
+ }
+ }
+
+ }
+
+ /**
+ * Determines destinations which can be reached from the starting IN-Port via connections and flows in subcomponents.
+ *
+ * @param ci root component
+ * @param inPort start port in root component
+ * @return List of destination features (can be null in case of sinks)
+ */
+ List getDestinations(ComponentInstance ci, FeatureInstance inPort) {
+ LinkedList destinations = new LinkedList<>();
+ EList connections = ci.getConnectionInstances();
+
+ LinkedList unWalkedFeatures = new LinkedList<>();
+
+ // add starting port
+ unWalkedFeatures.add(inPort);
+
+ while (!unWalkedFeatures.isEmpty()) {
+
+ // Get connection with feature as source
+ LinkedList unWalkedConnections = new LinkedList<>();
+ for (FeatureInstance feature : unWalkedFeatures) {
+ if (!feature.isActive(som)) {
+ continue;
+ }
+
+ // Add connections (from ci) which start with the feature to the walking list
+ for (ConnectionInstance connectionInstance : connections) {
+ if (!connectionInstance.isActive(som)) {
+ continue;
+ }
+ if (connectionInstance.getSource() == feature) {
+ unWalkedConnections.add(connectionInstance);
+ }
+ }
+ }
+ unWalkedFeatures.clear();
+
+ // Walk along connection
+ for (ConnectionInstance connection : unWalkedConnections) {
+ if (!connection.isActive(som)) {
+ continue;
+ }
+ ConnectionInstanceEnd end = connection.getDestination();
+
+ if (end instanceof FeatureInstance) {
+ FeatureInstance subComponentFeature = (FeatureInstance) end;
+ ComponentInstance subComponent = end.getComponentInstance();
+
+ if (subComponent != ci) {
+ // Find flows in subcomponent which start with the feature used at the end of the current connection
+ EList flowSpecifications = subComponent.getFlowSpecifications();
+ for (FlowSpecificationInstance fsi : flowSpecifications) {
+ // skip all flows which are not active in the current mode
+ if (!fsi.isActive(som)) {
+ continue;
+ }
+ if (fsi.getSource() == subComponentFeature) {
+ FeatureInstance destination = fsi.getDestination();
+ if (destination != null) {
+ // Follow the subcomponents flow destination
+ unWalkedFeatures.add(destination);
+ } else {
+ // flow sink in subcomponent
+ destinations.add(null);
+ }
+ }
+ }
+ } else {
+ // End of connection is a feature on the component itself
+ destinations.add(subComponentFeature);
+ }
+
+ }
+ }
+ unWalkedConnections.clear();
+ }
+
+ return destinations;
+ }
+
+ /**
+ * Determines sources which lead to the OUT-Port via connections and flows in subcomponents.
+ *
+ * @param ci root component
+ * @param outPort target port in root component
+ * @return List of source features (can be null in case of sources)
+ */
+ List getSources(ComponentInstance ci, FeatureInstance outPort) {
+ LinkedList sources = new LinkedList<>();
+ EList connections = ci.getConnectionInstances();
+
+ LinkedList unWalkedFeatures = new LinkedList<>();
+
+ // Add starting port
+ unWalkedFeatures.add(outPort);
+
+ while (!unWalkedFeatures.isEmpty()) {
+
+ // Get connection with feature as destination
+ LinkedList unWalkedConnections = new LinkedList<>();
+ for (FeatureInstance feature : unWalkedFeatures) {
+ if (!feature.isActive(som)) {
+ continue;
+ }
+ // Add connections (from ci) which start with the feature to the walking list
+ for (ConnectionInstance connectionInstance : connections) {
+ if (!connectionInstance.isActive(som)) {
+ continue;
+ }
+ if (connectionInstance.getDestination() == feature) {
+ unWalkedConnections.add(connectionInstance);
+ }
+ }
+ }
+ unWalkedFeatures.clear();
+
+ // Walk backwards along connection
+ for (ConnectionInstance connection : unWalkedConnections) {
+ if (!connection.isActive(som)) {
+ continue;
+ }
+ ConnectionInstanceEnd src = connection.getSource();
+
+ if (src instanceof FeatureInstance) {
+ FeatureInstance subComponentFeature = (FeatureInstance) src;
+ ComponentInstance subComponent = src.getComponentInstance();
+
+ if (subComponent != ci) {
+ // Find flows in subcomponent which end with the feature used at the start of the current connection
+ EList flowSpecifications = subComponent.getFlowSpecifications();
+ for (FlowSpecificationInstance fsi : flowSpecifications) {
+ // skip all flows which are not active in the current mode
+ if (!fsi.isActive(som)) {
+ continue;
+ }
+ if (fsi.getDestination() == subComponentFeature) {
+ FeatureInstance source = fsi.getSource();
+ if (source != null) {
+ // Follow the subcomponents flow destination
+ unWalkedFeatures.add(source);
+ } else {
+ // flow source in subcomponent
+ sources.add(null);
+ }
+ }
+ }
+ } else {
+ // Start of connection is a feature on the component itself
+ sources.add(subComponentFeature);
+ }
+
+ }
+ }
+ unWalkedConnections.clear();
+ }
+
+ return sources;
+ }
+
+ /**
+ * Determine if the instance object is active within the current SOM
+ * @param io instance object to check for
+ * @return true fi the instance object is active
+ */
+ private boolean isActiveInstanceObject(InstanceObject io) {
+ if (io instanceof ComponentInstance) {
+ ComponentInstance ci = (ComponentInstance) io;
+ return ci.getInModes().isEmpty() || ci.isActive(som);
+ } else {
+ return io.isActive(som);
+ }
+ }
+
+}
diff --git a/analyses/org.osate.analysis.security/src/org/osate/analysis/security/SecurityPlugin.java b/analyses/org.osate.analysis.security/src/org/osate/analysis/security/SecurityPlugin.java
new file mode 100644
index 00000000000..b8c2ee2dba0
--- /dev/null
+++ b/analyses/org.osate.analysis.security/src/org/osate/analysis/security/SecurityPlugin.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2004-2023 Carnegie Mellon University and others. (see Contributors file).
+ * All Rights Reserved.
+ *
+ * NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
+ * OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
+ * MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
+ *
+ * This program includes and/or can make use of certain third party source code, object code, documentation and other
+ * files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
+ * configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
+ * conditions contained in any such Third Party Software or separate license file distributed with such Third Party
+ * Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party beneficiaries
+ * to this license with respect to the terms applicable to their Third Party Software. Third Party Software licenses
+ * only apply to the Third Party Software and not any other portion of this program or this program as a whole.
+ *******************************************************************************/
+package org.osate.analysis.security;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The main plugin class to be used in the desktop.
+ */
+public class SecurityPlugin extends AbstractUIPlugin {
+ // The shared instance.
+ private static SecurityPlugin plugin;
+ // Resource bundle.
+ private ResourceBundle resourceBundle;
+
+ /**
+ * The constructor.
+ */
+ public SecurityPlugin() {
+ super();
+ plugin = this;
+ try {
+ resourceBundle = ResourceBundle.getBundle("org.osate.analysis.security.SecurityPluginResources");
+ } catch (MissingResourceException x) {
+ resourceBundle = null;
+ }
+ }
+
+ /**
+ * This method is called upon plug-in activation
+ */
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ }
+
+ /**
+ * This method is called when the plug-in is stopped
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance.
+ */
+ public static SecurityPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Returns the string from the plugin's resource bundle,
+ * or 'key' if not found.
+ */
+ public static String getResourceString(String key) {
+ ResourceBundle bundle = SecurityPlugin.getDefault().getResourceBundle();
+ try {
+ return (bundle != null) ? bundle.getString(key) : key;
+ } catch (MissingResourceException e) {
+ return key;
+ }
+ }
+
+ /**
+ * Returns the plugin's resource bundle,
+ */
+ public ResourceBundle getResourceBundle() {
+ return resourceBundle;
+ }
+}
diff --git a/analyses/org.osate.plugins.feature/feature.xml b/analyses/org.osate.plugins.feature/feature.xml
index 3f0fb88eb5b..cbd655b62e4 100644
--- a/analyses/org.osate.plugins.feature/feature.xml
+++ b/analyses/org.osate.plugins.feature/feature.xml
@@ -2,7 +2,7 @@
+
+
+
+
diff --git a/analyses/org.osate.plugins.feature/pom.xml b/analyses/org.osate.plugins.feature/pom.xml
index 006b5d269d3..5437195e2e3 100644
--- a/analyses/org.osate.plugins.feature/pom.xml
+++ b/analyses/org.osate.plugins.feature/pom.xml
@@ -12,7 +12,7 @@
org.osate
org.osate.plugins.feature
- 6.1.5-SNAPSHOT
+ 6.2.0-SNAPSHOT
eclipse-feature
diff --git a/analyses/pom.xml b/analyses/pom.xml
index 6a1e0bf4832..8ed4df395b2 100644
--- a/analyses/pom.xml
+++ b/analyses/pom.xml
@@ -61,6 +61,9 @@
org.osate.modelstats
org.osate.modelstats.ui
org.osate.modelstats.tests
+
+ org.osate.analysis.security
+ org.osate.analysis.security.ui
diff --git a/core/org.osate.build.coverage.report/pom.xml b/core/org.osate.build.coverage.report/pom.xml
index 65da12983be..f2f42bc5304 100644
--- a/core/org.osate.build.coverage.report/pom.xml
+++ b/core/org.osate.build.coverage.report/pom.xml
@@ -651,6 +651,27 @@
true
test
+
+ org.osate
+ org.osate.analysis.security
+ 1.0.0-SNAPSHOT
+ true
+ compile
+
+
+ org.osate
+ org.osate.analysis.security.ui
+ 1.0.0-SNAPSHOT
+ true
+ compile
+
+
+ org.osate
+ org.osate.security.contributions
+ 1.0.0-SNAPSHOT
+ true
+ compile
+
diff --git a/core/org.osate.core.feature/feature.xml b/core/org.osate.core.feature/feature.xml
index 12a0119738e..cdf2c84c3b9 100644
--- a/core/org.osate.core.feature/feature.xml
+++ b/core/org.osate.core.feature/feature.xml
@@ -2,7 +2,7 @@
+
+
diff --git a/core/org.osate.core.feature/pom.xml b/core/org.osate.core.feature/pom.xml
index a21b6a8fdf4..67eb4a7f341 100644
--- a/core/org.osate.core.feature/pom.xml
+++ b/core/org.osate.core.feature/pom.xml
@@ -12,7 +12,7 @@
org.osate
org.osate.core.feature
- 11.1.2-SNAPSHOT
+ 11.2.0-SNAPSHOT
eclipse-feature
diff --git a/core/org.osate.security.contributions/.classpath b/core/org.osate.security.contributions/.classpath
new file mode 100644
index 00000000000..946fb3d346f
--- /dev/null
+++ b/core/org.osate.security.contributions/.classpath
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/core/org.osate.security.contributions/.gitignore b/core/org.osate.security.contributions/.gitignore
new file mode 100644
index 00000000000..ae3c1726048
--- /dev/null
+++ b/core/org.osate.security.contributions/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/core/org.osate.security.contributions/.project b/core/org.osate.security.contributions/.project
new file mode 100644
index 00000000000..2de4e93fef8
--- /dev/null
+++ b/core/org.osate.security.contributions/.project
@@ -0,0 +1,73 @@
+
+
+ org.osate.security.contributions
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+ org.eclipse.oomph.version.VersionBuilder
+
+
+ check.feature.closure.completeness
+ true
+
+
+ check.feature.closure.content
+ true
+
+
+ check.maven.pom
+ true
+
+
+ ignore.feature.content.redundancy
+ true
+
+
+ ignore.lower.bound.dependency.ranges
+ false
+
+
+ ignore.schema.builder
+ true
+
+
+ release.path
+ /releng/version-management/release.xml
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+ org.eclipse.oomph.version.VersionNature
+
+
+
+ 1702127013300
+
+ 30
+
+ org.eclipse.core.resources.regexFilterMatcher
+ node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__
+
+
+
+
diff --git a/core/org.osate.security.contributions/META-INF/MANIFEST.MF b/core/org.osate.security.contributions/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..1a43b650a02
--- /dev/null
+++ b/core/org.osate.security.contributions/META-INF/MANIFEST.MF
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Contributions
+Bundle-SymbolicName: org.osate.security.contributions;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.osate.security.contributions.Activator
+Require-Bundle: org.eclipse.core.runtime
+Bundle-RequiredExecutionEnvironment: JavaSE-17
+Automatic-Module-Name: org.osate.security.contributions
+Bundle-ActivationPolicy: lazy
+Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.17.0,4.0.0)",
+ org.osate.aadl2;bundle-version="[5.0.0,6.0.0)",
+ org.osate.aadl2.modelsupport;bundle-version="[7.0.0,8.0.0)",
+ org.osate.pluginsupport;bundle-version="[7.2.0,8.0.0)",
+ org.osate.aadl2.contrib;bundle-version="[2.1.0,3.0.0)"
+Export-Package: org.osate.security.contributions;version="1.0.0"
diff --git a/core/org.osate.security.contributions/build.properties b/core/org.osate.security.contributions/build.properties
new file mode 100644
index 00000000000..95e79b5a76d
--- /dev/null
+++ b/core/org.osate.security.contributions/build.properties
@@ -0,0 +1,31 @@
+###############################################################################
+# Copyright (c) 2004-2023 Carnegie Mellon University and others. (see Contributors file).
+# All Rights Reserved.
+#
+# NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
+# KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
+# OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
+# MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
+#
+# This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
+# which is available at https://www.eclipse.org/legal/epl-2.0/
+# SPDX-License-Identifier: EPL-2.0
+#
+# Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
+#
+# This program includes and/or can make use of certain third party source code, object code, documentation and other
+# files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
+# configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
+# conditions contained in any such Third Party Software or separate license file distributed with such Third Party
+# Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party beneficiaries
+# to this license with respect to the terms applicable to their Third Party Software. Third Party Software licenses
+# only apply to the Third Party Software and not any other portion of this program or this program as a whole.
+###############################################################################
+source.. = src/,\
+ src-gen/
+output.. = bin/
+bin.includes = .,\
+ plugin.xml,\
+ resources/,\
+ META-INF/
+src.includes = resources/
diff --git a/core/org.osate.security.contributions/plugin.xml b/core/org.osate.security.contributions/plugin.xml
new file mode 100644
index 00000000000..dceb4def119
--- /dev/null
+++ b/core/org.osate.security.contributions/plugin.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/core/org.osate.security.contributions/pom.xml b/core/org.osate.security.contributions/pom.xml
new file mode 100644
index 00000000000..9bdeaaafa46
--- /dev/null
+++ b/core/org.osate.security.contributions/pom.xml
@@ -0,0 +1,43 @@
+
+
+
+
+ 4.0.0
+
+
+ org.osate
+ core.parent
+ 2.14.0-SNAPSHOT
+
+
+ org.osate
+ org.osate.security.contributions
+ 1.0.0-SNAPSHOT
+ eclipse-plugin
+
+
diff --git a/core/org.osate.security.contributions/resources/properties/SecurityClassificationProperties.aadl b/core/org.osate.security.contributions/resources/properties/SecurityClassificationProperties.aadl
new file mode 100644
index 00000000000..853a8236098
--- /dev/null
+++ b/core/org.osate.security.contributions/resources/properties/SecurityClassificationProperties.aadl
@@ -0,0 +1,19 @@
+-- Copyright (c) 2004-2023 Carnegie Mellon University. All right reserved.
+-- Distribution Statement A: Approved for Public Release; Distribution is Unlimited.
+-- @codegen-package org.osate.security.contributions.securityclassificationproperties
+property set SecurityClassificationProperties is
+
+ -- Both the Security_Level and Security_Level_Caveats can be overridden by custom definitions.
+ Security_Level: inherit enumeration (TopSecret, Secret, Confidential, No_Clearance) applies to (system, processor,
+ virtual processor, thread,
+ thread group, subprogram, subprogram group, data, port,
+ feature group, process, device, memory, bus, abstract, flow,
+ parameter, access);
+ Security_Level_Caveats: inherit list of enumeration (FOUO, NOFORN, NOCONTRACTOR, PROPIN, IMCON, ORCON) applies to (
+ system, processor, virtual processor, thread,
+ thread group, subprogram, subprogram group, data, port,
+ feature group, process, device, memory, bus, abstract, flow,
+ parameter, access);
+
+ Trusted: aadlboolean => false applies to (flow);
+end SecurityClassificationProperties;
\ No newline at end of file
diff --git a/core/org.osate.security.contributions/src-gen/org/osate/security/contributions/securityclassificationproperties/SecurityLevel.java b/core/org.osate.security.contributions/src-gen/org/osate/security/contributions/securityclassificationproperties/SecurityLevel.java
new file mode 100644
index 00000000000..c10345b92f6
--- /dev/null
+++ b/core/org.osate.security.contributions/src-gen/org/osate/security/contributions/securityclassificationproperties/SecurityLevel.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2004-2023 Carnegie Mellon University and others. (see Contributors file).
+ * All Rights Reserved.
+ *
+ * NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
+ * OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
+ * MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
+ *
+ * This program includes and/or can make use of certain third party source code, object code, documentation and other
+ * files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
+ * configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
+ * conditions contained in any such Third Party Software or separate license file distributed with such Third Party
+ * Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party beneficiaries
+ * to this license with respect to the terms applicable to their Third Party Software. Third Party Software licenses
+ * only apply to the Third Party Software and not any other portion of this program or this program as a whole.
+ *******************************************************************************/
+package org.osate.security.contributions.securityclassificationproperties;
+
+import org.eclipse.emf.common.util.URI;
+import org.osate.aadl2.AbstractNamedValue;
+import org.osate.aadl2.EnumerationLiteral;
+import org.osate.aadl2.NamedValue;
+import org.osate.aadl2.PropertyExpression;
+import org.osate.pluginsupport.properties.GeneratedEnumeration;
+
+public enum SecurityLevel implements GeneratedEnumeration {
+ TOPSECRET("TopSecret", "platform:/resource/SecurityClassificationProperties.aadl#/0/@ownedProperty.0/@ownedPropertyType/@ownedLiteral.0"),
+ SECRET("Secret", "platform:/resource/SecurityClassificationProperties.aadl#/0/@ownedProperty.0/@ownedPropertyType/@ownedLiteral.1"),
+ CONFIDENTIAL("Confidential", "platform:/resource/SecurityClassificationProperties.aadl#/0/@ownedProperty.0/@ownedPropertyType/@ownedLiteral.2"),
+ NO_CLEARANCE("No_Clearance", "platform:/resource/SecurityClassificationProperties.aadl#/0/@ownedProperty.0/@ownedPropertyType/@ownedLiteral.3");
+
+ private final String originalName;
+ private final URI uri;
+
+ private SecurityLevel(String originalName, String uri) {
+ this.originalName = originalName;
+ this.uri = URI.createURI(uri);
+ }
+
+ public static SecurityLevel valueOf(PropertyExpression propertyExpression) {
+ AbstractNamedValue abstractNamedValue = ((NamedValue) propertyExpression).getNamedValue();
+ return valueOf(((EnumerationLiteral) abstractNamedValue).getName().toUpperCase());
+ }
+
+ @Override
+ public URI getURI() {
+ return uri;
+ }
+
+ @Override
+ public String toString() {
+ return originalName;
+ }
+}
diff --git a/core/org.osate.security.contributions/src-gen/org/osate/security/contributions/securityclassificationproperties/SecurityLevelCaveats.java b/core/org.osate.security.contributions/src-gen/org/osate/security/contributions/securityclassificationproperties/SecurityLevelCaveats.java
new file mode 100644
index 00000000000..b7b9598441c
--- /dev/null
+++ b/core/org.osate.security.contributions/src-gen/org/osate/security/contributions/securityclassificationproperties/SecurityLevelCaveats.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2004-2023 Carnegie Mellon University and others. (see Contributors file).
+ * All Rights Reserved.
+ *
+ * NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
+ * OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
+ * MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
+ *
+ * This program includes and/or can make use of certain third party source code, object code, documentation and other
+ * files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
+ * configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
+ * conditions contained in any such Third Party Software or separate license file distributed with such Third Party
+ * Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party beneficiaries
+ * to this license with respect to the terms applicable to their Third Party Software. Third Party Software licenses
+ * only apply to the Third Party Software and not any other portion of this program or this program as a whole.
+ *******************************************************************************/
+package org.osate.security.contributions.securityclassificationproperties;
+
+import org.eclipse.emf.common.util.URI;
+import org.osate.aadl2.AbstractNamedValue;
+import org.osate.aadl2.EnumerationLiteral;
+import org.osate.aadl2.NamedValue;
+import org.osate.aadl2.PropertyExpression;
+import org.osate.pluginsupport.properties.GeneratedEnumeration;
+
+public enum SecurityLevelCaveats implements GeneratedEnumeration {
+ A("A", "platform:/resource/SecurityClassificationProperties.aadl#/0/@ownedProperty.1/@ownedPropertyType/@ownedElementType/@ownedLiteral.0"),
+ B("B", "platform:/resource/SecurityClassificationProperties.aadl#/0/@ownedProperty.1/@ownedPropertyType/@ownedElementType/@ownedLiteral.1"),
+ C("C", "platform:/resource/SecurityClassificationProperties.aadl#/0/@ownedProperty.1/@ownedPropertyType/@ownedElementType/@ownedLiteral.2"),
+ D("D", "platform:/resource/SecurityClassificationProperties.aadl#/0/@ownedProperty.1/@ownedPropertyType/@ownedElementType/@ownedLiteral.3"),
+ E("E", "platform:/resource/SecurityClassificationProperties.aadl#/0/@ownedProperty.1/@ownedPropertyType/@ownedElementType/@ownedLiteral.4");
+
+ private final String originalName;
+ private final URI uri;
+
+ private SecurityLevelCaveats(String originalName, String uri) {
+ this.originalName = originalName;
+ this.uri = URI.createURI(uri);
+ }
+
+ public static SecurityLevelCaveats valueOf(PropertyExpression propertyExpression) {
+ AbstractNamedValue abstractNamedValue = ((NamedValue) propertyExpression).getNamedValue();
+ return valueOf(((EnumerationLiteral) abstractNamedValue).getName().toUpperCase());
+ }
+
+ @Override
+ public URI getURI() {
+ return uri;
+ }
+
+ @Override
+ public String toString() {
+ return originalName;
+ }
+}
diff --git a/core/org.osate.security.contributions/src-gen/org/osate/security/contributions/securityclassificationproperties/Securityclassificationproperties.java b/core/org.osate.security.contributions/src-gen/org/osate/security/contributions/securityclassificationproperties/Securityclassificationproperties.java
new file mode 100644
index 00000000000..ffd3d024762
--- /dev/null
+++ b/core/org.osate.security.contributions/src-gen/org/osate/security/contributions/securityclassificationproperties/Securityclassificationproperties.java
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * Copyright (c) 2004-2023 Carnegie Mellon University and others. (see Contributors file).
+ * All Rights Reserved.
+ *
+ * NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
+ * OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
+ * MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
+ *
+ * This program includes and/or can make use of certain third party source code, object code, documentation and other
+ * files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
+ * configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
+ * conditions contained in any such Third Party Software or separate license file distributed with such Third Party
+ * Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party beneficiaries
+ * to this license with respect to the terms applicable to their Third Party Software. Third Party Software licenses
+ * only apply to the Third Party Software and not any other portion of this program or this program as a whole.
+ *******************************************************************************/
+package org.osate.security.contributions.securityclassificationproperties;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.eclipse.emf.ecore.EObject;
+import org.osate.aadl2.Aadl2Package;
+import org.osate.aadl2.BooleanLiteral;
+import org.osate.aadl2.ListValue;
+import org.osate.aadl2.Mode;
+import org.osate.aadl2.NamedElement;
+import org.osate.aadl2.Property;
+import org.osate.aadl2.PropertyExpression;
+import org.osate.aadl2.modelsupport.scoping.Aadl2GlobalScopeUtil;
+import org.osate.aadl2.properties.PropertyDoesNotApplyToHolderException;
+import org.osate.aadl2.properties.PropertyNotPresentException;
+import org.osate.pluginsupport.properties.CodeGenUtil;
+
+public final class Securityclassificationproperties {
+ public static final String SECURITYCLASSIFICATIONPROPERTIES__NAME = "SecurityClassificationProperties";
+
+ private Securityclassificationproperties() {}
+
+ // Lookup methods for SecurityClassificationProperties::Security_Level
+
+ public static final String SECURITY_LEVEL__NAME = "Security_Level";
+
+ public static boolean acceptsSecurityLevel(NamedElement lookupContext) {
+ return lookupContext.acceptsProperty(getSecurityLevel_Property(lookupContext));
+ }
+
+ public static Optional getSecurityLevel(NamedElement lookupContext) {
+ return getSecurityLevel(lookupContext, Optional.empty());
+ }
+
+ public static Optional getSecurityLevel(NamedElement lookupContext, Mode mode) {
+ return getSecurityLevel(lookupContext, Optional.of(mode));
+ }
+
+ public static Optional getSecurityLevel(NamedElement lookupContext, Optional mode) {
+ Property property = getSecurityLevel_Property(lookupContext);
+ try {
+ PropertyExpression value = CodeGenUtil.lookupProperty(property, lookupContext, mode);
+ PropertyExpression resolved = CodeGenUtil.resolveNamedValue(value, lookupContext, mode);
+ return Optional.of(SecurityLevel.valueOf(resolved));
+ } catch (PropertyNotPresentException | PropertyDoesNotApplyToHolderException e) {
+ return Optional.empty();
+ }
+ }
+
+ public static Property getSecurityLevel_Property(EObject lookupContext) {
+ String name = SECURITYCLASSIFICATIONPROPERTIES__NAME + "::" + SECURITY_LEVEL__NAME;
+ return Aadl2GlobalScopeUtil.get(lookupContext, Aadl2Package.eINSTANCE.getProperty(), name);
+ }
+
+ public static PropertyExpression getSecurityLevel_EObject(NamedElement lookupContext) {
+ return lookupContext.getNonModalPropertyValue(getSecurityLevel_Property(lookupContext));
+ }
+
+ // Lookup methods for SecurityClassificationProperties::Security_Level_Caveats
+
+ public static final String SECURITY_LEVEL_CAVEATS__NAME = "Security_Level_Caveats";
+
+ public static boolean acceptsSecurityLevelCaveats(NamedElement lookupContext) {
+ return lookupContext.acceptsProperty(getSecurityLevelCaveats_Property(lookupContext));
+ }
+
+ public static Optional> getSecurityLevelCaveats(NamedElement lookupContext) {
+ return getSecurityLevelCaveats(lookupContext, Optional.empty());
+ }
+
+ public static Optional> getSecurityLevelCaveats(NamedElement lookupContext, Mode mode) {
+ return getSecurityLevelCaveats(lookupContext, Optional.of(mode));
+ }
+
+ public static Optional> getSecurityLevelCaveats(NamedElement lookupContext, Optional mode) {
+ Property property = getSecurityLevelCaveats_Property(lookupContext);
+ try {
+ PropertyExpression value = CodeGenUtil.lookupProperty(property, lookupContext, mode);
+ PropertyExpression resolved = CodeGenUtil.resolveNamedValue(value, lookupContext, mode);
+ return Optional.of(((ListValue) resolved).getOwnedListElements().stream().map(element1 -> {
+ PropertyExpression resolved1 = CodeGenUtil.resolveNamedValue(element1, lookupContext, mode);
+ return SecurityLevelCaveats.valueOf(resolved1);
+ }).collect(Collectors.toList()));
+ } catch (PropertyNotPresentException | PropertyDoesNotApplyToHolderException e) {
+ return Optional.empty();
+ }
+ }
+
+ public static Property getSecurityLevelCaveats_Property(EObject lookupContext) {
+ String name = SECURITYCLASSIFICATIONPROPERTIES__NAME + "::" + SECURITY_LEVEL_CAVEATS__NAME;
+ return Aadl2GlobalScopeUtil.get(lookupContext, Aadl2Package.eINSTANCE.getProperty(), name);
+ }
+
+ public static PropertyExpression getSecurityLevelCaveats_EObject(NamedElement lookupContext) {
+ return lookupContext.getNonModalPropertyValue(getSecurityLevelCaveats_Property(lookupContext));
+ }
+
+ // Lookup methods for SecurityClassificationProperties::Trusted
+
+ public static final String TRUSTED__NAME = "Trusted";
+
+ public static boolean acceptsTrusted(NamedElement lookupContext) {
+ return lookupContext.acceptsProperty(getTrusted_Property(lookupContext));
+ }
+
+ public static Optional getTrusted(NamedElement lookupContext) {
+ return getTrusted(lookupContext, Optional.empty());
+ }
+
+ public static Optional getTrusted(NamedElement lookupContext, Mode mode) {
+ return getTrusted(lookupContext, Optional.of(mode));
+ }
+
+ public static Optional getTrusted(NamedElement lookupContext, Optional mode) {
+ Property property = getTrusted_Property(lookupContext);
+ try {
+ PropertyExpression value = CodeGenUtil.lookupProperty(property, lookupContext, mode);
+ PropertyExpression resolved = CodeGenUtil.resolveNamedValue(value, lookupContext, mode);
+ return Optional.of(((BooleanLiteral) resolved).getValue());
+ } catch (PropertyNotPresentException | PropertyDoesNotApplyToHolderException e) {
+ return Optional.empty();
+ }
+ }
+
+ public static Property getTrusted_Property(EObject lookupContext) {
+ String name = SECURITYCLASSIFICATIONPROPERTIES__NAME + "::" + TRUSTED__NAME;
+ return Aadl2GlobalScopeUtil.get(lookupContext, Aadl2Package.eINSTANCE.getProperty(), name);
+ }
+
+ public static PropertyExpression getTrusted_EObject(NamedElement lookupContext) {
+ return lookupContext.getNonModalPropertyValue(getTrusted_Property(lookupContext));
+ }
+}
diff --git a/core/org.osate.security.contributions/src/org/osate/security/contributions/Activator.java b/core/org.osate.security.contributions/src/org/osate/security/contributions/Activator.java
new file mode 100644
index 00000000000..84af69d0bdc
--- /dev/null
+++ b/core/org.osate.security.contributions/src/org/osate/security/contributions/Activator.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2004-2023 Carnegie Mellon University and others. (see Contributors file).
+ * All Rights Reserved.
+ *
+ * NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
+ * OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
+ * MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
+ *
+ * This program includes and/or can make use of certain third party source code, object code, documentation and other
+ * files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
+ * configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
+ * conditions contained in any such Third Party Software or separate license file distributed with such Third Party
+ * Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party beneficiaries
+ * to this license with respect to the terms applicable to their Third Party Software. Third Party Software licenses
+ * only apply to the Third Party Software and not any other portion of this program or this program as a whole.
+ *******************************************************************************/
+package org.osate.security.contributions;
+
+import org.eclipse.core.runtime.Plugin;
+import org.osgi.framework.BundleContext;
+
+public class Activator extends Plugin {
+
+ public static final String PLUGIN_ID = "org.osate.security.contributions";
+ private static Activator plugin;
+
+ public Activator() {
+ plugin = this;
+ }
+
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+}
\ No newline at end of file
diff --git a/core/osate.releng/OSATE2 small fonts.launch b/core/osate.releng/OSATE2 small fonts.launch
index 530bc4ad6c5..c5ea364ad9f 100644
--- a/core/osate.releng/OSATE2 small fonts.launch
+++ b/core/osate.releng/OSATE2 small fonts.launch
@@ -1126,6 +1126,8 @@
+
+
diff --git a/core/osate.releng/OSATE2.launch b/core/osate.releng/OSATE2.launch
index 4c432599621..636015be0df 100644
--- a/core/osate.releng/OSATE2.launch
+++ b/core/osate.releng/OSATE2.launch
@@ -699,6 +699,9 @@
+
+
+
diff --git a/core/pom.xml b/core/pom.xml
index 355da7e4e25..d1743412d0a 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -74,5 +74,6 @@
org.osate.core.tests
org.osate.core.tests.log4j
org.osate.slicer.tests
+ org.osate.security.contributions
\ No newline at end of file
diff --git a/examples/org.osate.examples/META-INF/MANIFEST.MF b/examples/org.osate.examples/META-INF/MANIFEST.MF
index 91c4196c04a..d6ffd182a70 100644
--- a/examples/org.osate.examples/META-INF/MANIFEST.MF
+++ b/examples/org.osate.examples/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Examples
Bundle-SymbolicName: org.osate.examples;singleton:=true
-Bundle-Version: 1.0.6.qualifier
+Bundle-Version: 1.0.7.qualifier
Automatic-Module-Name: org.osate.examples
Require-Bundle: org.osate.ui;bundle-version="[6.3.0,7.0.0)"
Bundle-Vendor: CMU/SEI
diff --git a/examples/org.osate.examples/build.properties b/examples/org.osate.examples/build.properties
index e40e5c89ec0..5a63caf9c1a 100644
--- a/examples/org.osate.examples/build.properties
+++ b/examples/org.osate.examples/build.properties
@@ -21,4 +21,6 @@ bin.excludes = examples/arp4761/doc/markdown/,\
examples/ACVIP/pom.xml,\
examples/ACVIP/doc/markdown/,\
examples/ACVIP_ALISA/pom.xml,\
- examples/ACVIP_ALISA/ALISA_Example/doc/markdown/
+ examples/ACVIP_ALISA/ALISA_Example/doc/markdown/,\
+ examples/SecurityAnalysisExample/doc/markdown/,\
+ examples/SecurityAnalysisExample/pom.xml,\
diff --git a/examples/org.osate.examples/examples/SecurityAnalysisExample/.project b/examples/org.osate.examples/examples/SecurityAnalysisExample/.project
new file mode 100644
index 00000000000..244c59d878b
--- /dev/null
+++ b/examples/org.osate.examples/examples/SecurityAnalysisExample/.project
@@ -0,0 +1,18 @@
+
+
+ SecurityAnalysisExample
+
+
+
+
+
+ org.eclipse.xtext.ui.shared.xtextBuilder
+
+
+
+
+
+ org.osate.core.aadlnature
+ org.eclipse.xtext.ui.shared.xtextNature
+
+
diff --git a/examples/org.osate.examples/examples/SecurityAnalysisExample/Examples/CompleteBoundFlowExample.aadl b/examples/org.osate.examples/examples/SecurityAnalysisExample/Examples/CompleteBoundFlowExample.aadl
new file mode 100644
index 00000000000..d9f210da326
--- /dev/null
+++ b/examples/org.osate.examples/examples/SecurityAnalysisExample/Examples/CompleteBoundFlowExample.aadl
@@ -0,0 +1,293 @@
+package CompleteBoundFlowExample
+-- Producer - consumer example with confidentiality reducing middle-man (transformer)
+-- Both the producer and transformer are marked as private systems, which are therefore allowed to handle private data.
+-- The consumer system is declared as 'public'. The private data provided by the transformer translated into public data while preserving confidentiality.
+-- The flow of data is described using flows within the individual systems.
+-- This example does not consider implications of hardware security.
+public
+ with SecurityClassificationProperties;
+
+ data PrivateDataSet
+ properties
+ SecurityClassificationProperties::Security_Level => TopSecret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end PrivateDataSet;
+
+ data PublicDataSet
+ properties
+ SecurityClassificationProperties::Security_Level => No_Clearance;
+ SecurityClassificationProperties::Security_Level_Caveats => (A, E);
+ end PublicDataSet;
+
+ bus InternalBus
+ end InternalBus;
+
+ bus implementation InternalBus.imp
+ properties
+ SecurityClassificationProperties::Security_Level => TopSecret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end InternalBus.imp;
+
+ bus ExternalBus
+ properties
+ SecurityClassificationProperties::Security_Level => No_Clearance;
+ SecurityClassificationProperties::Security_Level_Caveats => (A, E);
+ end ExternalBus;
+
+ bus implementation ExternalBus.imp
+ end ExternalBus.imp;
+
+---
+ -- private provider system with flow source
+ memory ProviderStorage
+ end ProviderStorage;
+
+ memory implementation ProviderStorage.imp
+ end ProviderStorage.imp;
+
+ system Provider
+ features
+ dataOut: out data port PrivateDataSet;
+ flows
+ flowSource: flow source dataOut;
+ properties
+ SecurityClassificationProperties::Security_Level => TopSecret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end Provider;
+
+ process ProviderProcess
+ features
+ dataOut: out data port PrivateDataSet;
+ flows
+ flowSource: flow source dataOut;
+ end ProviderProcess;
+
+ thread ProviderThread
+ features
+ dataOut: out data port PrivateDataSet;
+ flows
+ flowSource: flow source dataOut;
+ end ProviderThread;
+
+ thread implementation ProviderThread.imp
+ end ProviderThread.imp;
+
+ process implementation ProviderProcess.imp
+ subcomponents
+ providerThread: thread ProviderThread.imp;
+ connections
+ conn: port providerThread.dataOut -> dataOut;
+ flows
+ flowSource: flow source providerThread.flowSource -> conn -> dataOut;
+ end ProviderProcess.imp;
+
+ processor ProviderProcessor
+
+ end ProviderProcessor;
+
+ processor implementation ProviderProcessor.imp
+ end ProviderProcessor.imp;
+
+ system implementation Provider.imp
+ subcomponents
+ providerProcessor: processor ProviderProcessor.imp;
+ providerProcess: process ProviderProcess.imp;
+ storage: memory ProviderStorage.imp;
+ connections
+ conn: port providerProcess.dataOut -> dataOut;
+ flows
+ flowSource: flow source providerProcess.flowSource -> conn -> dataOut;
+ properties
+ Actual_Memory_Binding => (reference (storage)) applies to dataOut;
+ Actual_Processor_Binding => (reference (providerProcessor)) applies to providerProcess;
+ end Provider.imp;
+
+---
+ -- public consumer system with flow sink
+ memory ConsumerStorage
+ end ConsumerStorage;
+
+ memory implementation ConsumerStorage.imp
+ end ConsumerStorage.imp;
+
+ system Consumer
+ features
+ dataIn: in data port PublicDataSet;
+ flows
+ flowSink: flow sink dataIn;
+ properties
+ SecurityClassificationProperties::Security_Level => No_Clearance;
+ SecurityClassificationProperties::Security_Level_Caveats => (A, E);
+ end Consumer;
+
+ processor ConsumerProcessor
+ end ConsumerProcessor;
+
+ processor implementation ConsumerProcessor.imp
+ end ConsumerProcessor.imp;
+
+ process ConsumerProcess
+ features
+ dataIn: in data port PublicDataSet;
+ flows
+ flowSink: flow sink dataIn;
+ end ConsumerProcess;
+
+ thread ConsumerThread
+ features
+ dataIn: in data port PublicDataSet;
+ flows
+ flowSink: flow sink dataIn;
+ end ConsumerThread;
+
+ thread implementation ConsumerThread.imp
+ end ConsumerThread.imp;
+
+ process implementation ConsumerProcess.imp
+ subcomponents
+ consumerThread: thread ConsumerThread.imp;
+ connections
+ conn: port dataIn -> consumerThread.dataIn;
+ flows
+ flowSink: flow sink dataIn -> conn -> consumerThread.flowSink;
+ end ConsumerProcess.imp;
+
+ system implementation Consumer.imp
+ subcomponents
+ consumerProcessor: processor ConsumerProcessor.imp;
+ consumerProcess: process ConsumerProcess.imp;
+ storage: memory ConsumerStorage.imp;
+ connections
+ conn: port dataIn -> consumerProcess.dataIn;
+ flows
+ flowSink: flow sink dataIn -> conn -> consumerProcess.flowSink;
+ properties
+ Actual_Memory_Binding => (reference (storage)) applies to dataIn;
+ Actual_Processor_Binding => (reference (consumerProcessor)) applies to consumerProcess;
+ end Consumer.imp;
+
+---
+ -- private transformer system with flow path (private in, public out) - transforms data while retaining confidentiality
+ process TransformerProcess
+ features
+ dataIn: in data port PrivateDataSet;
+ dataOut: out data port PublicDataSet;
+ flows
+ transformerProcessFlowPath: flow path dataIn -> dataOut;
+
+ properties
+ SecurityClassificationProperties::Security_Level => TopSecret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A, E);
+ end TransformerProcess;
+
+ thread TransformerThread
+ features
+ dataIn: in data port PrivateDataSet;
+ dataOut: out data port PublicDataSet;
+ flows
+ transformerThreadFlowPath: flow path dataIn -> dataOut;
+ properties
+ -- configure flow - which transforms the data type - to retain confidentiality (anonymization process)
+ SecurityClassificationProperties::Trusted => True applies to transformerThreadFlowPath;
+ end TransformerThread;
+
+ thread implementation TransformerThread.imp
+ end TransformerThread.imp;
+
+ processor TransformerProcessor
+ end TransformerProcessor;
+
+ processor implementation TransformerProcessor.imp
+ end TransformerProcessor.imp;
+
+ process implementation TransformerProcess.imp
+ subcomponents
+ transformerThread: thread TransformerThread.imp;
+ connections
+ connDataIn: port dataIn -> transformerThread.dataIn;
+ connDataOut: port transformerThread.dataOut -> dataOut;
+ flows
+ transformerProcessFlowPath: flow path dataIn -> connDataIn -> transformerThread.transformerThreadFlowPath -> connDataOut -> dataOut;
+ properties
+ SecurityClassificationProperties::Trusted => True applies to transformerProcessFlowPath;
+ end TransformerProcess.imp;
+
+ system Transformer
+ features
+ dataIn: in data port PrivateDataSet;
+ dataOut: out data port PublicDataSet;
+ flows
+ transformerSystemFlowPath: flow path dataIn -> dataOut;
+ properties
+ SecurityClassificationProperties::Security_Level => TopSecret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A, E);
+ SecurityClassificationProperties::Trusted => True applies to transformerSystemFlowPath;
+ end Transformer;
+
+ system implementation Transformer.imp
+ subcomponents
+ transformerProcessor: processor TransformerProcessor.imp;
+ transformerProcess: process TransformerProcess.imp;
+ connections
+ connDataIn: port dataIn -> transformerProcess.dataIn;
+ connDataOut: port transformerProcess.dataOut -> dataOut;
+ flows
+ transformerSystemFlowPath: flow path dataIn -> connDataIn -> transformerProcess.transformerProcessFlowPath -> connDataOut -> dataOut;
+ properties
+ SecurityClassificationProperties::Trusted => True applies to transformerSystemFlowPath;
+ Actual_Processor_Binding => (reference (transformerProcessor)) applies to transformerProcess;
+ end Transformer.imp;
+
+---
+ system ExampleSystem
+ properties
+ SecurityClassificationProperties::Security_Level => TopSecret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A, E);
+ end ExampleSystem;
+
+ -- system containing producer and consumer subsystems with a built in transformer for translating the data type
+ system implementation ExampleSystem.builtInTransformerImp
+ subcomponents
+ provider: system Provider.imp;
+ consumer: system Consumer.imp;
+ transformerProcessor: processor TransformerProcessor.imp;
+ transformerProcess: process TransformerProcess.imp;
+ internalBus: bus InternalBus.imp;
+ externalBus: bus ExternalBus.imp;
+ connections
+ connProviderTransformer: port provider.dataOut -> transformerProcess.dataIn;
+ connTransformerConsumer: port transformerProcess.dataOut -> consumer.dataIn;
+
+ flows
+ -- flow from producer thread to consumer thread via built in transformer
+ endToEndFlow: end to end flow provider.flowSource -> connProviderTransformer -> transformerProcess.transformerProcessFlowPath -> connTransformerConsumer -> consumer.flowSink;
+ properties
+ Actual_Connection_Binding => (
+ reference (internalBus)) applies to connProviderTransformer, provider.conn, provider.providerProcess.conn, transformerProcess.connDataIn;
+ Actual_Connection_Binding => (
+ reference (externalBus)) applies to connTransformerConsumer, consumer.conn, consumer.consumerProcess.conn, transformerProcess.connDataOut;
+ Actual_Processor_Binding => (reference (transformerProcessor)) applies to transformerProcess;
+ end ExampleSystem.builtInTransformerImp;
+
+ system implementation ExampleSystem.externalTransformerImp
+ subcomponents
+ provider: system Provider.imp;
+ consumer: system Consumer.imp;
+ transformer: system Transformer.imp;
+ internalBus: bus InternalBus.imp;
+ externalBus: bus ExternalBus.imp;
+ connections
+ connProviderTransformer: port provider.dataOut -> transformer.dataIn;
+ connTransformerConsumer: port transformer.dataOut -> consumer.dataIn;
+
+ flows
+ -- flow form producer thread to consumer thread via transformer system
+ endToEndFlow: end to end flow provider.flowSource -> connProviderTransformer -> transformer.transformerSystemFlowPath -> connTransformerConsumer -> consumer.flowSink;
+ properties
+ Actual_Connection_Binding => (
+ reference (internalBus)) applies to connProviderTransformer, provider.conn, provider.providerProcess.conn, transformer.connDataIn, transformer.transformerProcess.connDataIn;
+ Actual_Connection_Binding => (
+ reference (externalBus)) applies to connTransformerConsumer, consumer.conn, consumer.consumerProcess.conn, transformer.connDataOut, transformer.transformerProcess.connDataOut;
+ end ExampleSystem.externalTransformerImp;
+
+end CompleteBoundFlowExample;
\ No newline at end of file
diff --git a/examples/org.osate.examples/examples/SecurityAnalysisExample/Examples/CompleteFlowExample.aadl b/examples/org.osate.examples/examples/SecurityAnalysisExample/Examples/CompleteFlowExample.aadl
new file mode 100644
index 00000000000..4dfea27dea1
--- /dev/null
+++ b/examples/org.osate.examples/examples/SecurityAnalysisExample/Examples/CompleteFlowExample.aadl
@@ -0,0 +1,233 @@
+package CompleteFlowExample
+-- Producer - consumer example with confidentiality reducing middle-man (transformer)
+-- Both the producer and transformer are marked as private systems, which are therefore allowed to handle private data.
+-- The consumer system is declared as 'public'. The private data provided by the transformer translated into public data while preserving confidentiality.
+-- The flow of data is described using flows within the individual systems.
+-- This example does not consider implications of hardware security.
+public
+ with SecurityClassificationProperties;
+
+ data PrivateDataSet
+ properties
+ SecurityClassificationProperties::Security_Level => TopSecret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end PrivateDataSet;
+
+ data PublicDataSet
+ properties
+ SecurityClassificationProperties::Security_Level => No_Clearance;
+ SecurityClassificationProperties::Security_Level_Caveats => (A, E);
+ end PublicDataSet;
+
+---
+ -- private provider system with flow source
+ system Provider
+ features
+ dataOut: out data port PrivateDataSet;
+ flows
+ flowSource: flow source dataOut;
+ properties
+ SecurityClassificationProperties::Security_Level => TopSecret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end Provider;
+
+ process ProviderProcess
+ features
+ dataOut: out data port PrivateDataSet;
+ flows
+ flowSource: flow source dataOut;
+ end ProviderProcess;
+
+ thread ProviderThread
+ features
+ dataOut: out data port PrivateDataSet;
+ flows
+ flowSource: flow source dataOut;
+ end ProviderThread;
+
+ thread implementation ProviderThread.imp
+ end ProviderThread.imp;
+
+ process implementation ProviderProcess.imp
+ subcomponents
+ providerThread: thread ProviderThread.imp;
+ connections
+ conn: port providerThread.dataOut -> dataOut;
+ flows
+ flowSource: flow source providerThread.flowSource -> conn -> dataOut;
+ end ProviderProcess.imp;
+
+ system implementation Provider.imp
+ subcomponents
+ providerProcess: process ProviderProcess.imp;
+ connections
+ conn: port providerProcess.dataOut -> dataOut;
+ flows
+ flowSource: flow source providerProcess.flowSource -> conn -> dataOut;
+ end Provider.imp;
+
+---
+ -- public consumer system with flow sink
+ system Consumer
+ features
+ dataIn: in data port PublicDataSet;
+ flows
+ flowSink: flow sink dataIn;
+ properties
+ SecurityClassificationProperties::Security_Level => No_Clearance;
+ SecurityClassificationProperties::Security_Level_Caveats => (A, E);
+ end Consumer;
+
+ process ConsumerProcess
+ features
+ dataIn: in data port PublicDataSet;
+ flows
+ flowSink: flow sink dataIn;
+ end ConsumerProcess;
+
+ thread ConsumerThread
+ features
+ dataIn: in data port PublicDataSet;
+ flows
+ flowSink: flow sink dataIn;
+ end ConsumerThread;
+
+ thread implementation ConsumerThread.imp
+
+ end ConsumerThread.imp;
+
+ process implementation ConsumerProcess.imp
+ subcomponents
+ consumerThread: thread ConsumerThread.imp;
+ connections
+ conn: port dataIn -> consumerThread.dataIn;
+ flows
+ flowSink: flow sink dataIn -> conn -> consumerThread.flowSink;
+ end ConsumerProcess.imp;
+
+ system implementation Consumer.imp
+ subcomponents
+ consumerProcess: process ConsumerProcess.imp;
+ connections
+ conn: port dataIn -> consumerProcess.dataIn;
+ flows
+ flowSink: flow sink dataIn -> conn -> consumerProcess.flowSink;
+ end Consumer.imp;
+
+---
+ -- private transformer system with flow path (private in, public out) - transforms data while retaining confidentiality
+ process TransformerProcess
+ features
+ dataIn: in data port PrivateDataSet;
+ dataOut: out data port PublicDataSet;
+ flows
+ transformerProcessFlowPath: flow path dataIn -> dataOut;
+
+ properties
+ SecurityClassificationProperties::Security_Level => TopSecret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A, E);
+ end TransformerProcess;
+
+ thread TransformerThread
+ features
+ dataIn: in data port PrivateDataSet;
+ dataOut: out data port PublicDataSet;
+ flows
+ transformerThreadFlowPath: flow path dataIn -> dataOut;
+ properties
+ -- configure flow - which transforms the data type - to retain confidentiality (anonymization process)
+ SecurityClassificationProperties::Trusted => True applies to transformerThreadFlowPath;
+ end TransformerThread;
+
+ thread implementation TransformerThread.imp
+
+ end TransformerThread.imp;
+
+ process implementation TransformerProcess.imp
+ subcomponents
+ transformerThread: thread TransformerThread.imp;
+ connections
+ connDataIn: port dataIn -> transformerThread.dataIn;
+ connDataOut: port transformerThread.dataOut -> dataOut;
+ flows
+ transformerProcessFlowPath: flow path dataIn -> connDataIn -> transformerThread.transformerThreadFlowPath -> connDataOut -> dataOut;
+ properties
+ SecurityClassificationProperties::Trusted => True applies to transformerProcessFlowPath;
+ end TransformerProcess.imp;
+
+ system Transformer
+ features
+ dataIn: in data port PrivateDataSet;
+ dataOut: out data port PublicDataSet;
+ flows
+ transformerSystemFlowPath: flow path dataIn -> dataOut;
+ properties
+ SecurityClassificationProperties::Security_Level => TopSecret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A, E);
+ SecurityClassificationProperties::Trusted => True applies to transformerSystemFlowPath;
+ end Transformer;
+
+ system implementation Transformer.imp
+ subcomponents
+ transformerProcess: process TransformerProcess.imp;
+ connections
+ connDataIn: port dataIn -> transformerProcess.dataIn;
+ connDataOut: port transformerProcess.dataOut -> dataOut;
+ flows
+ transformerSystemFlowPath: flow path dataIn -> connDataIn -> transformerProcess.transformerProcessFlowPath -> connDataOut -> dataOut;
+ properties
+ SecurityClassificationProperties::Trusted => True applies to transformerSystemFlowPath;
+ end Transformer.imp;
+
+---
+ system ExampleSystem
+ properties
+ SecurityClassificationProperties::Security_Level => TopSecret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A, E);
+ end ExampleSystem;
+
+ -- incomplete system specification which moves data from the producer System to the consumer system via the transformer
+ system implementation ExampleSystem.incomplete
+ subcomponents
+ provider: system Provider;
+ consumer: system Consumer;
+ transformer: system Transformer;
+ connections
+ connProviderTransformer: port provider.dataOut -> transformer.dataIn;
+ connTransformerConsumer: port transformer.dataOut -> consumer.dataIn;
+ flows
+ endToEndFlow: end to end flow provider -> connProviderTransformer -> Transformer.transformerSystemFlowPath -> connTransformerConsumer -> consumer;
+ end ExampleSystem.incomplete;
+
+ -- system containing producer and consumer subsystems with a built in transformer for translating the data type
+ system implementation ExampleSystem.builtInTransformerImp
+ subcomponents
+ provider: system Provider.imp;
+ consumer: system Consumer.imp;
+ transformerProcess: process TransformerProcess.imp;
+ connections
+ connProviderTransformer: port provider.dataOut -> transformerProcess.dataIn;
+ connTransformerConsumer: port transformerProcess.dataOut -> consumer.dataIn;
+
+ flows
+ -- flow from producer thread to consumer thread via built in transformer
+ endToEndFlow: end to end flow provider.flowSource -> connProviderTransformer -> transformerProcess.transformerProcessFlowPath -> connTransformerConsumer -> consumer.flowSink;
+
+ end ExampleSystem.builtInTransformerImp;
+
+ system implementation ExampleSystem.externalTransformerImp
+ subcomponents
+ provider: system Provider.imp;
+ consumer: system Consumer.imp;
+ transformer: system Transformer.imp;
+ connections
+ connProviderTransformer: port provider.dataOut -> transformer.dataIn;
+ connTransformerConsumer: port transformer.dataOut -> consumer.dataIn;
+
+ flows
+ -- flow form producer thread to consumer thread via transformer system
+ endToEndFlow: end to end flow provider.flowSource -> connProviderTransformer -> transformer.transformerSystemFlowPath -> connTransformerConsumer -> consumer.flowSink;
+
+ end ExampleSystem.externalTransformerImp;
+
+end CompleteFlowExample;
\ No newline at end of file
diff --git a/examples/org.osate.examples/examples/SecurityAnalysisExample/Examples/CompleteSystemExample.aadl b/examples/org.osate.examples/examples/SecurityAnalysisExample/Examples/CompleteSystemExample.aadl
new file mode 100644
index 00000000000..42827c6d5e7
--- /dev/null
+++ b/examples/org.osate.examples/examples/SecurityAnalysisExample/Examples/CompleteSystemExample.aadl
@@ -0,0 +1,96 @@
+-- Copyright (c) 2004-2023 Carnegie Mellon University. All right reserved.
+package CompleteSystemExample
+public
+ with SecurityClassificationProperties;
+
+ data X
+ properties
+ SecurityClassificationProperties::Security_Level => Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end X;
+
+ data Y
+ properties
+ SecurityClassificationProperties::Security_Level => Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (B);
+ end Y;
+
+ data Z
+ properties
+ SecurityClassificationProperties::Security_Level => Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (A, B);
+ end Z;
+
+ system Producer1
+ features
+ output: out data port X;
+ flows
+ src: flow source output;
+ properties
+ SecurityClassificationProperties::Security_Level => Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end Producer1;
+
+ system Producer2
+ features
+ output: out data port Y;
+ flows
+ src: flow source output;
+ properties
+ SecurityClassificationProperties::Security_Level => Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (B);
+ end Producer2;
+
+ system Computer
+ features
+ in1: in data port X;
+ in2: in data port Y;
+ result: out data port Z;
+ interrupt: out event port {
+ SecurityClassificationProperties::Security_Level => Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (C);
+ };
+ flows
+ through1: flow path in1 -> result;
+ through2: flow path in2 -> result;
+ src: flow source interrupt;
+ properties
+ SecurityClassificationProperties::Security_Level => Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (A, B, C);
+ end Computer;
+
+ system Consumer
+ features
+ input: in data port Z;
+ interrupt: in event port {
+ SecurityClassificationProperties::Security_Level => Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (C);
+ };
+ flows
+ snk1: flow sink input;
+ snk2: flow sink interrupt;
+ properties
+ SecurityClassificationProperties::Security_Level => Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (A, B, C);
+ end Consumer;
+
+ system CompleteSystem
+ properties
+ SecurityClassificationProperties::Security_Level => Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (A, B, C);
+ end CompleteSystem;
+
+ system implementation CompleteSystem.Impl
+ subcomponents
+ src1: system Producer1;
+ src2: system Producer2;
+ comp: system Computer;
+ dest: system Consumer;
+ connections
+ c1: port src1.output -> comp.in1;
+ c2: port src2.output -> comp.in2;
+ c3: port comp.result -> dest.input;
+ c4: port comp.interrupt -> dest.interrupt;
+ end CompleteSystem.Impl;
+
+end CompleteSystemExample;
\ No newline at end of file
diff --git a/examples/org.osate.examples/examples/SecurityAnalysisExample/SecurityClassificationProperties.aadl b/examples/org.osate.examples/examples/SecurityAnalysisExample/SecurityClassificationProperties.aadl
new file mode 100644
index 00000000000..84728a54ec7
--- /dev/null
+++ b/examples/org.osate.examples/examples/SecurityAnalysisExample/SecurityClassificationProperties.aadl
@@ -0,0 +1,19 @@
+-- Copyright (c) 2004-2023 Carnegie Mellon University. All right reserved.
+-- Distribution Statement A: Approved for Public Release; Distribution is Unlimited.
+-- @codegen-package org.osate.security.contributions.securityclassificationproperties
+property set SecurityClassificationProperties is
+
+ -- Both the Security_Level and Security_Level_Caveats can be overridden by custom definitions.
+ Security_Level: inherit enumeration (TopSecret, Secret, Confidential, No_Clearance) applies to (system, processor,
+ virtual processor, thread,
+ thread group, subprogram, subprogram group, data, port,
+ feature group, process, device, memory, bus, abstract, flow,
+ parameter, access);
+ Security_Level_Caveats: inherit list of enumeration (A, B, C, D, E, F) applies to (
+ system, processor, virtual processor, thread,
+ thread group, subprogram, subprogram group, data, port,
+ feature group, process, device, memory, bus, abstract, flow,
+ parameter, access);
+
+ Trusted: aadlboolean => false applies to (flow);
+end SecurityClassificationProperties;
\ No newline at end of file
diff --git a/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/BindingExample.aadl b/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/BindingExample.aadl
new file mode 100644
index 00000000000..3ec87e90776
--- /dev/null
+++ b/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/BindingExample.aadl
@@ -0,0 +1,140 @@
+package BindingExample
+-- Example: Rule 5 - The security label of a bound component/feature must be dominated by the component they are bound to.
+-- : Rule 6 - The labels of the data used in a connection must dominate the bus to which the connection is bound.
+public
+ with SecurityClassificationProperties;
+ with Base_Types;
+
+ data customData extends Base_Types::Integer_64
+ properties
+ SecurityClassificationProperties::Security_Level => Secret;
+ SecurityClassificationProperties::Security_Level_Caveats => (C);
+ end customData;
+
+ thread ExampleThread
+ features
+ port1: in data port customData;
+ port2: out data port customData;
+ end ExampleThread;
+
+--
+ process ExampleProcess
+ features
+ port1: in data port customData;
+ port2: out data port customData;
+ end ExampleProcess;
+
+ process implementation ExampleProcess.imp
+ subcomponents
+ t1: thread ExampleThread;
+ connections
+ fwd: port port1 -> t1.port1;
+ fwd2: port t1.port2 -> port2;
+ end ExampleProcess.imp;
+
+ process implementation ExampleProcess.Secret extends ExampleProcess.imp
+ properties
+ SecurityClassificationProperties::Security_Level => Secret;
+ SecurityClassificationProperties::Security_Level_Caveats => (C);
+ end ExampleProcess.Secret;
+
+ process implementation ExampleProcess.Confidential extends ExampleProcess.imp
+ properties
+ SecurityClassificationProperties::Security_Level => Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (C);
+ end ExampleProcess.Confidential;
+
+--
+ processor ExampleProcessor
+ end ExampleProcessor;
+
+ processor implementation ExampleProcessor.Confidential
+ properties
+ SecurityClassificationProperties::Security_Level => Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (C);
+ end ExampleProcessor.Confidential;
+
+ processor implementation ExampleProcessor.Secret
+ properties
+ SecurityClassificationProperties::Security_Level => Secret;
+ SecurityClassificationProperties::Security_Level_Caveats => (C);
+ end ExampleProcessor.Secret;
+
+--
+ bus ExampleBus
+ end ExampleBus;
+
+ bus implementation ExampleBus.Secret
+ properties
+ SecurityClassificationProperties::Security_Level => Secret; --Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (C);
+ end ExampleBus.Secret;
+
+ bus implementation ExampleBus.Confidential
+ properties
+ SecurityClassificationProperties::Security_Level => Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (C);
+ end ExampleBus.Confidential;
+
+--
+ memory ExampleMemory
+ end ExampleMemory;
+
+ memory implementation ExampleMemory.Secret
+ properties
+ SecurityClassificationProperties::Security_Level => Secret;
+ SecurityClassificationProperties::Security_Level_Caveats => (C);
+ end ExampleMemory.Secret;
+
+ memory implementation ExampleMemory.Confidential
+ properties
+ SecurityClassificationProperties::Security_Level => Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (C);
+ end ExampleMemory.Confidential;
+
+--
+ system TestSystem
+ properties
+ SecurityClassificationProperties::Security_Level => Secret;
+ SecurityClassificationProperties::Security_Level_Caveats => (C);
+ end TestSystem;
+
+ system implementation TestSystem.valid
+ subcomponents
+ processorS: processor ExampleProcessor.Secret;
+ processS: process ExampleProcess.Secret;
+ memS: memory ExampleMemory.Secret;
+ busS: bus ExampleBus.Secret;
+ connections
+ loop: port processS.port2 -> processS.port1;
+
+ properties
+
+ Actual_Processor_Binding => (reference (processorS)) applies to processS;
+ Actual_Memory_Binding => (reference (memS)) applies to processS.t1.port1;
+ Actual_Connection_Binding => (reference (busS)) applies to loop;
+
+ end TestSystem.valid;
+
+ system implementation TestSystem.invalid
+ subcomponents
+ processorC: processor ExampleProcessor.Confidential;
+ processS: process ExampleProcess.Secret;
+ memC: memory ExampleMemory.Confidential;
+ busC: bus ExampleBus.Confidential;
+ connections
+ loop: port processS.port2 -> processS.port1;
+
+ properties
+ -- Bind Secret Process to Secret Processor
+ Actual_Processor_Binding => (reference (processorC)) applies to processS;
+
+ -- Secret Data stored on Confidential memory
+ Actual_Memory_Binding => (reference (memC)) applies to processS.t1.port1;
+
+ -- Secret Data on connection end bound to confidential bus
+ Actual_Connection_Binding => (reference (busC)) applies to loop;
+
+ end TestSystem.invalid;
+
+end BindingExample;
\ No newline at end of file
diff --git a/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/ConnectionEquality.aadl b/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/ConnectionEquality.aadl
new file mode 100644
index 00000000000..20cc6a7587f
--- /dev/null
+++ b/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/ConnectionEquality.aadl
@@ -0,0 +1,44 @@
+package ConnectionEquality
+-- Example: Rule 9 - Both labels at the end of a connection must be identical
+public
+ with SecurityClassificationProperties;
+ with Base_Types;
+
+ data CustomData extends Base_Types::Integer_64
+ properties
+ SecurityClassificationProperties::Security_Level => Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end CustomData;
+
+ system SubSystem
+ features
+ TSPortIn: in data port CustomData {SecurityClassificationProperties::Security_Level => TopSecret;};
+ TSPortIn2: in data port CustomData {SecurityClassificationProperties::Security_Level => TopSecret;};
+ CPortIn: in data port CustomData;
+ TSPortOut: out data port CustomData {SecurityClassificationProperties::Security_Level => TopSecret;};
+ CPortOut: out data port CustomData;
+ end SubSystem;
+
+ system TestSystem
+ properties
+ SecurityClassificationProperties::Security_Level => TopSecret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end TestSystem;
+
+ system implementation TestSystem.imp
+ subcomponents
+ subSystem1: system SubSystem;
+ subSystem2: system SubSystem;
+ connections
+ -- Connection with same security label on both ends
+ validConn: port subSystem1.TSPortOut -> subSystem2.TSPortIn;
+
+ -- Connection with high security label on destination
+ invalidConn: port subSystem1.CPortOut -> subSystem2.TSPortIn2;
+
+ -- Connection with lower security label on destination
+ invalidConn2: port subSystem1.TSPortOut -> subSystem2.CPortIn;
+
+ end TestSystem.imp;
+
+end ConnectionEquality;
\ No newline at end of file
diff --git a/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/FeatureClassifierEquality.aadl b/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/FeatureClassifierEquality.aadl
new file mode 100644
index 00000000000..07c3b874701
--- /dev/null
+++ b/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/FeatureClassifierEquality.aadl
@@ -0,0 +1,28 @@
+package FeatureClassifierEquality
+-- Example: Rule 8 enforcement. Features and their classifiers must have the same security label.
+public
+ with SecurityClassificationProperties;
+
+ data CustomData
+ properties
+ SecurityClassificationProperties::Security_Level => Secret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end CustomData;
+
+ system TestSystem
+ features
+ port0: in data port CustomData;
+ port1: in data port CustomData {SecurityClassificationProperties::Security_Level => Secret;};
+
+ -- Invalid feature label assignment (not equal to label used in classifier)
+ port2: in data port CustomData {SecurityClassificationProperties::Security_Level => TopSecret;};
+ properties
+ SecurityClassificationProperties::Security_Level => TopSecret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end TestSystem;
+
+ system implementation TestSystem.imp
+
+ end TestSystem.imp;
+
+end FeatureClassifierEquality;
\ No newline at end of file
diff --git a/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/FeatureGroupDomination.aadl b/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/FeatureGroupDomination.aadl
new file mode 100644
index 00000000000..bc0176a14fa
--- /dev/null
+++ b/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/FeatureGroupDomination.aadl
@@ -0,0 +1,32 @@
+package FeatureGroupDomination
+-- Example: Rule 2 - All features in a feature group must be dominated by the security label of the feature group
+public
+ with Base_Types;
+ with SecurityClassificationProperties;
+
+ feature group FeatureGroup
+ features
+ p1: in data port Base_Types::Integer_64 {SecurityClassificationProperties::Security_Level => TopSecret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);};
+ p2: out data port Base_Types::Integer_64 {SecurityClassificationProperties::Security_Level => TopSecret;
+ SecurityClassificationProperties::Security_Level_Caveats => (B);};
+ end FeatureGroup;
+
+ system FeatureGroupTestSystem
+ features
+ -- inherited labels, least privilege violation
+ group0: feature group FeatureGroup;
+ -- modified, valid labels
+ group1: feature group FeatureGroup {SecurityClassificationProperties::Security_Level_Caveats => (A, B);};
+ -- invalid security label (does not dominate all element in feature group)
+ group2: feature group FeatureGroup {SecurityClassificationProperties::Security_Level_Caveats => (A, C);};
+
+ properties
+ SecurityClassificationProperties::Security_Level => TopSecret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A, B, C);
+ end FeatureGroupTestSystem;
+
+ system implementation FeatureGroupTestSystem.imp
+ end FeatureGroupTestSystem.imp;
+
+end FeatureGroupDomination;
\ No newline at end of file
diff --git a/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/FlowSanitization.aadl b/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/FlowSanitization.aadl
new file mode 100644
index 00000000000..41a517de39c
--- /dev/null
+++ b/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/FlowSanitization.aadl
@@ -0,0 +1,50 @@
+package FlowSanitization
+-- Example Rule 7: Star-Property (flow destination must dominate source security label)
+-- Rule 11: Trusted/Sanitized Flows - if a flow is marked as Trusted Rule 7 does not apply
+-- Sanitization Metrics
+public
+ with Base_Types;
+ with SecurityClassificationProperties;
+
+ data TopSecretData extends Base_Types::Integer_64
+ properties
+ SecurityClassificationProperties::Security_Level => TopSecret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end TopSecretData;
+
+ data ConfidentialData extends Base_Types::Integer_64
+ properties
+ SecurityClassificationProperties::Security_Level => Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end ConfidentialData;
+
+ system TestSystem
+ features
+ CdataIn: in data port ConfidentialData;
+ TSdataIn: in data port TopSecretData;
+ CdataOut: out data port ConfidentialData;
+ TSdataOut: out data port TopSecretData;
+
+ flows
+ -- Valid
+ validFlowPath: flow path CdataIn -> TSdataOut;
+
+ -- Invalid flow
+ invalidFlowPath: flow path TSdataIn -> CdataOut;
+
+ -- Invalid flow
+ trustedFlowPath: flow path TSdataIn -> CdataOut {SecurityClassificationProperties::Trusted => true;};
+
+ -- Suspicious flow (unnecessary trusted statement)
+ susFlowPath: flow path CdataIn -> TSdataOut {SecurityClassificationProperties::Trusted => true;};
+
+ properties
+ SecurityClassificationProperties::Security_Level => TopSecret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end TestSystem;
+
+ system implementation TestSystem.imp
+
+ end TestSystem.imp;
+
+end FlowSanitization;
\ No newline at end of file
diff --git a/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/ImplicitFlowDetection.aadl b/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/ImplicitFlowDetection.aadl
new file mode 100644
index 00000000000..d1a947f9fe4
--- /dev/null
+++ b/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/ImplicitFlowDetection.aadl
@@ -0,0 +1,103 @@
+package ImplicitFlowDetection
+-- Example: Missing implicit flows which are required for analysis
+public
+ with SecurityClassificationProperties;
+
+---
+ data CustomData
+ properties
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end CustomData;
+
+ data ConfidentialData extends CustomData
+ properties
+ SecurityClassificationProperties::Security_Level => Confidential;
+ end ConfidentialData;
+
+ data TopSecretData extends CustomData
+ properties
+ SecurityClassificationProperties::Security_Level => TopSecret;
+ end TopSecretData;
+
+---
+ system SubSystem
+ --- Basic subsystem with various flows
+ features
+ inPortTS: in data port TopSecretData;
+ inPortC: in data port ConfidentialData;
+ outPortTS: out data port TopSecretData;
+ outPortC: out data port ConfidentialData;
+ snkPort: in data port TopSecretData;
+ srcPort: out data port TopSecretData;
+ flows
+ fwdTS: flow path inPortTS -> outPortTS;
+ fwdC: flow path inPortC -> outPortC;
+ trustedFlow: flow path inPortTS -> outPortC {SecurityClassificationProperties::Trusted => true;};
+ flowsnk: flow sink snkPort;
+ flowsrc: flow source srcPort;
+ end SubSystem;
+
+ system TestSystem
+ features
+ inPortTS: in data port TopSecretData;
+ outPortTS: out data port TopSecretData;
+ outPortTS2: out data port TopSecretData;
+ outPortC: out data port ConfidentialData;
+ flows
+ flow1: flow path inPortTS -> outPortTs;
+ -- missingFlow: flow path inPortTS -> outPortC;
+ -- missingSink: flow sink inPortTS;
+ -- missingSource: flow source outPortTS2;
+ properties
+ SecurityClassificationProperties::Security_Level => TopSecret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end TestSystem;
+
+ system implementation TestSystem.imp
+ -- System which contains implicit flows, commented out above
+ subcomponents
+ subSystem: system SubSystem;
+ connections
+ -- from the flow contained in the subsystem we derive it's out-ports as the starting point for further analysis (in this case conn2 and conn3)
+ -- this output can be reached based on flows defined in this component
+ conn1: port inPortTS -> subSystem.inPortTS;
+ conn2: port subSystem.outPortTS -> outPortTS;
+
+ -- the destination of this feature reachable via a flow defined in the subcomponent, but it is not reachable via flows from this component
+ conn3: port subSystem.outPortC -> outPortC;
+
+ -- connection sinks in subsystem. No sink specified in this system
+ conn4: port inPortTS -> subSystem.snkPort;
+
+ -- connection has a source in SubSystem. No source specified in this system.
+ conn5: port subSystem.srcPort -> outPortTS2;
+ end TestSystem.imp;
+
+ system SnakeSystem
+ -- System does not specify a flow
+ features
+ inPortTS: in data port TopSecretData;
+ outPortC: out data port ConfidentialData;
+ --flows
+ -- missingFlow: flow path inPortTS -> outPortC;
+ properties
+ SecurityClassificationProperties::Security_Level => TopSecret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end SnakeSystem;
+
+ system implementation SnakeSystem.imp
+ subcomponents
+ subSystem1: system SubSystem;
+ subSystem2: system SubSystem;
+ subSystem3: system SubSystem;
+ subSystem4: system SubSystem;
+ connections
+ -- Implicit flow through multiple connection and subcomponent flows
+ conn1: port inPortTS -> subSystem1.inPortTS;
+ conn2: port subSystem1.outPortC -> subSystem2.inPortC;
+ conn3: port subSystem2.outPortC -> subSystem3.inPortC;
+ conn4: port subSystem3.outPortC -> subSystem4.inPortC;
+ conn5: port subSystem4.outPortC -> outPortC;
+ end SnakeSystem.imp;
+
+end ImplicitFlowDetection;
\ No newline at end of file
diff --git a/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/LeastPrivilegeExample.aadl b/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/LeastPrivilegeExample.aadl
new file mode 100644
index 00000000000..0c857ce3d5a
--- /dev/null
+++ b/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/LeastPrivilegeExample.aadl
@@ -0,0 +1,84 @@
+package LeastPrivilegeExample
+-- Example: Rule 10
+public
+ with SecurityClassificationProperties;
+
+--
+ data NoClearanceData
+ properties
+ SecurityClassificationProperties::Security_Level => No_Clearance;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end NoClearanceData;
+
+ data ConfidentialData
+ properties
+ SecurityClassificationProperties::Security_Level => Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end ConfidentialData;
+
+ data TopSecretData
+ properties
+ SecurityClassificationProperties::Security_Level => TopSecret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end TopSecretData;
+
+ data SecretData
+ end SecretData;
+
+ data implementation SecretData.imp
+ subcomponents
+ invalidSubData: data ConfidentialData;
+ properties
+ SecurityClassificationProperties::Security_Level => Secret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A, B);
+ end SecretData.imp;
+
+--
+ feature group FeatureGroup
+ features
+ p1: in data port ConfidentialData;
+ p2: in data port SecretData.imp;
+ end FeatureGroup;
+
+--
+ thread NoClearanceThread
+ properties
+ SecurityClassificationProperties::Security_Level => No_Clearance;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end NoClearanceThread;
+
+ process ConfidentialProcess
+ features
+ port1: in data port NoClearanceData;
+ properties
+ SecurityClassificationProperties::Security_Level => Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (A, B);
+ end ConfidentialProcess;
+
+ process implementation ConfidentialProcess.imp
+ subcomponents
+ noClearanceThread: thread NoClearanceThread;
+ end ConfidentialProcess.imp;
+
+--
+ system TestSystem
+ features
+ cData: in data port ConfidentialData;
+ sData: in data port SecretData.imp;
+
+ featureGroup: in feature group FeatureGroup {
+ SecurityClassificationProperties::Security_Level => Secret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A, B, C);};
+
+ properties
+ SecurityClassificationProperties::Security_Level => TopSecret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A, B, C, D, E);
+ end TestSystem;
+
+ system implementation TestSystem.imp
+ subcomponents
+ cProcess1: process ConfidentialProcess;
+ cProcess2: process ConfidentialProcess.imp;
+ end TestSystem.imp;
+
+end LeastPrivilegeExample;
\ No newline at end of file
diff --git a/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/OperationMode.aadl b/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/OperationMode.aadl
new file mode 100644
index 00000000000..9e94643b8f4
--- /dev/null
+++ b/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/OperationMode.aadl
@@ -0,0 +1,82 @@
+package OperationMode
+-- This file contains various invalid configurations given that the operation mode is not valid on all components
+public
+ with SecurityClassificationProperties;
+ with Base_Types;
+
+ data ConfidentialData
+ properties
+ SecurityClassificationProperties::Security_Level => Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end ConfidentialData;
+
+ data SecretData
+ properties
+ SecurityClassificationProperties::Security_Level => Secret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end SecretData;
+
+ processor TestProcessor
+ features
+ sPortIn: in data port SecretData;
+ notSoSecretPortOut: out data port SecretData {
+ SecurityClassificationProperties::Security_Level => TopSecret in modes (invalid), Secret;};
+ cPortIn: in data port ConfidentialData {
+ SecurityClassificationProperties::Security_Level => Confidential in modes (valid), TopSecret;};
+ cPortOut: out data port ConfidentialData;
+ flows
+ flow1: flow path sPortIn -> cPortOut {SecurityClassificationProperties::Trusted => true;};
+ modes
+ valid: initial mode;
+ invalid: mode;
+ end TestProcessor;
+
+ bus goodBus
+ properties
+ SecurityClassificationProperties::Security_Level => Secret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end goodBus;
+
+ bus evilBus
+ properties
+ SecurityClassificationProperties::Security_Level => No_Clearance;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end evilBus;
+
+ system TestSystem
+ features
+ sPortIn: in data port SecretData;
+ cPortOut: out data port ConfidentialData;
+ tsPortOut: out data port Base_Types::Integer_64 {
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ SecurityClassificationProperties::Security_Level => TopSecret in modes (invalid), Confidential;};
+ flows
+ flow1: flow path sPortIn -> cPortOut {SecurityClassificationProperties::Trusted => true in modes (
+ valid), false;};
+ modes
+ valid: initial mode;
+ invalid: mode;
+ properties
+ SecurityClassificationProperties::Security_Level => Secret in modes (valid), Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+
+ end TestSystem;
+
+ system implementation TestSystem.imp
+ subcomponents
+ p1: processor TestProcessor;
+ p2: processor TestProcessor;
+ evilBus: bus evilBus;
+ goodBus: bus goodBus;
+ evilBus2: bus evilBus {SecurityClassificationProperties::Security_Level => No_Clearance;
+ SecurityClassificationProperties::Security_Level_Caveats => (A, B, C);} in modes (invalid);
+ connections
+ conn1: port p1.cPortOut -> p2.cPortIn in modes (valid);
+ conn2: port p1.notSoSecretPortOut -> p2.sPortIn in modes (invalid);
+ properties
+ Actual_Connection_Binding => (reference (evilBus)) in modes (invalid), (
+ reference (goodBus)) applies to conn2;
+
+ end TestSystem.imp;
+
+end OperationMode;
\ No newline at end of file
diff --git a/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/SubcomponentDomination.aadl b/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/SubcomponentDomination.aadl
new file mode 100644
index 00000000000..f83f79d3bf0
--- /dev/null
+++ b/examples/org.osate.examples/examples/SecurityAnalysisExample/Tests/SubcomponentDomination.aadl
@@ -0,0 +1,53 @@
+package SubcomponentDomination
+-- Example: Rule 1 - features inside of a component must be dominated by the label of the component
+-- Rule 3 - Security labels of components must dominate the Security labels of their subcomponents
+public
+ with SecurityClassificationProperties;
+ with Base_Types;
+
+ data CustomData
+ properties
+ SecurityClassificationProperties::Security_Level => Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end CustomData;
+
+ data implementation CustomData.imp
+ subcomponents
+ -- valid data subcomponent
+ otherData0: data Base_Types::Integer_64 {SecurityClassificationProperties::Security_Level => Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);};
+ -- invalid subcomponent (not dominated by parent)
+ otherData1: data Base_Types::Integer_64 {SecurityClassificationProperties::Security_Level => TopSecret;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);};
+ end CustomData.imp;
+
+ processor ExampleProcessor
+ properties
+ SecurityClassificationProperties::Security_Level => Confidential;
+ end ExampleProcessor;
+
+ processor implementation ExampleProcessor.imp
+ properties
+ SecurityClassificationProperties::Security_Level => TopSecret;
+ end ExampleProcessor.imp;
+
+ system TestSystem
+ features
+ port1: in data port CustomData;
+ port2: in data port CustomData.imp;
+ properties
+ SecurityClassificationProperties::Security_Level => Confidential;
+ SecurityClassificationProperties::Security_Level_Caveats => (A);
+ end TestSystem;
+
+ system implementation TestSystem.imp
+
+ subcomponents
+ -- valid - dominated
+ processor0: processor ExampleProcessor;
+ -- invalid - not dominated
+ processor1: processor ExampleProcessor.imp;
+
+ end TestSystem.imp;
+
+end SubcomponentDomination;
\ No newline at end of file
diff --git a/examples/org.osate.examples/examples/SecurityAnalysisExample/doc/html/readme.html b/examples/org.osate.examples/examples/SecurityAnalysisExample/doc/html/readme.html
new file mode 100644
index 00000000000..448de5935c7
--- /dev/null
+++ b/examples/org.osate.examples/examples/SecurityAnalysisExample/doc/html/readme.html
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+ Security and Confidentiality Analysis Example
+ This example collection contains example systems and Test cases for individual rules used in the Confidentiality and Security Analysis.
+
+
\ No newline at end of file
diff --git a/examples/org.osate.examples/examples/SecurityAnalysisExample/doc/markdown/readme.md b/examples/org.osate.examples/examples/SecurityAnalysisExample/doc/markdown/readme.md
new file mode 100644
index 00000000000..2a625fe44ae
--- /dev/null
+++ b/examples/org.osate.examples/examples/SecurityAnalysisExample/doc/markdown/readme.md
@@ -0,0 +1,3 @@
+# Security and Confidentiality Analysis Example
+
+This example collection contains example systems and Test cases for individual rules used in the Confidentiality and Security Analysis.
\ No newline at end of file
diff --git a/examples/org.osate.examples/examples/SecurityAnalysisExample/pom.xml b/examples/org.osate.examples/examples/SecurityAnalysisExample/pom.xml
new file mode 100644
index 00000000000..0516ad89a83
--- /dev/null
+++ b/examples/org.osate.examples/examples/SecurityAnalysisExample/pom.xml
@@ -0,0 +1,60 @@
+
+
+
+ 4.0.0
+
+
+ org.osate
+ examples
+ 2.14.0-SNAPSHOT
+ ..
+
+
+ org.osate
+ SecurityAnalysisExample
+ pom
+
+
+
+
+ com.ruleoftech
+ markdown-page-generator-plugin
+ 2.1.0
+
+ ${project.basedir}/doc/markdown
+ ${project.basedir}/doc/html
+ images,css
+
+ BlockQuote|style="font-size:90%"
+
+ EXTANCHORLINKS,TOC
+
+
+
+
+
diff --git a/examples/org.osate.examples/plugin.xml b/examples/org.osate.examples/plugin.xml
index 688331f68df..8da8e458abe 100644
--- a/examples/org.osate.examples/plugin.xml
+++ b/examples/org.osate.examples/plugin.xml
@@ -81,6 +81,13 @@ censes only apply to the Third Party Software and not any other portion of this
category="Safety Examples"
name="Safety Tutorial">
+
+
+
diff --git a/examples/org.osate.examples/pom.xml b/examples/org.osate.examples/pom.xml
index 9239cdd4817..51df5b9b81d 100644
--- a/examples/org.osate.examples/pom.xml
+++ b/examples/org.osate.examples/pom.xml
@@ -35,7 +35,7 @@ censes only apply to the Third Party Software and not any other portion of this
org.osate
org.osate.examples
- 1.0.6-SNAPSHOT
+ 1.0.7-SNAPSHOT
eclipse-plugin
diff --git a/releng/version-management/release.digest b/releng/version-management/release.digest
index b5d517488e6..3817056e5c0 100644
Binary files a/releng/version-management/release.digest and b/releng/version-management/release.digest differ
diff --git a/releng/version-management/release.xml b/releng/version-management/release.xml
index 3eeb6e4381e..a84d4cb11b2 100644
--- a/releng/version-management/release.xml
+++ b/releng/version-management/release.xml
@@ -879,6 +879,8 @@
+
+
@@ -925,6 +927,7 @@
+