2 * Copyright (c) 2017 Cisco Systems, Inc. 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.netconf.auth;
10 import com.google.common.base.Strings;
11 import java.io.IOException;
12 import java.io.StringReader;
13 import java.security.KeyPair;
14 import java.util.Optional;
15 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
16 import org.opendaylight.aaa.encrypt.PKIUtil;
17 import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
18 import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfKeystoreAdapter;
19 import org.opendaylight.netconf.shaded.sshd.client.future.AuthFuture;
20 import org.opendaylight.netconf.shaded.sshd.client.session.ClientSession;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.keystore.entry.KeyCredential;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
25 public class DatastoreBackedPublicKeyAuth extends AuthenticationHandler {
27 private static final Logger LOG = LoggerFactory.getLogger(DatastoreBackedPublicKeyAuth.class);
29 private final String username;
30 private final String pairId;
31 private final NetconfKeystoreAdapter keystoreAdapter;
32 private final AAAEncryptionService encryptionService;
34 private Optional<KeyPair> keyPair = Optional.empty();
36 public DatastoreBackedPublicKeyAuth(final String username, final String pairId,
37 final NetconfKeystoreAdapter keystoreAdapter,
38 final AAAEncryptionService encryptionService) {
39 this.username = username;
41 this.keystoreAdapter = keystoreAdapter;
42 this.encryptionService = encryptionService;
44 // try to immediately retrieve the pair from the adapter
49 public String getUsername() {
54 public AuthFuture authenticate(final ClientSession session) throws IOException {
55 // if we have keypair set the identity, otherwise retry the retrieval from the adapter
56 // if successful set the identity.
57 if (keyPair.isPresent() || tryToSetKeyPair()) {
58 session.addPublicKeyIdentity(keyPair.get());
60 return session.auth();
63 private boolean tryToSetKeyPair() {
64 LOG.debug("Trying to retrieve keypair for: {}", pairId);
65 final Optional<KeyCredential> keypairOptional = keystoreAdapter.getKeypairFromId(pairId);
67 if (keypairOptional.isPresent()) {
68 final KeyCredential dsKeypair = keypairOptional.get();
69 final String passPhrase = Strings.isNullOrEmpty(dsKeypair.getPassphrase()) ? "" : dsKeypair.getPassphrase();
72 this.keyPair = Optional.of(
73 new PKIUtil().decodePrivateKey(
74 new StringReader(encryptionService.decrypt(
75 dsKeypair.getPrivateKey()).replaceAll("\\\\n", "\n")),
76 encryptionService.decrypt(passPhrase)));
77 } catch (IOException exception) {
78 LOG.warn("Unable to decode private key, id={}", pairId, exception);
83 LOG.debug("Unable to retrieve keypair for: {}", pairId);