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 @@ +