Commit e64e650d authored by Paff's avatar Paff

analysis: identity link with encryption

parent 827ebc03
/**
* Generated on Mon Oct 06 13:57:43 CEST 2014
* Generated on Tue Oct 07 08:12:34 CEST 2014
*/
config {
Require-Model:
......
......@@ -136,8 +136,18 @@ public class ArchitectureGraphBuilder {
visitComponent(subComponent, componentType);
}
visitConnectors(componentType, componentParent);
}
protected void visitComponentForConnector(SubComponentEntry component, ComponentEntry componentParent) {
ComponentEntry componentType = component.getComponentType().getBestKnownVersion();
/* Recursively visit all subcomponents and add them as well as their ports
* to the graph before proceeding with connectors. */
for (SubComponentEntry subComponent : componentType.getSubComponents()) {
visitComponentForConnector(subComponent, componentType);
}
visitConnectors(componentType, componentParent);
}
/**
......@@ -187,12 +197,12 @@ public class ArchitectureGraphBuilder {
if (sourceComponent.isEmpty()) {
if(((SecComponentEntry) componentType).getPort(sourcePort).isPresent()) {
PortEntry port = ((SecComponentEntry) componentType).getPort(sourcePort).get();
PortEntry port = ((SecComponentEntry) componentType).getPort(sourcePort).get().getBestKnownVersion();
checkState(port != null, INCONSISTENT_MODEL_ERROR);
sourcePortVertex = Vertex.lookup(port, this.graph);
} else if(componentParent != null &&
((SecComponentEntry) componentParent).getPort(sourcePort).isPresent()) {
PortEntry port = ((SecComponentEntry) componentParent).getPort(sourcePort).get();
PortEntry port = ((SecComponentEntry) componentParent).getPort(sourcePort).get().getBestKnownVersion();
checkState(port != null, INCONSISTENT_MODEL_ERROR);
sourcePortVertex = Vertex.lookup(port, this.graph);
......@@ -205,19 +215,19 @@ public class ArchitectureGraphBuilder {
subComponent = componentType.getSubComponent(sourceComponent).get();
}
checkNotNull(subComponent);
PortEntry port = ((SecComponentEntry) subComponent.getComponentType()).getPort(sourcePort).get();
PortEntry port = ((SecComponentEntry) subComponent.getComponentType()).getPort(sourcePort).get().getBestKnownVersion();
checkState(port != null, INCONSISTENT_MODEL_ERROR);
sourcePortVertex = Vertex.lookup(port, this.graph);
}
if (targetComponent.isEmpty()) {
if(((SecComponentEntry) componentType).getPort(targetPort).isPresent()) {
PortEntry port = ((SecComponentEntry) componentType).getPort(targetPort).get();
PortEntry port = ((SecComponentEntry) componentType).getPort(targetPort).get().getBestKnownVersion();
checkState(port != null, INCONSISTENT_MODEL_ERROR);
targetPortVertex = Vertex.lookup(port, this.graph);
} else if(componentParent != null &&
((SecComponentEntry) componentParent).getPort(targetPort).isPresent()) {
PortEntry port = ((SecComponentEntry) componentParent).getPort(targetPort).get();
PortEntry port = ((SecComponentEntry) componentParent).getPort(targetPort).get().getBestKnownVersion();
checkState(port != null, INCONSISTENT_MODEL_ERROR);
sourcePortVertex = Vertex.lookup(port, this.graph);
......@@ -230,7 +240,7 @@ public class ArchitectureGraphBuilder {
subComponent = componentType.getSubComponent(targetComponent).get();
}
checkNotNull(subComponent);
PortEntry port = ((SecComponentEntry) subComponent.getComponentType()).getPort(targetPort).get();
PortEntry port = ((SecComponentEntry) subComponent.getComponentType()).getPort(targetPort).get().getBestKnownVersion();
checkState(port != null, INCONSISTENT_MODEL_ERROR);
targetPortVertex = Vertex.lookup(port, this.graph);
}
......@@ -242,6 +252,14 @@ public class ArchitectureGraphBuilder {
this.graph.addEdge(connectorVertex, targetPortVertex);
}
}
/**
* Adds all identity links of the given component type to the graph
*/
protected void visitIdentity() {
//TODO
}
/**
......@@ -251,7 +269,7 @@ public class ArchitectureGraphBuilder {
protected void visitIncomingPorts(ComponentEntry componentType,
Vertex<SubComponentEntry> componentVertex) {
for (PortEntry port : componentType.getIncomingPorts()) {
Vertex<PortEntry> portVertex = Vertex.of(port);
Vertex<PortEntry> portVertex = Vertex.of(port.getBestKnownVersion());
this.graph.addVertex(portVertex);
this.graph.addEdge(portVertex, componentVertex);
visitFilter(port, portVertex);
......@@ -265,7 +283,7 @@ public class ArchitectureGraphBuilder {
protected void visitOutgoingPorts(ComponentEntry componentType,
Vertex<SubComponentEntry> componentVertex) {
for (PortEntry port : componentType.getOutgoingPorts()) {
Vertex<PortEntry> portVertex = Vertex.of(port);
Vertex<PortEntry> portVertex = Vertex.of(port.getBestKnownVersion());
this.graph.addVertex(portVertex);
this.graph.addEdge(componentVertex, portVertex);
visitFilter(port, portVertex);
......@@ -282,6 +300,8 @@ public class ArchitectureGraphBuilder {
rootComponentEntry.setComponentType(this.rootComponent);
rootComponentEntry.setName("ROOT");
visitComponent(rootComponentEntry, null);
//connector must be integrated at the end because a port can be used in a connector before it is saved in the graph
visitComponentForConnector(rootComponentEntry, null);
}
}
/**
* Generated on Mon Oct 06 13:58:01 CEST 2014
* Generated on Tue Oct 07 08:12:56 CEST 2014
*/
config {
Require-Model:
......
......@@ -76,8 +76,13 @@ public enum MontiSecArcAnalysisErrorCodes implements IErrorCode {
DerivedRolesComponent,
/**
* Porpergates the needed filter
* Propergates the needed filter
*/
TaintPropergation,
/**
* Identity link is used with encryption
*/
IdentityWithEncryption,
}
package secarc.ets.analysis.checker;
import interfaces2.resolvers.AmbigousException;
import secarc._ast.ASTSecArcIdentity;
import secarc.ets.entries.IdentityEntry;
import secarc.ets.graph.ArchitectureGraph;
/**
* Analysis checker interface for checking identity
* related analysis
*
* <br>
* <br>
* Copyright (c) 2011 RWTH Aachen. All rights reserved
*
* @author (last commit) $Author$
* @version $Date$<br>
* $Revision$
*
*/
public interface ISecAnalysisIdentityChecker {
/**
*
* @param node
* @param entry
* @param graph
* @throws AmbigousException
*/
void check(ASTSecArcIdentity node, IdentityEntry entry, ArchitectureGraph graph) throws AmbigousException;
}
package secarc.ets.analysis.identity;
import java.util.List;
import org.jgrapht.traverse.DepthFirstIterator;
import org.jgrapht.traverse.GraphIterator;
import interfaces2.STEntry;
import interfaces2.namespaces.NameSpace;
import interfaces2.resolvers.AmbigousException;
import mc.IErrorCode;
import mc.umlp.arcd.ets.entries.ComponentEntry;
import mc.umlp.arcd.ets.entries.ConnectorEntry;
import mc.umlp.arcd.ets.entries.PortEntry;
import mc.umlp.arcd.ets.entries.SubComponentEntry;
import secarc._ast.ASTSecArcIdentity;
import secarc.error.MontiSecArcAnalysisErrorCodes;
import secarc.ets.analysis.checker.Analysis;
import secarc.ets.analysis.checker.ISecAnalysisIdentityChecker;
import secarc.ets.check.CoCoHelper;
import secarc.ets.check.MontiSecArcAnalysisConstants;
import secarc.ets.entries.IdentityEntry;
import secarc.ets.entries.SecComponentEntry;
import secarc.ets.entries.SecConnectorEntry;
import secarc.ets.graph.ArchitectureGraph;
import secarc.ets.graph.Edge;
import secarc.ets.graph.Vertex;
public class IdentityWithEncryption extends Analysis implements
ISecAnalysisIdentityChecker {
public IdentityWithEncryption() {
super(MontiSecArcAnalysisConstants.IDENTITY_WITH_ENCRYPTION);
}
@Override
public void check(ASTSecArcIdentity node, IdentityEntry entry, ArchitectureGraph graph)
throws AmbigousException {
ComponentEntry targetComponentEntry = null;
NameSpace ns = getNameSpaceFor(node);
//Searching for right namespace of target
while(ns != null) {
targetComponentEntry = CoCoHelper.getSecComponentEntry(entry.getTarget(), node, ns, this);
if(targetComponentEntry != null) {
break;
}
ns = ns.getParent();
}
SecComponentEntry sourceComponentEntry = CoCoHelper.getSecComponentEntry(entry.getSource(), node, getNameSpaceFor(node), this);
//Is check in a coco
if(targetComponentEntry == null || sourceComponentEntry == null) {
return;
}
List<PortEntry> incomingPorts = targetComponentEntry.getIncomingPorts();
Vertex<PortEntry> portVertex = null;
STEntry element = null;
//Look for paths with port as beginning
GraphIterator<Vertex<? extends STEntry>, Edge> iterator;
boolean encrypted = true;
boolean pathfound = false;
//Search for every port from target component
//at least one connection must be encrypted
for(PortEntry port : incomingPorts) {
portVertex = Vertex.of(port);
iterator = new DepthFirstIterator<Vertex<? extends STEntry>, Edge>(graph.getReversedRawGraph(), portVertex);
element = iterator.next().getArchitectureElement();
//Search for encrypted path
while(iterator.hasNext()) {
element = iterator.next().getArchitectureElement();
//Search for source component of the identity link
if(element instanceof SubComponentEntry &&
((SubComponentEntry) element).getComponentType().equals(sourceComponentEntry) &&
encrypted) {
pathfound = true;
//There is an encrypted path, break
break;
}
//Check if the connection is encrypted
if(element instanceof ConnectorEntry) {
if(((SecConnectorEntry) element).isUnencrypted()) {
encrypted = false;
}
}
//New path
if(element.equals(port)) {
encrypted = true;
}
}
//There is an encrypted path, break
if(pathfound) {
break;
}
}
if(!pathfound) {
addReport("There is an identity link between the component " + entry.getSource() + " and " + entry.getTarget() + ", but an encrypted connection is missing.", node.get_SourcePositionStart());
}
}
@Override
public IErrorCode getErrorCode() {
return MontiSecArcAnalysisErrorCodes.IdentityWithEncryption;
}
}
......@@ -56,4 +56,8 @@ public final class MontiSecArcAnalysisConstants {
public static final String DERIVED_ROLES_COMPONENT = "Derives all roles for components.";
public static final String ALL_IDENTITY = "Checks all analysis related to identity links.";
public static final String IDENTITY_WITH_ENCRYPTION = "Checks if the communication between two components is encrypted when an identity link is used.";
}
......@@ -14,6 +14,7 @@ import secarc.ets.analysis.connect.UnencryptedConnectorThroughLowTurstlevel;
import secarc.ets.analysis.filter.ListFilters;
import secarc.ets.analysis.filter.TaintPropergation;
import secarc.ets.analysis.filter.TaintTracking;
import secarc.ets.analysis.identity.IdentityWithEncryption;
import secarc.ets.analysis.port.ListCriticalPorts;
import secarc.ets.analysis.port.ListSystemIncomingPorts;
import secarc.ets.analysis.port.ListSystemOutgoingPorts;
......@@ -149,12 +150,19 @@ public final class MontiSecArcAnalysisCreator {
//Derives roles for "normal " components
roleAnalysis.addChild(new DerivedRolesComponent());
//Analysis for identity
CompositeContextCondition identityAnalysis = new CompositeContextCondition(MontiSecArcAnalysisConstants.ALL_IDENTITY);
//identity link needs an encrypted connection
identityAnalysis.addChild(new IdentityWithEncryption());
analysis.addChild(connectorAnalysis);
analysis.addChild(filterAnalysis);
analysis.addChild(portAnalysis);
analysis.addChild(configurationAnalysis);
analysis.addChild(roleAnalysis);
analysis.addChild(identityAnalysis);
}
return analysis;
......
......@@ -21,13 +21,16 @@ import mc.umlp.arcd.ets.entries.PortEntry;
import secarc._ast.ASTSecArcConfiguration;
import secarc._ast.ASTSecArcFilter;
import secarc._ast.ASTSecArcIdentity;
import secarc.ets.analysis.checker.ISecAnalysisComponentChecker;
import secarc.ets.analysis.checker.ISecAnalysisConfigurationChecker;
import secarc.ets.analysis.checker.ISecAnalysisConnectorChecker;
import secarc.ets.analysis.checker.ISecAnalysisFilterChecker;
import secarc.ets.analysis.checker.ISecAnalysisIdentityChecker;
import secarc.ets.analysis.checker.ISecAnalysisPortChecker;
import secarc.ets.entries.ConfigurationEntry;
import secarc.ets.entries.FilterEntry;
import secarc.ets.entries.IdentityEntry;
import secarc.ets.entries.SecComponentEntry;
import secarc.ets.entries.SecConnectorEntry;
import secarc.ets.entries.SecPortEntry;
......@@ -78,6 +81,11 @@ public class MontiSecArcAnalysisVisitor extends CheckWorkflowClient {
*/
private Set<ISecAnalysisComponentChecker> analysisComponentChecker;
/**
* Analysis for identity
*/
private Set<ISecAnalysisIdentityChecker> analysisIdentityChecker;
public MontiSecArcAnalysisVisitor() {
analysisFilterChecker = new HashSet<ISecAnalysisFilterChecker>();
......@@ -85,6 +93,7 @@ public class MontiSecArcAnalysisVisitor extends CheckWorkflowClient {
analysisPortChecker = new HashSet<ISecAnalysisPortChecker>();
analysisConnectorChecker = new HashSet<ISecAnalysisConnectorChecker>();
analysisComponentChecker = new HashSet<ISecAnalysisComponentChecker>();
analysisIdentityChecker = new HashSet<ISecAnalysisIdentityChecker>();
}
/**
......@@ -118,6 +127,9 @@ public class MontiSecArcAnalysisVisitor extends CheckWorkflowClient {
if(coco instanceof ISecAnalysisComponentChecker) {
analysisComponentChecker.add((ISecAnalysisComponentChecker) coco);
}
if(coco instanceof ISecAnalysisIdentityChecker) {
analysisIdentityChecker.add((ISecAnalysisIdentityChecker) coco);
}
}
}
......@@ -209,13 +221,12 @@ public class MontiSecArcAnalysisVisitor extends CheckWorkflowClient {
MCG.getLogger().info(e.getMessage());
}
}
}
/**
* Visits Components
*/
public void visit(ASTArcComponent node) {
public void visit(ASTArcComponent node) {
try {
SecComponentEntry entry = (SecComponentEntry) resolver.resolve(node.getName(), ComponentEntry.KIND, getNameSpaceFor(node));
for(ISecAnalysisComponentChecker cc : analysisComponentChecker) {
......@@ -227,4 +238,24 @@ public class MontiSecArcAnalysisVisitor extends CheckWorkflowClient {
}
}
/**
* Visits identity links
*/
public void visit(ASTSecArcIdentity node) {
for (ASTQualifiedName name : node.getTargets()) {
try {
IdentityEntry entry = (IdentityEntry) resolver.resolve(NameHelper.dotSeparatedStringFromList(name.getParts()), IdentityEntry.KIND,
getNameSpaceFor(node));
if (entry != null) {
for (ISecAnalysisIdentityChecker cc : analysisIdentityChecker) {
cc.check(node, entry, graph);
}
}
} catch (AmbigousException e) {
// not handled here
MCG.getLogger().info(e.getMessage());
}
}
}
}
......@@ -48,12 +48,10 @@ public class MontiSecArcAnalysisTest extends TestWithSymtabAnalysis<MontiSecArcA
errorCodes.add(MontiSecArcAnalysisErrorCodes.EncryptedPathWithUnencryptedPart);
errorCodes.add(MontiSecArcAnalysisErrorCodes.EncryptedPathEndInLowTrustlevel);
errorCodes.add(MontiSecArcAnalysisErrorCodes.UnencryptedConnectorThroughLowTrustlevel);
errorCodes.add(MontiSecArcAnalysisErrorCodes.DerivedRolesThirdParty);
errorCodes.add(MontiSecArcAnalysisErrorCodes.DerivedRolesComponent);
errorCodes.add(MontiSecArcAnalysisErrorCodes.ListIncomingtPorts);
errorCodes.add(MontiSecArcAnalysisErrorCodes.TaintPropergation);
assertEquals(25, handler.getWarnings().size());
assertEquals(17, handler.getWarnings().size());
for(ProblemReport error : handler.getErrors()) {
assertTrue(errorCodes.contains(error.getErrorcode()));
}
......@@ -74,11 +72,11 @@ public class MontiSecArcAnalysisTest extends TestWithSymtabAnalysis<MontiSecArcA
errorCodes.add(MontiSecArcAnalysisErrorCodes.ListFilters);
errorCodes.add(MontiSecArcAnalysisErrorCodes.ListIncomingtPorts);
errorCodes.add(MontiSecArcAnalysisErrorCodes.TaintTracking);
errorCodes.add(MontiSecArcAnalysisErrorCodes.EncryptedPathEndInLowTrustlevel);
errorCodes.add(MontiSecArcAnalysisErrorCodes.UnencryptedConnectorThroughLowTrustlevel);
errorCodes.add(MontiSecArcAnalysisErrorCodes.DerivedRolesComponent);
errorCodes.add(MontiSecArcAnalysisErrorCodes.TaintPropergation);
assertEquals(11, handler.getWarnings().size());
assertEquals(7, handler.getWarnings().size());
for(ProblemReport error : handler.getErrors()) {
assertTrue(errorCodes.contains(error.getErrorcode()));
}
......@@ -96,11 +94,9 @@ public class MontiSecArcAnalysisTest extends TestWithSymtabAnalysis<MontiSecArcA
List<MontiSecArcAnalysisErrorCodes> errorCodes = new ArrayList<MontiSecArcAnalysisErrorCodes>();
errorCodes.add(MontiSecArcAnalysisErrorCodes.ReviewedConfiguration);
errorCodes.add(MontiSecArcAnalysisErrorCodes.DerivedRolesThirdParty);
errorCodes.add(MontiSecArcAnalysisErrorCodes.DerivedRolesComponent);
errorCodes.add(MontiSecArcAnalysisErrorCodes.TaintPropergation);
assertEquals(10, handler.getWarnings().size());
assertEquals(6, handler.getWarnings().size());
for(ProblemReport error : handler.getErrors()) {
assertTrue(errorCodes.contains(error.getErrorcode()));
}
......@@ -119,8 +115,9 @@ public class MontiSecArcAnalysisTest extends TestWithSymtabAnalysis<MontiSecArcA
errorCodes.add(MontiSecArcAnalysisErrorCodes.DerivedRolesThirdParty);
errorCodes.add(MontiSecArcAnalysisErrorCodes.DerivedRolesComponent);
errorCodes.add(MontiSecArcAnalysisErrorCodes.TaintPropergation);
errorCodes.add(MontiSecArcAnalysisErrorCodes.IdentityWithEncryption);
assertEquals(6, handler.getWarnings().size());
assertEquals(7, handler.getWarnings().size());
for(ProblemReport error : handler.getErrors()) {
assertTrue(errorCodes.contains(error.getErrorcode()));
}
......@@ -139,10 +136,29 @@ public class MontiSecArcAnalysisTest extends TestWithSymtabAnalysis<MontiSecArcA
errorCodes.add(MontiSecArcAnalysisErrorCodes.ListIncomingtPorts);
errorCodes.add(MontiSecArcAnalysisErrorCodes.ListOutgoingPorts);
errorCodes.add(MontiSecArcAnalysisErrorCodes.ListAllCriticalPorts);
errorCodes.add(MontiSecArcAnalysisErrorCodes.TaintPropergation);
assertEquals(17, handler.getWarnings().size());
for(ProblemReport error : handler.getErrors()) {
assertTrue(errorCodes.contains(error.getErrorcode()));
}
}
/**
* Test for identity
*/
@Test
public void testIdentity() {
MontiSecArcAnalysisTestTool tool = createTestToolWithoutJava(new String[] { "src/test/resources/secarc/analysis/identity/" });
tool.init();
assertTrue(tool.run());
List<MontiSecArcAnalysisErrorCodes> errorCodes = new ArrayList<MontiSecArcAnalysisErrorCodes>();
errorCodes.add(MontiSecArcAnalysisErrorCodes.IdentityWithEncryption);
errorCodes.add(MontiSecArcAnalysisErrorCodes.DerivedRolesComponent);
errorCodes.add(MontiSecArcAnalysisErrorCodes.TaintPropergation);
assertEquals(23, handler.getWarnings().size());
assertEquals(8, handler.getWarnings().size());
for(ProblemReport error : handler.getErrors()) {
assertTrue(errorCodes.contains(error.getErrorcode()));
}
......
......@@ -2,7 +2,7 @@ package secarc.analysis.configuration;
component ConfigurationNotReviewed {
accesscontrol on;
accesscontrol off;
trustlevel +1;
......@@ -10,15 +10,12 @@ component ConfigurationNotReviewed {
trustlevel +1;
identity weak help -> targetHelp;
}
component TargetHelp targetHelp {
version "1.2";
configuration conf;
access user;
}
component SubEncryptedConnector subEncryptedConnector{
......
......@@ -2,15 +2,14 @@ package secarc.analysis.configuration;
component ConfigurationReviewed {
accesscontrol on;
accesscontrol off;
trustlevel +1;
component Help help {
trustlevel +1;
identity weak help -> targetHelp;
}
component TargetHelp targetHelp {
......@@ -20,9 +19,6 @@ component ConfigurationReviewed {
configuration conf_reviewed;
access user;
}
component SubEncryptedConnector subEncryptedConnector {
......
......@@ -2,7 +2,7 @@ package secarc.analysis.connector;
component EncryptedPathEndInLowTrustlevel {
accesscontrol on;
accesscontrol off;
trustlevel +1;
......@@ -12,8 +12,6 @@ component EncryptedPathEndInLowTrustlevel {
component Help help {
trustlevel +1;
identity weak help -> targetHelp;
}
component TargetHelp targetHelp {
......@@ -22,8 +20,6 @@ component EncryptedPathEndInLowTrustlevel {
port in String inputTarget;
configuration conf_reviewed;
access user;
}
......
......@@ -2,7 +2,7 @@ package secarc.analysis.connector;
component EncryptedPathWithUnencryptedPart {
accesscontrol on;
accesscontrol off;
trustlevel +1;
......@@ -12,8 +12,6 @@ component EncryptedPathWithUnencryptedPart {
component Help help {
trustlevel +1;
identity weak help -> targetHelp;
}