2 * Copyright (c) 2019 Pantheon Technologies, s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.netconf.sal.connect.util;
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static java.util.Objects.requireNonNull;
13 import com.google.common.collect.Sets;
14 import io.netty.handler.ssl.SslHandler;
15 import java.io.IOException;
16 import java.security.GeneralSecurityException;
17 import java.security.KeyStore;
18 import java.util.Collections;
20 import javax.net.ssl.KeyManagerFactory;
21 import javax.net.ssl.SSLContext;
22 import javax.net.ssl.SSLEngine;
23 import javax.net.ssl.TrustManagerFactory;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.opendaylight.netconf.client.SslHandlerFactory;
26 import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfKeystoreAdapter;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.protocol.Specification;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.protocol.specification.TlsCase;
30 public final class SslHandlerFactoryImpl implements SslHandlerFactory {
31 private final NetconfKeystoreAdapter keystoreAdapter;
32 private final @Nullable Specification specification;
34 public SslHandlerFactoryImpl(final NetconfKeystoreAdapter keystoreAdapter) {
35 this(keystoreAdapter, null);
38 public SslHandlerFactoryImpl(final NetconfKeystoreAdapter keystoreAdapter, final Specification specification) {
39 this.keystoreAdapter = requireNonNull(keystoreAdapter);
40 this.specification = specification;
44 public SslHandler createSslHandler() {
45 return createSslHandler(Collections.emptySet());
49 public SslHandler createSslHandler(Set<String> allowedKeys) {
51 final KeyStore keyStore = keystoreAdapter.getJavaKeyStore(allowedKeys);
53 final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
54 kmf.init(keyStore, "".toCharArray());
56 final TrustManagerFactory tmf =
57 TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
60 final SSLContext sslCtx = SSLContext.getInstance("TLS");
61 sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
62 final SSLEngine engine = sslCtx.createSSLEngine();
63 engine.setUseClientMode(true);
65 final String[] engineProtocols = engine.getSupportedProtocols();
66 final String[] enabledProtocols;
67 if (specification != null) {
68 checkArgument(specification instanceof TlsCase, "Cannot get TLS specification from: %s", specification);
70 final Set<String> protocols = Sets.newHashSet(engineProtocols);
71 protocols.removeAll(((TlsCase)specification).getTls().getExcludedVersions());
72 enabledProtocols = protocols.toArray(new String[0]);
74 enabledProtocols = engineProtocols;
77 engine.setEnabledProtocols(enabledProtocols);
78 engine.setEnabledCipherSuites(engine.getSupportedCipherSuites());
79 engine.setEnableSessionCreation(true);
80 return new SslHandler(engine);
81 } catch (GeneralSecurityException | IOException exc) {
82 throw new IllegalStateException(exc);