adding command-line and certificate functionalities 66/30166/29
authorMohamed El-Serngawy <melserngawy@inocybe.com>
Tue, 24 Nov 2015 23:16:22 +0000 (18:16 -0500)
committerRyan Goulding <ryandgoulding@gmail.com>
Thu, 11 Feb 2016 15:14:12 +0000 (15:14 +0000)
Change-Id: I0d5ffe7d004146fdcc92b3cf06cf45762b99cbd2
Signed-off-by: Mohamed El-Serngawy <melserngawy@inocybe.com>
33 files changed:
aaa-cert/pom.xml [new file with mode: 0755]
aaa-cert/src/main/java/org/opendaylight/aaa/cert/api/IAaaCertProvider.java [new file with mode: 0644]
aaa-cert/src/main/java/org/opendaylight/aaa/cert/impl/AaaCertProvider.java [new file with mode: 0644]
aaa-cert/src/main/java/org/opendaylight/aaa/cert/impl/ConnectionConfigurationImpl.java [new file with mode: 0644]
aaa-cert/src/main/java/org/opendaylight/aaa/cert/impl/KeyStoreUtilis.java [new file with mode: 0644]
aaa-cert/src/main/java/org/opendaylight/aaa/cert/impl/ODLKeyTool.java [new file with mode: 0644]
aaa-cert/src/main/java/org/opendaylight/aaa/cert/impl/TlsConfigurationImp.java [new file with mode: 0644]
aaa-cert/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/yang/aaa/cert/rev151126/AaaCertProviderModule.java [new file with mode: 0644]
aaa-cert/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/yang/aaa/cert/rev151126/AaaCertProviderModuleFactory.java [new file with mode: 0644]
aaa-cert/src/main/resources/OSGI-INF/blueprint/blueprint.xml [new file with mode: 0644]
aaa-cert/src/main/resources/initial/08-aaa-cert-config.xml [new file with mode: 0644]
aaa-cert/src/main/test/org/opendaylight/aaa/cert/test/AaaCertProviderTest.java [new file with mode: 0644]
aaa-cert/src/main/test/org/opendaylight/aaa/cert/test/KeyStoreUtilisTest.java [new file with mode: 0644]
aaa-cert/src/main/test/org/opendaylight/aaa/cert/test/ODLKeyToolTest.java [new file with mode: 0644]
aaa-cert/src/main/yang/aaa-cert-rpc.yang [new file with mode: 0644]
aaa-cert/src/main/yang/aaa-cert.yang [new file with mode: 0644]
aaa-cli/pom.xml [new file with mode: 0755]
aaa-cli/src/main/java/org/opendaylight/aaa/cli/AddCertODLKeyStore.java [new file with mode: 0644]
aaa-cli/src/main/java/org/opendaylight/aaa/cli/AddCertTrustStore.java [new file with mode: 0644]
aaa-cli/src/main/java/org/opendaylight/aaa/cli/CreateODLKeyStore.java [new file with mode: 0644]
aaa-cli/src/main/java/org/opendaylight/aaa/cli/CreateTrustKeyStore.java [new file with mode: 0644]
aaa-cli/src/main/java/org/opendaylight/aaa/cli/GenerateCertReq.java [new file with mode: 0644]
aaa-cli/src/main/java/org/opendaylight/aaa/cli/GetODLSelfSignCert.java [new file with mode: 0644]
aaa-cli/src/main/java/org/opendaylight/aaa/cli/GetTrustStoreCert.java [new file with mode: 0644]
aaa-cli/src/main/resources/OSGI-INF/blueprint/commands.xml [new file with mode: 0644]
artifacts/pom.xml
distribution-karaf/pom.xml
features/aaa-cert/pom.xml [new file with mode: 0644]
features/aaa-cert/src/main/features/features.xml [new file with mode: 0644]
features/aaa-cli/pom.xml [new file with mode: 0644]
features/aaa-cli/src/main/features/features.xml [new file with mode: 0644]
features/pom.xml
pom.xml

diff --git a/aaa-cert/pom.xml b/aaa-cert/pom.xml
new file mode 100755 (executable)
index 0000000..34f8f01
--- /dev/null
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2015 Inocybe Technology. All rights reserved.
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+  <parent>
+    <groupId>org.opendaylight.aaa</groupId>
+    <artifactId>aaa-parent</artifactId>
+    <version>0.4.0-SNAPSHOT</version>
+    <relativePath>../parent/</relativePath>
+  </parent>
+
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>aaa-cert</artifactId>
+  <packaging>bundle</packaging>
+
+  <properties>
+    <openflowplugin.version>0.3.0-SNAPSHOT</openflowplugin.version>
+    <openflow.protocol.spi.version>0.8.0-SNAPSHOT</openflow.protocol.spi.version>
+    <powermock.version>1.5.2</powermock.version>
+  </properties>
+
+
+  <dependencies>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-binding-config</artifactId>
+    </dependency>
+
+    <!-- Bouncy Castle dependency -->
+    <dependency>
+        <groupId>org.bouncycastle</groupId>
+        <artifactId>bcprov-jdk15on</artifactId>
+    </dependency>
+    <dependency>
+        <groupId>commons-codec</groupId>
+        <artifactId>commons-codec</artifactId>
+    </dependency>
+
+    <!-- openflow dependency -->
+    <dependency>
+      <groupId>org.opendaylight.openflowplugin</groupId>
+      <artifactId>features-openflowplugin</artifactId>
+      <classifier>features</classifier>
+      <version>${openflowplugin.version}</version>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.openflowjava</groupId>
+      <artifactId>openflow-protocol-spi</artifactId>
+      <version>${openflow.protocol.spi.version}</version>
+    </dependency>
+
+    <!-- Testing Dependencies -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-core</artifactId>
+      <version>${powermock.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-module-junit4</artifactId>
+      <version>${powermock.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-api-mockito</artifactId>
+      <version>${powermock.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-api-support</artifactId>
+      <version>${powermock.version}</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-artifacts</id>
+            <goals>
+              <goal>attach-artifact</goal>
+            </goals>
+            <phase>package</phase>
+            <configuration>
+              <artifacts>
+                <artifact>
+                  <file>${project.build.directory}/classes/initial/08-aaa-cert-config.xml</file>
+                  <type>xml</type>
+                  <classifier>config</classifier>
+                </artifact>
+              </artifacts>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.opendaylight.yangtools</groupId>
+        <artifactId>yang-maven-plugin</artifactId>
+        <version>${yangtools.version}</version>
+        <executions>
+          <execution>
+            <id>config</id>
+            <goals>
+              <goal>generate-sources</goal>
+            </goals>
+            <configuration>
+              <codeGenerators>
+                <generator>
+                <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
+                <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
+                <additionalConfiguration>
+                  <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
+                  </additionalConfiguration>
+                </generator>
+                <generator>
+                  <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
+                  <outputBaseDir>${salGeneratorPath}</outputBaseDir>
+                </generator>
+              </codeGenerators>
+              <inspectDependencies>true</inspectDependencies>
+            </configuration>
+          </execution>
+        </executions>
+        <dependencies>
+          <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>yang-jmx-generator-plugin</artifactId>
+            <version>${config.version}</version>
+          </dependency>
+          <dependency>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>maven-sal-api-gen-plugin</artifactId>
+            <version>${mdsal.model.version}</version>
+          </dependency>
+        </dependencies>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/aaa-cert/src/main/java/org/opendaylight/aaa/cert/api/IAaaCertProvider.java b/aaa-cert/src/main/java/org/opendaylight/aaa/cert/api/IAaaCertProvider.java
new file mode 100644 (file)
index 0000000..36372c0
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2015 Inocybe Technologies. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.aaa.cert.api;
+
+import java.security.KeyStore;
+
+/**
+ *
+ * @author mserngawy
+ *
+ * IAaaCertProvider define the basic operation for certificates management
+ */
+public interface IAaaCertProvider extends java.lang.AutoCloseable {
+
+    boolean addCertificateODLKeyStore(String storePasswd, String alias, String certificate);
+
+    boolean addCertificateTrustStore(String storePasswd, String alias, String certificate);
+
+    String createODLKeyStore(String keyStore, String storePasswd, String alias, String dName, int validity);
+
+    String createTrustKeyStore(String keyStore, String storePasswd, String alias);
+
+    String genODLKeyStorCertificateReq(String storePasswd, String alias);
+
+    String getCertificateTrustStore(String storePasswd, String aliase);
+
+    String getODLKeyStorCertificate(String storePasswd, String alias);
+
+    KeyStore getODLKeyStore();
+
+    KeyStore getTrustKeyStore();
+}
diff --git a/aaa-cert/src/main/java/org/opendaylight/aaa/cert/impl/AaaCertProvider.java b/aaa-cert/src/main/java/org/opendaylight/aaa/cert/impl/AaaCertProvider.java
new file mode 100644 (file)
index 0000000..e945d06
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2015 Inocybe Technologies. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.aaa.cert.impl;
+
+import com.google.common.util.concurrent.SettableFuture;
+import java.security.KeyStore;
+import java.util.concurrent.Future;
+import org.opendaylight.aaa.cert.api.IAaaCertProvider;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rev151126.CtlKeystore;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rev151126.TrustKeystore;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rpc.rev151215.AaaCertRpcService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rpc.rev151215.GetNodeCertifcateInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rpc.rev151215.GetNodeCertifcateOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rpc.rev151215.GetNodeCertifcateOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rpc.rev151215.GetODLCertificateOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rpc.rev151215.GetODLCertificateOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rpc.rev151215.GetODLCertificateReqOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rpc.rev151215.GetODLCertificateReqOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rpc.rev151215.SetNodeCertifcateInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rpc.rev151215.SetODLCertifcateInput;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author mserngawy
+ * AaaCertProvider use to manage the certificates manipulation operations add, revoke and update
+ */
+public class AaaCertProvider implements AutoCloseable, IAaaCertProvider, BindingAwareProvider, AaaCertRpcService {
+
+    private final static Logger LOG = LoggerFactory.getLogger(AaaCertProvider.class);
+    private ServiceRegistration<AaaCertRpcService> aaaCertRpcServiceRegisteration;
+    private ServiceRegistration<IAaaCertProvider> aaaCertServiceRegisteration;
+    private final CtlKeystore ctlKeyStore;
+    private final ODLKeyTool odlKeyTool;
+    private final TrustKeystore trustKeyStore;
+
+    public AaaCertProvider(final CtlKeystore ctlKeyStore, final TrustKeystore trustKeyStore) {
+        LOG.info("aaa Certificate Service Initalized");
+        odlKeyTool = new ODLKeyTool();
+        this.ctlKeyStore = ctlKeyStore;
+        this.trustKeyStore = trustKeyStore;
+    }
+
+    @Override
+    public boolean addCertificateODLKeyStore(final String storePasswd, final String alias, final String certificate) {
+        return odlKeyTool.addCertificate(ctlKeyStore.getName(), storePasswd, certificate, alias);
+    }
+
+    @Override
+    public boolean addCertificateTrustStore(final String storePasswd, final String alias, final String certificate) {
+        return odlKeyTool.addCertificate(trustKeyStore.getName(), storePasswd, certificate, alias);
+    }
+
+    @Override
+    public void close() throws Exception {
+        LOG.info("aaa Certificate Service Closed");
+        aaaCertServiceRegisteration.unregister();
+        aaaCertRpcServiceRegisteration.unregister();
+    }
+
+    public void createODLKeyStore() {
+        createODLKeyStore(ctlKeyStore.getName(),ctlKeyStore.getStorePassword(), ctlKeyStore.getAlias(),
+                  ctlKeyStore.getDname(), ctlKeyStore.getValidity());
+    }
+
+    @Override
+    public String createODLKeyStore(final String keyStore, final String storePasswd, final String alias,
+            final String dName, final int validity) {
+        ctlKeyStore.setAlias(alias);
+        ctlKeyStore.setDname(dName);
+        ctlKeyStore.setName(keyStore);
+        ctlKeyStore.setStorePassword(storePasswd);
+        ctlKeyStore.setValidity(validity);
+        if(odlKeyTool.createKeyStoreWithSelfSignCert(keyStore, storePasswd, dName, alias, validity)) {
+            return keyStore + " Keystore created.";
+        } else {
+            return "Failed to create keystore " + keyStore;
+        }
+    }
+
+    public void createTrustKeyStore() {
+        odlKeyTool.createKeyStoreImportCert(trustKeyStore.getName(), trustKeyStore.getStorePassword(),
+                trustKeyStore.getCertFile(), trustKeyStore.getAlias());
+    }
+
+    @Override
+    public String createTrustKeyStore(final String keyStore, final String storePasswd, final String alias) {
+        trustKeyStore.setAlias(alias);
+        trustKeyStore.setName(keyStore);
+        trustKeyStore.setStorePassword(storePasswd);
+        if(odlKeyTool.createKeyStoreImportCert(keyStore, storePasswd, trustKeyStore.getCertFile(), alias)) {
+            return keyStore + " Keystore created.";
+        } else {
+            return "Failed to create keystore " + keyStore;
+        }
+    }
+
+    @Override
+    public String genODLKeyStorCertificateReq(final String storePasswd, final String alias) {
+        return odlKeyTool.generateCertificateReq(ctlKeyStore.getName(), storePasswd,
+                     alias,KeyStoreUtilis.defaultSignAlg, true);
+    }
+
+    @Override
+    public String getCertificateTrustStore(final String storePasswd, final String aliase) {
+        return odlKeyTool.getCertificate(trustKeyStore.getName(), storePasswd, aliase, true);
+    }
+
+    @Override
+    public Future<RpcResult<GetNodeCertifcateOutput>> getNodeCertifcate(final GetNodeCertifcateInput input) {
+        final SettableFuture<RpcResult<GetNodeCertifcateOutput>> futureResult = SettableFuture.create();
+        final String cert = odlKeyTool.getCertificate(trustKeyStore.getName(), trustKeyStore.getStorePassword(),
+                                 input.getNodeAlias(), true);
+        if (cert != null) {
+            final GetNodeCertifcateOutput nodeCertOutput = new GetNodeCertifcateOutputBuilder()
+                                                        .setNodeCert(cert)
+                                                        .build();
+            futureResult.set(RpcResultBuilder.<GetNodeCertifcateOutput> success(nodeCertOutput).build());
+        } else {
+            futureResult.set(RpcResultBuilder.<GetNodeCertifcateOutput> failed().build());
+        }
+        return futureResult;
+    }
+
+    @Override
+    public Future<RpcResult<GetODLCertificateOutput>> getODLCertificate() {
+        final SettableFuture<RpcResult<GetODLCertificateOutput>> futureResult = SettableFuture.create();
+        final String cert = odlKeyTool.getCertificate(ctlKeyStore.getName(), ctlKeyStore.getStorePassword(),
+                                 ctlKeyStore.getAlias(), true);
+        if (cert != null) {
+            final GetODLCertificateOutput odlCertOutput = new GetODLCertificateOutputBuilder()
+                                                        .setOdlCert(cert)
+                                                        .build();
+            futureResult.set(RpcResultBuilder.<GetODLCertificateOutput> success(odlCertOutput).build());
+        } else {
+            futureResult.set(RpcResultBuilder.<GetODLCertificateOutput> failed().build());
+        }
+        return futureResult;
+    }
+
+    @Override
+    public Future<RpcResult<GetODLCertificateReqOutput>> getODLCertificateReq() {
+        final SettableFuture<RpcResult<GetODLCertificateReqOutput>> futureResult = SettableFuture.create();
+        final String certReq = odlKeyTool.generateCertificateReq(ctlKeyStore.getName(), ctlKeyStore.getStorePassword(),
+                                 ctlKeyStore.getAlias(), KeyStoreUtilis.defaultSignAlg, true);
+        if (certReq != null) {
+            final GetODLCertificateReqOutput odlCertReqOutput = new GetODLCertificateReqOutputBuilder()
+                                                        .setOdlCertReq(certReq)
+                                                        .build();
+            futureResult.set(RpcResultBuilder.<GetODLCertificateReqOutput> success(odlCertReqOutput).build());
+        } else {
+            futureResult.set(RpcResultBuilder.<GetODLCertificateReqOutput> failed().build());
+        }
+        return futureResult;
+    }
+
+    @Override
+    public String getODLKeyStorCertificate(final String storePasswd, final String alias) {
+        return odlKeyTool.getCertificate(ctlKeyStore.getName(), storePasswd, alias, true);
+    }
+
+    @Override
+    public KeyStore getODLKeyStore() {
+        return odlKeyTool.getKeyStore(ctlKeyStore.getName(), ctlKeyStore.getStorePassword());
+    }
+
+    @Override
+    public KeyStore getTrustKeyStore() {
+        return odlKeyTool.getKeyStore(trustKeyStore.getName(), trustKeyStore.getStorePassword());
+    }
+
+    @Override
+    public void onSessionInitiated(final ProviderContext session) {
+        LOG.info("aaa Certificate Service Session Initiated");
+        final BundleContext context = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
+        aaaCertServiceRegisteration = context.registerService(IAaaCertProvider.class, this, null);
+        aaaCertRpcServiceRegisteration = context.registerService(AaaCertRpcService.class, this, null);
+    }
+
+    @Override
+    public Future<RpcResult<Void>> setNodeCertifcate(final SetNodeCertifcateInput input) {
+        LOG.info("{} Certificate will be added to the trust keystore.", input.getNodeAlias());
+        final SettableFuture<RpcResult<Void>> futureResult = SettableFuture.create();
+        if (odlKeyTool.addCertificate(trustKeyStore.getName(), trustKeyStore.getStorePassword(),
+                input.getNodeCert(), input.getNodeAlias())) {
+            futureResult.set(RpcResultBuilder.<Void> success().build());
+        } else {
+            futureResult.set(RpcResultBuilder.<Void> failed().build());
+        }
+        return futureResult;
+    }
+
+    @Override
+    public Future<RpcResult<Void>> setODLCertifcate(final SetODLCertifcateInput input) {
+        LOG.info("Certificate will be add to ODL keystore.");
+        final SettableFuture<RpcResult<Void>> futureResult = SettableFuture.create();
+        //adding ca to the alias of signed certificate by Certificate Authority.
+        //can not have 2 certifciate under the same alias.
+        ctlKeyStore.setAlias("ca" + ctlKeyStore.getAlias());
+        if (odlKeyTool.addCertificate(ctlKeyStore.getName(), ctlKeyStore.getStorePassword(),
+                input.getOdlCert(), ctlKeyStore.getAlias())) {
+            futureResult.set(RpcResultBuilder.<Void> success().build());
+        } else {
+            futureResult.set(RpcResultBuilder.<Void> failed().build());
+        }
+        return futureResult;
+    }
+}
diff --git a/aaa-cert/src/main/java/org/opendaylight/aaa/cert/impl/ConnectionConfigurationImpl.java b/aaa-cert/src/main/java/org/opendaylight/aaa/cert/impl/ConnectionConfigurationImpl.java
new file mode 100644 (file)
index 0000000..f7716e6
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016 Inocybe Technologies. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.aaa.cert.impl;
+
+import java.net.InetAddress;
+
+import org.opendaylight.openflowjava.protocol.api.connection.ConnectionConfiguration;
+import org.opendaylight.openflowjava.protocol.api.connection.ThreadConfiguration;
+import org.opendaylight.openflowjava.protocol.api.connection.TlsConfiguration;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.TransportProtocol;
+
+public class ConnectionConfigurationImpl implements ConnectionConfiguration {
+
+    private final ConnectionConfiguration connConfig;
+    private final TlsConfiguration tlsConfig;
+
+    public ConnectionConfigurationImpl(final ConnectionConfiguration baseConnConfig, final TlsConfiguration tlsConfig) {
+        connConfig = baseConnConfig;
+        this.tlsConfig = tlsConfig;
+    }
+
+    @Override
+    public InetAddress getAddress() {
+        return connConfig.getAddress();
+    }
+
+    @Override
+    public int getPort() {
+        return connConfig.getPort();
+    }
+
+    @Override
+    public Object getSslContext() {
+        return connConfig.getSslContext();
+    }
+
+    @Override
+    public long getSwitchIdleTimeout() {
+        return connConfig.getSwitchIdleTimeout();
+    }
+
+    @Override
+    public ThreadConfiguration getThreadConfiguration() {
+        return connConfig.getThreadConfiguration();
+    }
+
+    @Override
+    public TlsConfiguration getTlsConfiguration() {
+        return tlsConfig;
+    }
+
+    @Override
+    public Object getTransferProtocol() {
+        return TransportProtocol.TLS;
+    }
+
+    @Override
+    public boolean useBarrier() {
+        return connConfig.useBarrier();
+    }
+
+}
diff --git a/aaa-cert/src/main/java/org/opendaylight/aaa/cert/impl/KeyStoreUtilis.java b/aaa-cert/src/main/java/org/opendaylight/aaa/cert/impl/KeyStoreUtilis.java
new file mode 100644 (file)
index 0000000..46ba778
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2015 Inocybe Technologies. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.aaa.cert.impl;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+/**
+ *
+ * @author mserngawy
+ * Utility class for aaa-cert bundle
+ */
+public class KeyStoreUtilis {
+
+    public static final String BEGIN_CERTIFICATE = "-----BEGIN CERTIFICATE-----";
+
+    public static final String BEGIN_CERTIFICATE_REQUEST = "-----BEGIN CERTIFICATE REQUEST-----";
+    public static String defaultKeyAlg = "RSA"; //DES
+    public static int defaultKeySize = 2048; //1024
+    public static String defaultSignAlg = "SHA1WithRSAEncryption"; //MD5WithRSAEncryption
+
+    public static int defaultValidity = 365;
+    public static final String END_CERTIFICATE = "-----END CERTIFICATE-----";
+    public static final String END_CERTIFICATE_REQUEST = "-----END CERTIFICATE REQUEST-----";
+    public static String keyStorePath = "configuration" + File.separator + "ssl" + File.separator;
+
+    public static boolean checkKeyStoreFile(final String fileName) {
+        final File file = new File(keyStorePath + fileName);
+        return file.exists();
+    }
+
+    public static String createDir(final String dir) {
+        final File file = new File(dir);
+        if(!file.exists()) {
+            file.mkdirs();
+        }
+        return file.getAbsolutePath();
+    }
+
+    public static String readFile(final String certFile) {
+        if (certFile == null || certFile.isEmpty()) {
+            return null;
+        }
+
+        try {
+            final FileInputStream fInputStream = new FileInputStream(keyStorePath + certFile);
+            final byte[] certBytes = new byte[fInputStream.available()];
+            fInputStream.read(certBytes);
+            fInputStream.close();
+            final String cert = new String(certBytes, StandardCharsets.UTF_8);
+            return cert;
+        } catch (final IOException e) {
+            return null;
+        }
+    }
+
+    public static boolean saveCert(final String fileName, final String cert) {
+        if (fileName == null || fileName.isEmpty()) {
+            return false;
+        }
+
+        BufferedWriter out;
+        try {
+            out = new BufferedWriter(new FileWriter(keyStorePath + fileName));
+            out.write(cert);
+            out.close();
+            return true;
+        } catch (final IOException e) {
+            return false;
+        }
+    }
+}
\ No newline at end of file
diff --git a/aaa-cert/src/main/java/org/opendaylight/aaa/cert/impl/ODLKeyTool.java b/aaa-cert/src/main/java/org/opendaylight/aaa/cert/impl/ODLKeyTool.java
new file mode 100644 (file)
index 0000000..e6e249f
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2015 Inocybe Technologies. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.aaa.cert.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.SignatureException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+
+import javax.xml.bind.DatatypeConverter;
+
+import org.apache.commons.codec.binary.Base64;
+import org.bouncycastle.asn1.x509.X509Name;
+import org.bouncycastle.jce.PKCS10CertificationRequest;
+import org.bouncycastle.jce.X509Principal;
+import org.bouncycastle.x509.X509V3CertificateGenerator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author mserngawy
+ *
+ * ODLKeyTool has the basic operation to manage the Java keyStores such as generate, add and delete certificates
+ */
+public class ODLKeyTool {
+
+    private final static Logger LOG = LoggerFactory.getLogger(ODLKeyTool.class);
+    // Day time in millisecond
+    private final long dayTime = 1000L * 60 * 60 * 24;
+    private String workingDir = KeyStoreUtilis.keyStorePath;
+
+    protected ODLKeyTool() {
+        KeyStoreUtilis.createDir(workingDir);
+    }
+
+    public ODLKeyTool(final String workingDirectory) {
+        workingDir = workingDirectory;
+        KeyStoreUtilis.createDir(workingDir);
+    }
+
+    public boolean addCertificate(final String keyStoreName, final String keyStorePwd, final String certificate, final String alias) {
+        try {
+            final X509Certificate newCert = getCertificate(certificate);
+            final KeyStore keyStore = KeyStore.getInstance("JKS");
+            final FileInputStream fInputStream = new FileInputStream(workingDir + keyStoreName);
+            keyStore.load(fInputStream, keyStorePwd.toCharArray());
+            if(keyStore.isCertificateEntry(alias)) {
+                keyStore.deleteEntry(alias);
+            }
+            keyStore.setCertificateEntry(alias, newCert);
+            keyStore.store( new FileOutputStream(workingDir + keyStoreName), keyStorePwd.toCharArray());
+            LOG.info("Certificate {}  Added to keyStore {}", alias, keyStoreName);
+            return true;
+        } catch (CertificateException | KeyStoreException | NoSuchAlgorithmException | IOException e) {
+            LOG.error("failed to add certificate {}", e.getMessage());
+            return false;
+        }
+    }
+
+    public boolean createKeyStoreImportCert(final String keyStoreName, final String keyStorePwd, final String certFile, final String alias) {
+        KeyStore trustKeyStore;
+        try {
+            trustKeyStore = KeyStore.getInstance("JKS");
+            trustKeyStore.load(null, keyStorePwd.toCharArray());
+            if(KeyStoreUtilis.checkKeyStoreFile(certFile)) {
+                final String certificate = KeyStoreUtilis.readFile(certFile);
+                final X509Certificate newCert = getCertificate(certificate);
+                trustKeyStore.setCertificateEntry(alias, newCert);
+            }
+            trustKeyStore.store( new FileOutputStream(workingDir + keyStoreName), keyStorePwd.toCharArray());
+            LOG.info("{} is created", keyStoreName);
+            return true;
+        } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) {
+            LOG.error("Failed to create keystore {}", keyStoreName);
+            return false;
+        }
+    }
+
+    public boolean createKeyStoreWithSelfSignCert(final String keyStoreName, final String keyStorePwd, final String dName, final String keyAlias, final int validity) {
+        try {
+            final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KeyStoreUtilis.defaultKeyAlg);
+            keyPairGenerator.initialize(KeyStoreUtilis.defaultKeySize);
+            final KeyPair keyPair = keyPairGenerator.generateKeyPair();
+            final X509V3CertificateGenerator x509V3CertGen = new X509V3CertificateGenerator();
+            x509V3CertGen.setSerialNumber(getSecureRandomeInt());
+            x509V3CertGen.setIssuerDN(new X509Principal(dName));
+            x509V3CertGen.setNotBefore(new Date(System.currentTimeMillis()));
+            x509V3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (dayTime * validity)));
+            x509V3CertGen.setSubjectDN(new X509Principal(dName));
+            x509V3CertGen.setPublicKey(keyPair.getPublic());
+            x509V3CertGen.setSignatureAlgorithm(KeyStoreUtilis.defaultSignAlg);
+            final X509Certificate x509Cert = x509V3CertGen.generateX509Certificate(keyPair.getPrivate());
+            final KeyStore ctlKeyStore = KeyStore.getInstance("JKS");
+            ctlKeyStore.load(null, keyStorePwd.toCharArray());
+            ctlKeyStore.setKeyEntry(keyAlias, keyPair.getPrivate(), keyStorePwd.toCharArray(),
+                       new java.security.cert.Certificate[]{x509Cert});
+            final FileOutputStream fOutputStream = new FileOutputStream(workingDir + keyStoreName);
+            ctlKeyStore.store( fOutputStream, keyStorePwd.toCharArray());
+            LOG.info("{} is created", keyStoreName);
+            return true;
+        }
+        catch (NoSuchAlgorithmException | InvalidKeyException | SecurityException | SignatureException | KeyStoreException | CertificateException | IOException e) {
+            LOG.error("Fatal error creating key cert: {}", e.getMessage());
+            return false;
+        }
+    }
+
+    public String generateCertificateReq(final String keyStoreName, final String keyStorePwd, final String keyAlias, final String signAlg,
+                  final boolean withTag) {
+        try {
+            final KeyStore ctlKeyStore = KeyStore.getInstance("JKS");
+            final FileInputStream fInputStream = new FileInputStream(workingDir + keyStoreName);
+            ctlKeyStore.load(fInputStream, keyStorePwd.toCharArray());
+            if (ctlKeyStore.containsAlias(keyAlias)) {
+                final X509Certificate odlCert = (X509Certificate)ctlKeyStore.getCertificate(keyAlias);
+                final PublicKey pubKey = odlCert.getPublicKey();
+                final PrivateKey privKey = (PrivateKey)ctlKeyStore.getKey(keyAlias, keyStorePwd.toCharArray());
+                final String subject = odlCert.getSubjectDN().getName();
+                final X509Name xname = new X509Name(subject);
+                final String signatureAlgorithm = signAlg;
+                final PKCS10CertificationRequest csr =
+                        new PKCS10CertificationRequest(signatureAlgorithm, xname, pubKey, null, privKey);
+                final String certReq = DatatypeConverter.printBase64Binary(csr.getEncoded());
+                if (withTag) {
+                    final StringBuilder sb = new StringBuilder();
+                    sb.append(KeyStoreUtilis.BEGIN_CERTIFICATE_REQUEST);
+                    sb.append("\n");
+                    sb.append(certReq);
+                    sb.append("\n");
+                    sb.append(KeyStoreUtilis.END_CERTIFICATE_REQUEST);
+                    return sb.toString();
+                }
+                return certReq;
+            }
+            LOG.info("{} KeyStore does not contain alias {}", keyStoreName, keyAlias);
+            return null;
+        } catch (NoSuchAlgorithmException | CertificateException | IOException | KeyStoreException |
+                 UnrecoverableKeyException | InvalidKeyException | NoSuchProviderException | SignatureException e) {
+            LOG.error("Failed to generate certificate request {}", e.getMessage());
+            return null;
+        }
+    }
+
+    private X509Certificate getCertificate(String certificate) {
+        if (certificate.isEmpty()) {
+            return null;
+        }
+
+        if (certificate.contains(KeyStoreUtilis.BEGIN_CERTIFICATE)) {
+            final int fIdx = certificate.indexOf(KeyStoreUtilis.BEGIN_CERTIFICATE) + KeyStoreUtilis.BEGIN_CERTIFICATE.length();
+            final int sIdx = certificate.indexOf(KeyStoreUtilis.END_CERTIFICATE);
+            certificate = certificate.substring(fIdx, sIdx);
+        }
+        final byte[] byteCert = Base64.decodeBase64(certificate);
+        final InputStream inputStreamCert = new ByteArrayInputStream(byteCert);
+        CertificateFactory certFactory;
+        try {
+            certFactory = CertificateFactory.getInstance("X.509");
+            final X509Certificate newCert = (X509Certificate) certFactory.generateCertificate(inputStreamCert);
+            newCert.checkValidity();
+            return newCert;
+        } catch (final CertificateException e) {
+            LOG.error("Failed to get certificate {}", e.getMessage());
+            return null;
+        }
+    }
+
+    public String getCertificate(final String keyStoreName, final String keyStorePwd, final String certAlias, final boolean withTag) {
+        try {
+            final KeyStore ctlKeyStore = KeyStore.getInstance("JKS");
+            final FileInputStream fInputStream = new FileInputStream(workingDir + keyStoreName);
+            ctlKeyStore.load(fInputStream, keyStorePwd.toCharArray());
+            if (ctlKeyStore.containsAlias(certAlias)) {
+                final X509Certificate odlCert = (X509Certificate)ctlKeyStore.getCertificate(certAlias);
+                final String cert = DatatypeConverter.printBase64Binary(odlCert.getEncoded());
+                if (withTag) {
+                    final StringBuilder sb = new StringBuilder();
+                    sb.append(KeyStoreUtilis.BEGIN_CERTIFICATE);
+                    sb.append("\n");
+                    sb.append(cert);
+                    sb.append("\n");
+                    sb.append(KeyStoreUtilis.END_CERTIFICATE);
+                    return sb.toString();
+                }
+                return cert;
+            }
+            LOG.info("{} KeyStore does not contain alias {}", keyStoreName, certAlias);
+            return null;
+        } catch (NoSuchAlgorithmException | CertificateException | IOException | KeyStoreException e) {
+            LOG.error("Failed to get Certificate {}", e.getMessage());
+            return null;
+        }
+    }
+
+    public KeyStore getKeyStore(final String keyStoreName, final String keyStorePwd) {
+        try {
+            final KeyStore keyStore = KeyStore.getInstance("JKS");
+            final FileInputStream fInputStream = new FileInputStream(workingDir + keyStoreName);
+            keyStore.load(fInputStream, keyStorePwd.toCharArray());
+            return keyStore;
+        } catch (NoSuchAlgorithmException | CertificateException | IOException | KeyStoreException e) {
+            LOG.error("failed to get keystore {}", e.getMessage());
+            return null;
+        }
+    }
+
+    private BigInteger getSecureRandomeInt() {
+        final SecureRandom secureRandom = new SecureRandom();
+        final BigInteger bigInt = BigInteger.valueOf(secureRandom.nextInt());
+        return new BigInteger(1, bigInt.toByteArray());
+    }
+}
diff --git a/aaa-cert/src/main/java/org/opendaylight/aaa/cert/impl/TlsConfigurationImp.java b/aaa-cert/src/main/java/org/opendaylight/aaa/cert/impl/TlsConfigurationImp.java
new file mode 100644 (file)
index 0000000..7e93ab3
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2016 Inocybe Technologies. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.aaa.cert.impl;
+
+import org.opendaylight.openflowjava.protocol.api.connection.TlsConfiguration;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.KeystoreType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType;
+
+/**
+ *
+ * @author mserngawy
+ * TlsConfigurationImp has configurations of the TLS connection
+ */
+public class TlsConfigurationImp implements TlsConfiguration{
+
+    private final String certPwd;
+    private final String tlsKeyStore;
+    private final PathType tlsKeystorePathType;
+    private final String tlsKeyStorePwd;
+    private final KeystoreType tlsKeyStoreType;
+    private final String trustKeyStore;
+    private final PathType trustKeystorePathType;
+    private final String trustKeyStorePwd;
+    private final KeystoreType trustKeyStoreType;
+
+    public TlsConfigurationImp(final String tlsKeyStore, final String trustKeyStore, final String tlsKeyStorePwd,
+            final String trustKeyStorePwd, final String certPwd, final KeystoreType tlsKeyStoreType,final KeystoreType trustKeyStoreTy,
+            final PathType tlsKeystorePathType, final PathType trustKeystorePathType) {
+        this.tlsKeyStore = tlsKeyStore;
+        this.trustKeyStore = trustKeyStore;
+        this.tlsKeyStorePwd = tlsKeyStorePwd;
+        this.trustKeyStorePwd = trustKeyStorePwd;
+        this.certPwd = certPwd;
+        this.tlsKeyStoreType = tlsKeyStoreType;
+        this.trustKeyStoreType = trustKeyStoreTy;
+        this.tlsKeystorePathType = tlsKeystorePathType;
+        this.trustKeystorePathType = trustKeystorePathType;
+    }
+
+    @Override
+    public String getCertificatePassword() {
+        return certPwd;
+    }
+
+    @Override
+    public String getKeystorePassword() {
+        return tlsKeyStorePwd;
+    }
+
+    @Override
+    public String getTlsKeystore() {
+        return tlsKeyStore;
+    }
+
+    @Override
+    public PathType getTlsKeystorePathType() {
+        return tlsKeystorePathType;
+    }
+
+    @Override
+    public KeystoreType getTlsKeystoreType() {
+        return tlsKeyStoreType;
+    }
+
+    @Override
+    public String getTlsTruststore() {
+        return trustKeyStore;
+    }
+
+    @Override
+    public PathType getTlsTruststorePathType() {
+        return trustKeystorePathType;
+    }
+
+    @Override
+    public KeystoreType getTlsTruststoreType() {
+        return trustKeyStoreType;
+    }
+
+    @Override
+    public String getTruststorePassword() {
+        return trustKeyStorePwd;
+    }
+}
diff --git a/aaa-cert/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/yang/aaa/cert/rev151126/AaaCertProviderModule.java b/aaa-cert/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/yang/aaa/cert/rev151126/AaaCertProviderModule.java
new file mode 100644 (file)
index 0000000..9ec349f
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2015 Inocybe Technologies. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rev151126;
+
+import java.util.List;
+
+import org.opendaylight.aaa.cert.impl.AaaCertProvider;
+import org.opendaylight.aaa.cert.impl.ConnectionConfigurationImpl;
+import org.opendaylight.aaa.cert.impl.KeyStoreUtilis;
+import org.opendaylight.aaa.cert.impl.TlsConfigurationImp;
+import org.opendaylight.openflowjava.protocol.api.connection.ConnectionConfiguration;
+import org.opendaylight.openflowjava.protocol.api.connection.TlsConfiguration;
+import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.KeystoreType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author mserngawy
+ * AaaCertProviderModule create and intialize the AaaCertProvider services
+ */
+public class AaaCertProviderModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rev151126.AbstractAaaCertProviderModule {
+
+    private final static Logger LOG = LoggerFactory.getLogger(AaaCertProviderModule.class);
+
+    public AaaCertProviderModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public AaaCertProviderModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, final org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rev151126.AaaCertProviderModule oldModule, final java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public AutoCloseable createInstance() {
+        final CtlKeystore ctlKeyStore = this.getCtlKeystore();
+        final TrustKeystore trust = this.getTrustKeystore();
+        final AaaCertProvider aaaCertProvider = new AaaCertProvider(ctlKeyStore, trust);
+        if (this.getUseConfig() && !KeyStoreUtilis.checkKeyStoreFile(ctlKeyStore.getName())) {
+            LOG.info("Creating keystore based on given configuration");
+            aaaCertProvider.createODLKeyStore();
+            aaaCertProvider.createTrustKeyStore();
+        }
+
+        final List<SwitchConnectionProvider> listSwitchConnectionProvider = this.getOpenflowSwitchConnectionDependency();
+        for (final SwitchConnectionProvider switchConnProvider : listSwitchConnectionProvider) {
+            if (switchConnProvider.getConfiguration() != null) {
+                LOG.info("Set TLS config then restart the connections ");
+                final ConnectionConfiguration connConfig = switchConnProvider.getConfiguration();
+                final TlsConfiguration tlsConfig = new TlsConfigurationImp(KeyStoreUtilis.keyStorePath + ctlKeyStore.getName(),
+                             KeyStoreUtilis.keyStorePath + trust.getName(), ctlKeyStore.getStorePassword(), trust.getStorePassword(),
+                             trust.getStorePassword(), KeystoreType.JKS, KeystoreType.JKS,
+                             PathType.PATH, PathType.PATH);
+                final ConnectionConfigurationImpl connConfigImpl = new ConnectionConfigurationImpl(connConfig, tlsConfig);
+                switchConnProvider.shutdown();
+                switchConnProvider.setConfiguration(connConfigImpl);
+                switchConnProvider.startup();
+            }
+        }
+
+        getBrokerDependency().registerProvider(aaaCertProvider);
+        return aaaCertProvider;
+    }
+
+    @Override
+    public void customValidation() {
+        // add custom validation form module attributes here.
+    }
+
+}
diff --git a/aaa-cert/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/yang/aaa/cert/rev151126/AaaCertProviderModuleFactory.java b/aaa-cert/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/yang/aaa/cert/rev151126/AaaCertProviderModuleFactory.java
new file mode 100644 (file)
index 0000000..4c96d4a
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+* Generated file
+*
+* Generated from: yang module name: aaa-cert yang module local name: aaa-cert
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Sun Nov 29 23:46:12 EST 2015
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rev151126;
+public class AaaCertProviderModuleFactory extends org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rev151126.AbstractAaaCertProviderModuleFactory {
+
+}
diff --git a/aaa-cert/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/aaa-cert/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644 (file)
index 0000000..6bd3c15
--- /dev/null
@@ -0,0 +1,4 @@
+<blueprint xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+           xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+           xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
+</blueprint>
\ No newline at end of file
diff --git a/aaa-cert/src/main/resources/initial/08-aaa-cert-config.xml b/aaa-cert/src/main/resources/initial/08-aaa-cert-config.xml
new file mode 100644 (file)
index 0000000..acf7c52
--- /dev/null
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2015 Inocybe Technology. All rights reserved.
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
+-->
+<snapshot>
+  <required-capabilities>
+      <capability>urn:opendaylight:yang:aaa:cert?module=aaa-cert&amp;revision=2015-11-26</capability>
+      <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28</capability>
+  </required-capabilities>
+  <configuration>
+    <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+      <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+        <module>
+          <type xmlns:prefix="urn:opendaylight:yang:aaa:cert">prefix:aaa-cert</type>
+          <name>aaa-cert</name>
+          <broker>
+            <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
+            <name>binding-osgi-broker</name>
+          </broker>
+          <openflow-switch-connection>
+            <type xmlns:ofSwitch="urn:opendaylight:params:xml:ns:yang:openflow:switch:connection:provider">ofSwitch:openflow-switch-connection-provider</type>
+            <name>openflow-switch-connection-provider-legacy</name>
+          </openflow-switch-connection>
+          <openflow-switch-connection>
+            <type xmlns:ofSwitch="urn:opendaylight:params:xml:ns:yang:openflow:switch:connection:provider">ofSwitch:openflow-switch-connection-provider</type>
+            <name>openflow-switch-connection-provider-default</name>
+          </openflow-switch-connection>
+          <useConfig>true</useConfig>
+          <ctlKeystore>
+            <name>ctl.jks</name>
+            <alias>controller</alias>
+            <storePassword>storePassword</storePassword>
+            <dname>CN=ODL, OU=Dev, O=LinuxFoundation, L=QC Montreal, C=CA</dname>
+            <validity>365</validity>
+          </ctlKeystore>
+          <trustKeystore>
+            <name>truststore.jks</name>
+            <alias>controller</alias>
+            <storePassword>storePassword</storePassword>
+            <certFile>cacert.pem</certFile>
+          </trustKeystore>
+        </module>
+      </modules>
+    </data>
+  </configuration>
+</snapshot>
diff --git a/aaa-cert/src/main/test/org/opendaylight/aaa/cert/test/AaaCertProviderTest.java b/aaa-cert/src/main/test/org/opendaylight/aaa/cert/test/AaaCertProviderTest.java
new file mode 100644 (file)
index 0000000..9c41377
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2016 Inocybe Technologies. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.aaa.cert.test;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.security.Security;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.opendaylight.aaa.cert.impl.AaaCertProvider;
+import org.opendaylight.aaa.cert.impl.KeyStoreUtilis;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rev151126.CtlKeystore;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rev151126.TrustKeystore;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rpc.rev151215.GetNodeCertifcateInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rpc.rev151215.GetNodeCertifcateOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rpc.rev151215.GetODLCertificateOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rpc.rev151215.GetODLCertificateReqOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rpc.rev151215.SetNodeCertifcateInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rpc.rev151215.SetODLCertifcateInput;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@RunWith(PowerMockRunner.class)
+public class AaaCertProviderTest {
+
+    private static AaaCertProvider aaaCertProv;
+    private static CtlKeystore ctlKeyStore;
+    private static TrustKeystore trustKeyStore;
+
+    private String dummyAlias = "fooAlias";
+    private String dummyCert = KeyStoreUtilis.BEGIN_CERTIFICATE +
+                          "MIIDLjCCAhagAwIBAgIELsFzhjANBgkqhkiG9w0BAQUFADBZMQwwCgYDV"+
+                          "QQDDANPREwxDDAKBgNVBAsMA0RldjEYMBYGA1UECgwPTGludXhGb3VuZG"+
+                          "F0aW9uMRQwEgYDVQQHDAtRQyBNb250cmVhbDELMAkGA1UEBhMCQ0EwHhc"+
+                          "NMTYwMTA0MTcxNDM3WhcNMTcwMTAzMTcxNDM3WjBZMQwwCgYDVQQDDANP"+
+                          "REwxDDAKBgNVBAsMA0RldjEYMBYGA1UECgwPTGludXhGb3VuZGF0aW9uM"+
+                          "RQwEgYDVQQHDAtRQyBNb250cmVhbDELMAkGA1UEBhMCQ0EwggEiMA0GCS"+
+                          "qGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsmMPHlF5pfAO3HzvM1pVIPwg"+
+                          "at1gq8cHi5wF8d+qt4+jK2uihp9LhAZ3aAZEbRqvZjDYnXaavCFRXZKUN"+
+                          "3AjxvYV0VHtVILK7+xOJGUWgJ5BxZ4utTvQ/3LavTQGZHNH3jGeqWMf3f"+
+                          "t1T1jiM72nNxN3KZykDVKoUPLpmci0OCMo+IFkcelVojRJGC9q7MSHcbY"+
+                          "XBU/HI+frmp4UkfBTcUWJidTj3jJvT8azCEoysy0HSt85x/IZukN2goco"+
+                          "kDm6uyavImdqac/c2ApzEAkBVM/+NkvMBIrRjX4AsmejYSP6nMIPbYRV0"+
+                          "V6oWL1sMmrvCb5Kt8/jNDa493jO/dDiRAgMBAAEwDQYJKoZIhvcNAQEFB"+
+                          "QADggEBAHKFTBRPqXFp4VYECTSdUsn7nad1LawrYE4DB16j5pbmnNwNIH"+
+                          "D4W+Wh0EJEfd6iEdu7DJfHS6OqjYKj9ruqyO6LOGBy8eYzyvtq9dkYEOy"+
+                          "i86CIb6NRfVR/ycJgeC7sc+y91wPbZlRXtY+UA7RohebC8Cyg6Kr/zEwv"+
+                          "OT0fAjQi6Mypje08OstA2sklTSPfYtrDFJUpJW7+5fGic/wf5ITPmMVJl"+
+                          "rt6aSStfyOLhCSAWXmU/1Pn1pixltJvaLnd0HYQdhcFOS9XG5LfA3Mlqm"+
+                          "ZEwGEjhpmk810dJyRjoCEsokljWyhmJGW6hTK1j+2V+PCHqyawghiTB0jQFRTt2zo="+
+                          KeyStoreUtilis.END_CERTIFICATE;
+
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        KeyStoreUtilis.keyStorePath = "target" + File.separator + "test" + File.separator;
+        String dName = "CN=ODL, OU=Dev, O=LinuxFoundation, L=QC Montreal, C=CA";
+        Security.addProvider(new BouncyCastleProvider());
+        ctlKeyStore = new CtlKeystore();
+        ctlKeyStore.setAlias("fooTest");
+        ctlKeyStore.setDname(dName);
+        ctlKeyStore.setName("fooTest.jks");
+        ctlKeyStore.setStorePassword("passWord");
+        ctlKeyStore.setValidity(KeyStoreUtilis.defaultValidity);
+        trustKeyStore = new TrustKeystore();
+        trustKeyStore.setAlias("trustTest");
+        trustKeyStore.setCertFile("cacert.pem");
+        trustKeyStore.setName("trustTest.jks");
+        trustKeyStore.setStorePassword("passWord");
+        aaaCertProv = new AaaCertProvider(ctlKeyStore, trustKeyStore);
+    }
+
+    @Test
+    public void testCreateTrustKeyStore() {
+        String result = aaaCertProv.createTrustKeyStore(trustKeyStore.getName(), trustKeyStore.getStorePassword(),
+                trustKeyStore.getAlias());
+        assertEquals(result, trustKeyStore.getName() + " Keystore created.");
+    }
+
+    @Test
+    public void testCreateODLKeyStoreString() {
+        String result = aaaCertProv.createODLKeyStore(ctlKeyStore.getName(), ctlKeyStore.getStorePassword(),
+                ctlKeyStore.getAlias(), ctlKeyStore.getDname(), ctlKeyStore.getValidity());
+        assertEquals(result, ctlKeyStore.getName() + " Keystore created.");
+    }
+
+    @Test
+    public void testGetODLCertificateReq() throws InterruptedException, ExecutionException {
+        Future<RpcResult<GetODLCertificateReqOutput>> future = aaaCertProv.getODLCertificateReq();
+        assertTrue(future != null);
+        RpcResult<GetODLCertificateReqOutput> rpc = future.get();
+        assertTrue(rpc.isSuccessful());
+        String certReq = rpc.getResult().getOdlCertReq();
+        assertTrue(certReq != null);
+        assertTrue(certReq.contains(KeyStoreUtilis.BEGIN_CERTIFICATE_REQUEST));
+    }
+
+    @Test
+    public void testSetODLCertifcate() throws InterruptedException, ExecutionException {
+        SetODLCertifcateInput input = mock(SetODLCertifcateInput.class, Mockito.RETURNS_MOCKS);
+        when(input.getOdlCert()).thenReturn(dummyCert);
+        Future<RpcResult<Void>> future = aaaCertProv.setODLCertifcate(input);
+        assertTrue(future != null);
+        assertTrue(future.get().isSuccessful());
+    }
+
+    @Test
+    public void testGetODLCertificate() throws InterruptedException, ExecutionException {
+        Future<RpcResult<GetODLCertificateOutput>> future = aaaCertProv.getODLCertificate();
+        assertTrue(future != null);
+        RpcResult<GetODLCertificateOutput> rpc = future.get();
+        assertTrue(rpc.isSuccessful());
+        String cert = aaaCertProv.getODLKeyStorCertificate(ctlKeyStore.getStorePassword(), ctlKeyStore.getAlias());
+        assertEquals(rpc.getResult().getOdlCert(), cert);
+    }
+
+    @Test
+    public void testSetNodeCertifcate() throws InterruptedException, ExecutionException {
+        SetNodeCertifcateInput input = mock(SetNodeCertifcateInput.class, Mockito.RETURNS_MOCKS);
+        when(input.getNodeCert()).thenReturn(dummyCert);
+        when(input.getNodeAlias()).thenReturn(dummyAlias);
+        Future<RpcResult<Void>> future = aaaCertProv.setNodeCertifcate(input);
+        assertTrue(future != null);
+        assertTrue(future.get().isSuccessful());
+    }
+
+    @Test
+    public void testGetNodeCertifcate() throws InterruptedException, ExecutionException {
+        GetNodeCertifcateInput input = mock(GetNodeCertifcateInput.class, Mockito.RETURNS_MOCKS);
+        when(input.getNodeAlias()).thenReturn(dummyAlias);
+        Future<RpcResult<GetNodeCertifcateOutput>> future = aaaCertProv.getNodeCertifcate(input);
+        assertTrue(future != null);
+        RpcResult<GetNodeCertifcateOutput> rpc = future.get();
+        assertTrue(rpc.isSuccessful());
+        String cert = aaaCertProv.getCertificateTrustStore(trustKeyStore.getStorePassword(), dummyAlias);
+        assertEquals(cert, rpc.getResult().getNodeCert());
+    }
+}
diff --git a/aaa-cert/src/main/test/org/opendaylight/aaa/cert/test/KeyStoreUtilisTest.java b/aaa-cert/src/main/test/org/opendaylight/aaa/cert/test/KeyStoreUtilisTest.java
new file mode 100644 (file)
index 0000000..91e3241
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Inocybe Technologies. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.aaa.cert.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.aaa.cert.impl.KeyStoreUtilis;
+
+public class KeyStoreUtilisTest {
+
+    private final String fileName = "foo.pem";
+    private final String txt = "test save text";
+
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        KeyStoreUtilis.keyStorePath = "target" + File.separator + "test" + File.separator;
+    }
+
+    @Test
+    public void testCreateDir() {
+        final String path = KeyStoreUtilis.createDir(KeyStoreUtilis.keyStorePath);
+        assertTrue(!path.isEmpty());
+        final File dir = new File(path);
+        assertTrue(dir.exists());
+    }
+
+    @Test
+    public void testSaveCert() {
+        assertTrue(KeyStoreUtilis.saveCert(fileName, txt));
+    }
+
+    @Test
+    public void testCheckKeyStoreFile() {
+        assertTrue(KeyStoreUtilis.checkKeyStoreFile(fileName));
+        assertTrue(!KeyStoreUtilis.checkKeyStoreFile("notExist.txt"));
+    }
+
+    @Test
+    public void testReadFile() {
+        final String readTxt = KeyStoreUtilis.readFile(fileName);
+        assertEquals(txt, readTxt);
+    }
+}
diff --git a/aaa-cert/src/main/test/org/opendaylight/aaa/cert/test/ODLKeyToolTest.java b/aaa-cert/src/main/test/org/opendaylight/aaa/cert/test/ODLKeyToolTest.java
new file mode 100644 (file)
index 0000000..74dfcbf
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2016 Inocybe Technologies. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.aaa.cert.test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.security.Security;
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.aaa.cert.impl.KeyStoreUtilis;
+import org.opendaylight.aaa.cert.impl.ODLKeyTool;
+
+public class ODLKeyToolTest {
+
+    private static ODLKeyTool odlKeyTool;
+    private static String testPath = "target" + File.separator + "test" + File.separator;
+    private final String keyStore = "fooTest.jks";
+    private final String trustKeyStore = "footrust.jks";
+    private final String passwd = "Password";
+    private final String alias = "FooTest";
+    private final String certFile = "cert.pem";
+
+    static {
+        Security.addProvider(new BouncyCastleProvider());
+    }
+
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        KeyStoreUtilis.keyStorePath = testPath;
+        odlKeyTool = new ODLKeyTool(testPath);
+    }
+
+    @Test
+    public void testCreateKeyStoreWithSelfSignCert() {
+        final String dName = "CN=ODL, OU=Dev, O=LinuxFoundation, L=QC Montreal, C=CA";
+        assertTrue(odlKeyTool.createKeyStoreWithSelfSignCert(keyStore, passwd, dName, alias,
+                KeyStoreUtilis.defaultValidity));
+    }
+
+    @Test
+    public void testGetCertificate() {
+        String cert = odlKeyTool.getCertificate(keyStore, passwd, alias, false);
+        assertTrue(cert != null && cert.length() > 0);
+        cert = odlKeyTool.getCertificate(keyStore, passwd, alias, true);
+        assertTrue(cert.contains(KeyStoreUtilis.BEGIN_CERTIFICATE));
+    }
+
+    @Test
+    public void testGenerateCertificateReq() {
+        String certReq = odlKeyTool.generateCertificateReq(keyStore, passwd, alias,
+                KeyStoreUtilis.defaultSignAlg, false);
+        assertTrue(certReq != null && certReq.length() > 0);
+        certReq = odlKeyTool.generateCertificateReq(keyStore, passwd, alias,
+                KeyStoreUtilis.defaultSignAlg, true);
+        assertTrue(certReq.contains(KeyStoreUtilis.BEGIN_CERTIFICATE_REQUEST));
+    }
+
+    @Test
+    public void testCreateKeyStoreImportCert() {
+        assertTrue(odlKeyTool.createKeyStoreImportCert(trustKeyStore, passwd, null, alias));
+        final String cert = odlKeyTool.getCertificate(keyStore, passwd, alias, false);
+        KeyStoreUtilis.saveCert(certFile, cert);
+        assertTrue(odlKeyTool.createKeyStoreImportCert(trustKeyStore, passwd, certFile, alias));
+    }
+
+    @Test
+    public void testAddCertificate() {
+        final String cert = KeyStoreUtilis.readFile(certFile);
+        assertTrue(odlKeyTool.addCertificate(trustKeyStore, passwd, cert, alias));
+    }
+
+    @Test
+    public void testGetKeyStore() {
+        assertNotNull(odlKeyTool.getKeyStore(keyStore, passwd));
+        assertNotNull(odlKeyTool.getKeyStore(trustKeyStore, passwd));
+    }
+
+}
diff --git a/aaa-cert/src/main/yang/aaa-cert-rpc.yang b/aaa-cert/src/main/yang/aaa-cert-rpc.yang
new file mode 100644 (file)
index 0000000..5d1aa69
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+Copyright (c) 2015 Inocybe Technology All rights reserved.
+
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
+*/
+
+module aaa-cert-rpc {
+    yang-version 1;
+    namespace "urn:opendaylight:yang:aaa:cert:rpc";
+    prefix "aaa-cert-rpc";
+
+    description
+        "defination of node certificate grouping and Rpc calls of certificate manipulation";
+
+    contact
+        "melserngawy@inocybe.com";
+
+    revision "2015-12-15" {
+        description
+            "Initial revision.";
+    }
+
+    grouping node-certificate {
+        leaf alias {
+            description "ovs node certificate alias";
+            type string;
+        }
+        leaf certificate {
+            description "ovs node certificate";
+            type string;
+        }
+    }
+
+    rpc getODLCertificate {
+        description
+            "Get the ctl.jks keystore certificate";
+        output {
+           leaf odl-cert {
+               type string;
+           }
+        }
+    }
+
+    rpc getODLCertificateReq {
+        description
+            "Generate a certificate request from the ctl.jks keystore to be signed by a CA";
+        output {
+           leaf odl-cert-req {
+               type string;
+           }
+        }
+    }
+
+    rpc setODLCertifcate {
+        description
+            "The certifcate should be generated based on
+            a certifcate request generated from the ctl.jks
+            keystore otherwise the certifcated will not be added to ctl keystore";
+        input {
+           leaf odl-cert {
+               type string;
+           }
+        }
+    }
+
+    rpc setNodeCertifcate {
+        description
+            "Certifcate of the ovs node that will communicate with opendaylight through TLS connection";
+        input {
+           leaf node-alias {
+               type string;
+           }
+           leaf node-cert {
+               type string;
+           }
+        }
+    }
+
+    rpc getNodeCertifcate {
+        description
+            "Get the ovs node certificate based on node alias";
+        input {
+           leaf node-alias {
+               type string;
+           }
+        }
+        output {
+            leaf node-cert {
+                type string;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/aaa-cert/src/main/yang/aaa-cert.yang b/aaa-cert/src/main/yang/aaa-cert.yang
new file mode 100644 (file)
index 0000000..32a16ff
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+Copyright (c) 2015 Inocybe Technology All rights reserved.
+
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
+*/
+
+module aaa-cert {
+    yang-version 1;
+    namespace "urn:opendaylight:yang:aaa:cert";
+    prefix aaa-cert;
+
+    import config {
+        prefix config;
+        revision-date 2013-04-05;
+    }
+
+    import opendaylight-md-sal-binding {
+        prefix md-sal-binding;
+        revision-date 2013-10-28;
+    }
+
+    import openflow-switch-connection-provider {
+        prefix openflow-switch-connection-provider;
+        revision-date 2014-03-28;
+    }
+
+    description
+        "Service definition for aaa certificate";
+
+    contact
+        "melserngawy@inocybe.com";
+
+    revision "2015-11-26" {
+        description
+            "Initial revision.";
+    }
+
+    identity aaa-cert {
+        base config:module-type;
+        config:java-name-prefix AaaCertProvider;
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case aaa-cert {
+            when "/config:modules/config:module/config:type = 'aaa-cert'";
+            container broker {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity md-sal-binding:binding-broker-osgi-registry;
+                    }
+                }
+            }
+            list openflow-switch-connection {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity openflow-switch-connection-provider:openflow-switch-connection-provider;
+                    }
+                }
+            }
+            leaf useConfig {
+                description "Use the configuration data to create the keystores";
+                type boolean;
+                default false;
+            }
+            container ctlKeystore {
+                leaf name {
+                    description "keystore name default is ctl";
+                    type string;
+                }
+                leaf alias {
+                    description "key alias";
+                    type string;
+                }
+                leaf storePassword {
+                    description "keystore password";
+                    type string;
+                }
+                leaf dname {
+                    description "X.500 Distinguished Names should be in the following formate
+                        CN=commonName
+                        OU=organizationUnit
+                        O=organizationName
+                        L=localityName
+                        S=stateName
+                        C=country";
+                    type string;
+                }
+                leaf validity {
+                    description "validity";
+                    type int32;
+                }
+            }
+            container trustKeystore {
+                leaf name {
+                    description "keystore name default is truststore";
+                    type string;
+                }
+                leaf alias {
+                    description "key alias";
+                    type string;
+                }
+                leaf storePassword {
+                    description "keystore password";
+                    type string;
+                }
+                leaf certFile {
+                    description "path to CA certificate pem file";
+                    type string;
+                }
+            }
+        }
+    }
+}
diff --git a/aaa-cli/pom.xml b/aaa-cli/pom.xml
new file mode 100755 (executable)
index 0000000..46e6032
--- /dev/null
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2015 Inocybe Technology All rights reserved.
+
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+
+  <parent>
+    <groupId>org.opendaylight.aaa</groupId>
+    <artifactId>aaa-parent</artifactId>
+    <version>0.4.0-SNAPSHOT</version>
+    <relativePath>../parent</relativePath>
+  </parent>
+
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>aaa-cli</artifactId>
+  <packaging>bundle</packaging>
+
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>aaa-cert</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.karaf.shell</groupId>
+      <artifactId>org.apache.karaf.shell.console</artifactId>
+      <version>${karaf.version}</version>
+    </dependency>
+
+    <!-- Testing Dependencies -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/aaa-cli/src/main/java/org/opendaylight/aaa/cli/AddCertODLKeyStore.java b/aaa-cli/src/main/java/org/opendaylight/aaa/cli/AddCertODLKeyStore.java
new file mode 100644 (file)
index 0000000..189439d
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2016 Inocybe Technologies. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.aaa.cli;
+
+import java.io.FileInputStream;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.aaa.cert.api.IAaaCertProvider;
+
+@Command(name = "add-odl-cert", scope = "aaa", description = "Add ODL signed certificaet to ODL key store.")
+
+/**
+ *
+ * @author mserngawy
+ * AddCertODLKeyStore adding certificate to the ODL keyStore
+ */
+public class AddCertODLKeyStore extends OsgiCommandSupport {
+
+    protected IAaaCertProvider certProvider;
+
+    @Option(name = "-cert",
+            aliases = { "--CertFile" },
+            description = "The ODL certificate file.\n-file / --should be accesable by the karaf command line",
+            required = true,
+            multiValued = false)
+    private String certFile = "";
+
+    @Option(name = "-storepass",
+            aliases = { "--KeyStorePass" },
+            description = "The ODL keystore password.\n-storepass",
+            required = true,
+            multiValued = false)
+    private String keyStorePassword = "";
+
+    @Option(name = "-alias",
+            aliases = { "--alias" },
+            description = "The alias.\n-alias / ODL alias default is controller as the configuration",
+            required = false,
+            multiValued = false)
+    private String alias = "controller";
+
+    public AddCertODLKeyStore(final IAaaCertProvider aaaCertProvider) {
+        this.certProvider = aaaCertProvider;
+    }
+
+    @Override
+    protected Object doExecute() throws Exception {
+        final FileInputStream fInputStream = new FileInputStream(certFile);
+        final byte[] certBytes = new byte[fInputStream.available()];
+        fInputStream.read(certBytes);
+        fInputStream.close();
+        final String certificate = new String(certBytes, StandardCharsets.UTF_8);
+        if (certProvider.addCertificateODLKeyStore(keyStorePassword, alias, certificate)) {
+            return alias + " certificate successfully added to ODL keystore";
+        } else {
+            return "Failed to add " + alias + " certificate to ODL keystore";
+        }
+    }
+
+}
diff --git a/aaa-cli/src/main/java/org/opendaylight/aaa/cli/AddCertTrustStore.java b/aaa-cli/src/main/java/org/opendaylight/aaa/cli/AddCertTrustStore.java
new file mode 100644 (file)
index 0000000..a4056b6
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016 Inocybe Technologies. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.aaa.cli;
+
+import java.io.FileInputStream;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.aaa.cert.api.IAaaCertProvider;
+
+@Command(name = "add-trust-cert", scope = "aaa", description = "Add node certificaet to trust key store.")
+
+/**
+*
+* @author mserngawy
+* AddCertTrustStore adding certificate to the ODL keyStore
+*/
+public class AddCertTrustStore extends OsgiCommandSupport {
+
+    protected IAaaCertProvider certProvider;
+
+    @Option(name = "-cert",
+            aliases = { "--CertFile" },
+            description = "The node certificate file.\n-file / --should be accesable by the karaf command line",
+            required = true,
+            multiValued = false)
+    private String certFile = "";
+
+    @Option(name = "-storepass",
+            aliases = { "--KeyStorePass" },
+            description = "The Trust keystore password.\n-storepass",
+            required = true,
+            multiValued = false)
+    private String keyStorePassword = "";
+
+    @Option(name = "-alias",
+            aliases = { "--alias" },
+            description = "The alias.\n-alias / node alias should be unique",
+            required = true,
+            multiValued = false)
+    private String alias = "";
+
+    public AddCertTrustStore(final IAaaCertProvider aaaCertProvider) {
+        this.certProvider = aaaCertProvider;
+    }
+
+    @Override
+    protected Object doExecute() throws Exception {
+        final FileInputStream fInputStream = new FileInputStream(certFile);
+        final byte[] certBytes = new byte[fInputStream.available()];
+        fInputStream.read(certBytes);
+        fInputStream.close();
+        final String certificate = new String(certBytes, StandardCharsets.UTF_8);
+        if (certProvider.addCertificateTrustStore(keyStorePassword, alias, certificate)) {
+            return alias + " certificate successfully added to trust keystore";
+        } else {
+            return "Failed to add " + alias + " certificate to trust keystore";
+        }
+    }
+}
diff --git a/aaa-cli/src/main/java/org/opendaylight/aaa/cli/CreateODLKeyStore.java b/aaa-cli/src/main/java/org/opendaylight/aaa/cli/CreateODLKeyStore.java
new file mode 100644 (file)
index 0000000..fb3e5f0
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016 Inocybe Technologies. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.aaa.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.aaa.cert.api.IAaaCertProvider;
+
+@Command(name = "gen-odl-ks", scope = "aaa", description = "Create the default keystore for the opendaylight controller.")
+
+/**
+ *
+ * @author mserngawy
+ * CreateODLKeyStore create the ODL keystore with new configuration.
+ */
+public class CreateODLKeyStore extends OsgiCommandSupport{
+
+    protected IAaaCertProvider certProvider;
+
+    @Option(name = "-keystore",
+            aliases = { "--KeyStore" },
+            description = "The keystore name.\n-keystore / --default is ctl.jks",
+            required = false,
+            multiValued = false)
+    private String keyStoreName = "ctl.jks";
+
+    @Option(name = "-storepass",
+            aliases = { "--KeyStorePass" },
+            description = "The keystore password.\n-storepass",
+            required = true,
+            multiValued = false)
+    private String keyStorePassword = "";
+
+    @Option(name = "-alias",
+            aliases = { "--alias" },
+            description = "The alias.\n-alias / --default is controller",
+            required = false,
+            multiValued = false)
+    private String alias = "controller";
+
+    @Option(name = "-validity",
+            aliases = { "--validity" },
+            description = "The validity.\n-validity of the keystore certificate / --default is 365",
+            required = false,
+            multiValued = false)
+    private int validity = 365;
+
+    @Option(name = "-dName",
+            aliases = { "--dName" },
+            description = "The dName.\n-dName / --should be in the following formate CN=, OU=, O=, L= C=",
+            required = false,
+            multiValued = false)
+    private String dName = "CN=ODL, OU=Dev, O=LinuxFoundation, L=QC. Montreal, C=CA";
+
+    public CreateODLKeyStore(final IAaaCertProvider aaaCertProvider) {
+        this.certProvider = aaaCertProvider;
+    }
+
+    @Override
+    protected Object doExecute() throws Exception {
+        final StringBuilder sb = new StringBuilder();
+        sb.append(certProvider.createODLKeyStore(keyStoreName, keyStorePassword, alias, dName, validity));
+        sb.append("\n");
+        sb.append("08-aaa-cert-config.xml file should be updated with new keystore info");
+        return sb.toString();
+    }
+}
\ No newline at end of file
diff --git a/aaa-cli/src/main/java/org/opendaylight/aaa/cli/CreateTrustKeyStore.java b/aaa-cli/src/main/java/org/opendaylight/aaa/cli/CreateTrustKeyStore.java
new file mode 100644 (file)
index 0000000..1abe662
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016 Inocybe Technologies. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.aaa.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.aaa.cert.api.IAaaCertProvider;
+
+@Command(name = "gen-trust-ks", scope = "aaa", description = "Create the trust keystore for the opendaylight controller.")
+
+/**
+ *
+ * @author mserngawy
+ * CreateTrustKeyStore create trust key store with new configuration
+ */
+public class CreateTrustKeyStore extends OsgiCommandSupport{
+
+    protected IAaaCertProvider certProvider;
+
+    @Option(name = "-keystore",
+            aliases = { "--KeyStore" },
+            description = "The keystore name.\n-keystore / --default is truststore.jks",
+            required = false,
+            multiValued = false)
+    private String keyStoreName = "truststore.jks";
+
+    @Option(name = "-storepass",
+            aliases = { "--KeyStorePass" },
+            description = "The keystore password.\n-storepass",
+            required = true,
+            multiValued = false)
+    private String keyStorePassword = "";
+
+    @Option(name = "-alias",
+            aliases = { "--alias" },
+            description = "The alias.\n-alias / --default is node",
+            required = false,
+            multiValued = false)
+    private String alias = "node";
+
+    public CreateTrustKeyStore(final IAaaCertProvider aaaCertProvider) {
+        this.certProvider = aaaCertProvider;
+    }
+
+    @Override
+    protected Object doExecute() throws Exception {
+        final StringBuilder sb = new StringBuilder();
+        sb.append(certProvider.createTrustKeyStore(keyStoreName, keyStorePassword, alias));
+        sb.append("\n");
+        sb.append("08-aaa-cert-config.xml file should be updated with new keystore info");
+        return sb.toString();
+    }
+
+}
diff --git a/aaa-cli/src/main/java/org/opendaylight/aaa/cli/GenerateCertReq.java b/aaa-cli/src/main/java/org/opendaylight/aaa/cli/GenerateCertReq.java
new file mode 100644 (file)
index 0000000..fe2599c
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Inocybe Technologies. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.aaa.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.aaa.cert.api.IAaaCertProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Command(name = "gen-cert-req", scope = "aaa", description = "generate a certificate request for the opendaylight controller.")
+
+/**
+ *
+ * @author mserngawy
+ * GenerateCertReq from the ODL key store to be signed by the Certificate Authority 'CA'
+ */
+public class GenerateCertReq extends OsgiCommandSupport{
+
+    private static final Logger LOG = LoggerFactory.getLogger(GenerateCertReq.class);
+    protected IAaaCertProvider certProvider;
+
+    @Option(name = "-storepass",
+            aliases = { "--KeyStorePass" },
+            description = "The keystore password.\n-storepass",
+            required = true,
+            multiValued = false)
+    private String keyStorePassword = "";
+
+    @Option(name = "-alias",
+            aliases = { "--alias" },
+            description = "The alias.\n-alias / --default is controller",
+            required = false,
+            multiValued = false)
+    private String alias = "controller";
+
+    public GenerateCertReq(final IAaaCertProvider aaaCertProvider) {
+        this.certProvider = aaaCertProvider;
+    }
+
+    @Override
+    protected Object doExecute() throws Exception {
+        return certProvider.genODLKeyStorCertificateReq(keyStorePassword, alias);
+    }
+
+}
diff --git a/aaa-cli/src/main/java/org/opendaylight/aaa/cli/GetODLSelfSignCert.java b/aaa-cli/src/main/java/org/opendaylight/aaa/cli/GetODLSelfSignCert.java
new file mode 100644 (file)
index 0000000..15ce8b3
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016 Inocybe Technologies. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.aaa.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.aaa.cert.api.IAaaCertProvider;
+
+@Command(name = "get-odl-cert", scope = "aaa", description = "get self sign certificate for the opendaylight controller.")
+
+/**
+ *
+ * @author mserngawy
+ * GetODLSelfSignCert get the ODL key store self sign certificate.
+ */
+public class GetODLSelfSignCert extends OsgiCommandSupport{
+
+    protected IAaaCertProvider certProvider;
+
+    @Option(name = "-storepass",
+            aliases = { "--KeyStorePass" },
+            description = "The keystore password.\n-storepass",
+            required = true,
+            multiValued = false)
+    private String keyStorePassword = "";
+
+    @Option(name = "-alias",
+            aliases = { "--alias" },
+            description = "The alias.\n-alias / --default is controller",
+            required = false,
+            multiValued = false)
+    private String alias = "controller";
+
+    public GetODLSelfSignCert(final IAaaCertProvider aaaCertProvider) {
+        this.certProvider = aaaCertProvider;
+    }
+
+    @Override
+    protected Object doExecute() throws Exception {
+        return certProvider.getODLKeyStorCertificate(keyStorePassword, alias);
+    }
+
+}
diff --git a/aaa-cli/src/main/java/org/opendaylight/aaa/cli/GetTrustStoreCert.java b/aaa-cli/src/main/java/org/opendaylight/aaa/cli/GetTrustStoreCert.java
new file mode 100644 (file)
index 0000000..fa6d11b
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Inocybe Technologies. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.aaa.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.aaa.cert.api.IAaaCertProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Command(name = "get-node-cert", scope = "aaa", description = "get node certificate form the opendaylight trust keystore .")
+
+/**
+ *
+ * @author mserngawy
+ * GetTrustStoreCert get a certain certificate stored in the trust key store using the its alias
+ */
+public class GetTrustStoreCert  extends OsgiCommandSupport{
+
+    private static final Logger LOG = LoggerFactory.getLogger(GetTrustStoreCert.class);
+    protected IAaaCertProvider certProvider;
+
+    @Option(name = "-storepass",
+            aliases = { "--KeyStorePass" },
+            description = "The keystore password.\n-storepass",
+            required = true,
+            multiValued = false)
+    private String keyStorePassword = "";
+
+    @Option(name = "-alias",
+            aliases = { "--alias" },
+            description = "The alias.\n-alias / --should be the node certificate alias",
+            required = true,
+            multiValued = false)
+    private String alias = "";
+
+    public GetTrustStoreCert(final IAaaCertProvider aaaCertProvider) {
+        this.certProvider = aaaCertProvider;
+    }
+
+    @Override
+    protected Object doExecute() throws Exception {
+        return certProvider.getCertificateTrustStore(keyStorePassword, alias);
+    }
+
+}
diff --git a/aaa-cli/src/main/resources/OSGI-INF/blueprint/commands.xml b/aaa-cli/src/main/resources/OSGI-INF/blueprint/commands.xml
new file mode 100644 (file)
index 0000000..5185343
--- /dev/null
@@ -0,0 +1,45 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+    <reference id="KeyStoreConsoleProvider" availability="mandatory"
+        activation="eager" interface="org.opendaylight.aaa.cert.api.IAaaCertProvider">
+    </reference>
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.opendaylight.aaa.cli.CreateODLKeyStore">
+                <argument ref="KeyStoreConsoleProvider" />
+            </action>
+        </command>
+        <command>
+            <action class="org.opendaylight.aaa.cli.GetODLSelfSignCert">
+                <argument ref="KeyStoreConsoleProvider" />
+            </action>
+        </command>
+        <command>
+            <action class="org.opendaylight.aaa.cli.GenerateCertReq">
+                <argument ref="KeyStoreConsoleProvider" />
+            </action>
+        </command>
+        <command>
+            <action class="org.opendaylight.aaa.cli.CreateTrustKeyStore">
+                <argument ref="KeyStoreConsoleProvider" />
+            </action>
+        </command>
+        <command>
+            <action class="org.opendaylight.aaa.cli.GetTrustStoreCert">
+                <argument ref="KeyStoreConsoleProvider" />
+            </action>
+        </command>
+        <command>
+            <action class="org.opendaylight.aaa.cli.AddCertTrustStore">
+                <argument ref="KeyStoreConsoleProvider" />
+            </action>
+        </command>
+        <command>
+            <action class="org.opendaylight.aaa.cli.AddCertODLKeyStore">
+                <argument ref="KeyStoreConsoleProvider" />
+            </action>
+        </command>
+    </command-bundle>
+
+</blueprint>
\ No newline at end of file
index 0ef8714d4ff90d7c437fb1aced0b13dcb7cc0c64..24a0611cfb4342bb9e8625c1eff259a45e4c2388 100644 (file)
                 <classifier>config</classifier>
                 <type>xml</type>
             </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>aaa-cli</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>aaa-cli</artifactId>
+                <version>${project.version}</version>
+                <classifier>features</classifier>
+                <type>xml</type>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>aaa-cert</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>aaa-cert</artifactId>
+                <version>${project.version}</version>
+                <classifier>config</classifier>
+                <type>xml</type>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>aaa-cert</artifactId>
+                <version>${project.version}</version>
+                <classifier>features</classifier>
+                <type>xml</type>
+            </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>features-aaa-shiro</artifactId>
index ea092b32eadb51fe8fc4f946c012edffec5367db..0c1d9816e2a2c550da5a1e1c62c6c6085186f9bf 100644 (file)
             <type>xml</type>
             <scope>runtime</scope>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.aaa</groupId>
+            <artifactId>features-aaa-cert</artifactId>
+            <classifier>features</classifier>
+            <version>${project.version}</version>
+            <type>xml</type>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.aaa</groupId>
+            <artifactId>features-aaa-cli</artifactId>
+            <classifier>features</classifier>
+            <version>${project.version}</version>
+            <type>xml</type>
+            <scope>runtime</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/features/aaa-cert/pom.xml b/features/aaa-cert/pom.xml
new file mode 100644 (file)
index 0000000..9d13269
--- /dev/null
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2015 Inocybe Technology All rights reserved.
+
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>features-parent</artifactId>
+        <version>1.7.0-SNAPSHOT</version>
+        <relativePath/>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.opendaylight.aaa</groupId>
+    <artifactId>features-aaa-cert</artifactId>
+    <version>0.4.0-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.opendaylight.aaa</groupId>
+                <artifactId>aaa-parent</artifactId>
+                <version>${project.version}</version>
+                <scope>import</scope>
+                <type>pom</type>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+  <properties>
+    <openflowplugin.version>0.3.0-SNAPSHOT</openflowplugin.version>
+    <controller.mdsal.version>1.4.0-SNAPSHOT</controller.mdsal.version>
+  </properties>
+
+  <dependencies>
+    <dependency>
+       <groupId>org.opendaylight.aaa</groupId>
+       <artifactId>features-aaa</artifactId>
+       <version>${project.version}</version>
+       <classifier>features</classifier>
+       <type>xml</type>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.aaa</groupId>
+      <artifactId>aaa-cert</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.aaa</groupId>
+      <artifactId>aaa-cert</artifactId>
+      <version>${project.version}</version>
+      <classifier>config</classifier>
+      <type>xml</type>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>features-mdsal</artifactId>
+      <classifier>features</classifier>
+      <type>xml</type>
+    </dependency>
+    <dependency>
+    <groupId>org.apache.maven</groupId>
+      <artifactId>maven-aether-provider</artifactId>
+      <version>3.0.5</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.openflowplugin</groupId>
+      <artifactId>features-openflowplugin-li</artifactId>
+      <version>${openflowplugin.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+    </dependency>
+    <dependency>
+      <groupId>org.bouncycastle</groupId>
+      <artifactId>bcprov-jdk15on</artifactId>
+    </dependency>
+  </dependencies>
+
+  <scm>
+      <connection>scm:git:ssh://git.opendaylight.org:29418/aaa.git</connection>
+      <developerConnection>scm:git:ssh://git.opendaylight.org:29418/aaa.git</developerConnection>
+      <tag>HEAD</tag>
+      <url>https://git.opendaylight.org/gerrit/gitweb?p=aaa.git;a=summary</url>
+  </scm>
+</project>
diff --git a/features/aaa-cert/src/main/features/features.xml b/features/aaa-cert/src/main/features/features.xml
new file mode 100644 (file)
index 0000000..f955ace
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2015 Inocybe Technology All rights reserved.
+
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
+-->
+<features name="odl-aaa-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+
+    <repository>mvn:org.opendaylight.mdsal/features-mdsal/{{VERSION}}/xml/features</repository>
+    <repository>mvn:org.opendaylight.aaa/features-aaa/{{VERSION}}/xml/features</repository>
+    <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin-li/{{VERSION}}/xml/features</repository>
+
+    <feature name='odl-aaa-cert' description='OpenDaylight :: AAA :: aaa opendaylight certificate Plugin'
+             version='${project.version}'>
+        <feature version='${controller.mdsal.version}'>odl-mdsal-broker</feature>
+        <feature version="${openflowplugin.version}">odl-openflowplugin-southbound-li</feature>
+
+        <bundle>mvn:org.bouncycastle/bcprov-jdk15on/{{VERSION}}</bundle>
+        <bundle>mvn:commons-codec/commons-codec/{{VERSION}}</bundle>
+        <configfile finalname="etc/opendaylight/karaf/08-aaa-cert-config.xml">mvn:org.opendaylight.aaa/aaa-cert/{{VERSION}}/xml/config</configfile>
+        <bundle>mvn:org.opendaylight.aaa/aaa-cert/{{VERSION}}</bundle>
+    </feature>
+
+</features>
\ No newline at end of file
diff --git a/features/aaa-cli/pom.xml b/features/aaa-cli/pom.xml
new file mode 100644 (file)
index 0000000..94443ae
--- /dev/null
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2015 Inocybe Technology All rights reserved.
+
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>features-parent</artifactId>
+        <version>1.7.0-SNAPSHOT</version>
+        <relativePath/>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.opendaylight.aaa</groupId>
+    <artifactId>features-aaa-cli</artifactId>
+    <version>0.4.0-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.opendaylight.aaa</groupId>
+                <artifactId>aaa-parent</artifactId>
+                <version>${project.version}</version>
+                <scope>import</scope>
+                <type>pom</type>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+  <dependencies>
+    <dependency>
+       <groupId>org.opendaylight.aaa</groupId>
+       <artifactId>features-aaa-cert</artifactId>
+       <version>${project.version}</version>
+       <classifier>features</classifier>
+       <type>xml</type>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.aaa</groupId>
+      <artifactId>aaa-cli</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-aether-provider</artifactId>
+      <version>3.0.5</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+    <scm>
+        <connection>scm:git:ssh://git.opendaylight.org:29418/aaa.git</connection>
+        <developerConnection>scm:git:ssh://git.opendaylight.org:29418/aaa.git</developerConnection>
+        <tag>HEAD</tag>
+        <url>https://git.opendaylight.org/gerrit/gitweb?p=aaa.git;a=summary</url>
+    </scm>
+</project>
diff --git a/features/aaa-cli/src/main/features/features.xml b/features/aaa-cli/src/main/features/features.xml
new file mode 100644 (file)
index 0000000..a350105
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2015 Inocybe Technology All rights reserved.
+
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
+-->
+<features name="odl-aaa-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+
+    <repository>mvn:org.opendaylight.aaa/features-aaa-cert/{{VERSION}}/xml/features</repository>
+
+    <feature name='odl-aaa-cli' description='OpenDaylight :: AAA :: aaa opendaylight command line'
+             version='${project.version}'>
+        <feature version="${project.version}">odl-aaa-cert</feature>
+        <bundle>mvn:org.opendaylight.aaa/aaa-cli/{{VERSION}}</bundle>
+    </feature>
+
+</features>
index fc679516ba85bc5368154cc75064b2d26e827508..63e4d39ed2fffac4ec0aab791b4d2a7f9498aac9 100644 (file)
@@ -15,5 +15,7 @@
     <module>api</module>
     <module>authn</module>
     <module>authz</module>
+    <module>aaa-cert</module>
+    <module>aaa-cli</module>
   </modules>
 </project>
diff --git a/pom.xml b/pom.xml
index b91d950d993260708c669728a1f00bf7fcff6d85..2bf9be63e94df362de01b296fac5f02d45b0f346 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -38,6 +38,8 @@
     <module>aaa-shiro</module>
     <module>aaa-shiro-act</module>
     <module>aaa-h2-store</module>
+    <module>aaa-cert</module>
+    <module>aaa-cli</module>
   </modules>
 
   <scm>