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
9 package org.opendaylight.netconf.sal.connect.netconf.auth;
11 import com.google.common.base.Strings;
12 import java.io.IOException;
13 import java.io.StringReader;
14 import java.security.KeyPair;
15 import java.util.Optional;
16 import org.apache.sshd.ClientSession;
17 import org.apache.sshd.client.future.AuthFuture;
18 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
19 import org.opendaylight.aaa.encrypt.PKIUtil;
20 import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
21 import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfKeystoreAdapter;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.keystore.entry.KeyCredential;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
26 public class DatastoreBackedPublicKeyAuth extends AuthenticationHandler {
28 private static final Logger LOG = LoggerFactory.getLogger(DatastoreBackedPublicKeyAuth.class);
30 private final String username;
31 private final String pairId;
32 private final NetconfKeystoreAdapter keystoreAdapter;
33 private final AAAEncryptionService encryptionService;
35 private Optional<KeyPair> keyPair = Optional.empty();
37 public DatastoreBackedPublicKeyAuth(final String username, final String pairId,
38 final NetconfKeystoreAdapter keystoreAdapter,
39 final AAAEncryptionService encryptionService) {
40 this.username = username;
42 this.keystoreAdapter = keystoreAdapter;
43 this.encryptionService = encryptionService;
45 // try to immediately retrieve the pair from the adapter
50 public String getUsername() {
55 public AuthFuture authenticate(ClientSession session) throws IOException {
56 // if we have keypair set the identity, otherwise retry the retrieval from the adapter
57 // if successful set the identity.
58 if (keyPair.isPresent() || tryToSetKeyPair()) {
59 session.addPublicKeyIdentity(keyPair.get());
61 return session.auth();
64 private boolean tryToSetKeyPair() {
65 LOG.debug("Trying to retrieve keypair for: {}", pairId);
66 final Optional<KeyCredential> keypairOptional = keystoreAdapter.getKeypairFromId(pairId);
68 if (keypairOptional.isPresent()) {
69 final KeyCredential dsKeypair = keypairOptional.get();
70 final String passPhrase = Strings.isNullOrEmpty(dsKeypair.getPassphrase()) ? "" : dsKeypair.getPassphrase();
73 this.keyPair = Optional.of(
74 new PKIUtil().decodePrivateKey(
75 new StringReader(encryptionService.decrypt(dsKeypair.getPrivateKey())),
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);