2 * Copyright © 2019 FRINX s.r.o. 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.test.tool;
10 import java.security.GeneralSecurityException;
11 import java.security.KeyPair;
12 import java.security.KeyPairGenerator;
13 import java.security.spec.AlgorithmParameterSpec;
14 import java.util.Collections;
15 import org.apache.sshd.common.cipher.ECCurves;
16 import org.apache.sshd.common.config.keys.KeyUtils;
17 import org.apache.sshd.common.keyprovider.KeyPairProvider;
18 import org.apache.sshd.common.session.SessionContext;
19 import org.apache.sshd.common.util.security.SecurityUtils;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
24 * Key provider that allows to create exactly one key-pair in memory (key-pair is not persisted in memory).
25 * If the key-pair has already been generated, the existing one is used.
27 public class VirtualKeyPairProvider implements KeyPairProvider {
28 private static final Logger LOG = LoggerFactory.getLogger(VirtualKeyPairProvider.class);
30 private KeyPair generatedKeyPair;
31 private String algorithm = KeyUtils.RSA_ALGORITHM;
32 private AlgorithmParameterSpec keySpecification;
33 private Integer keySize;
36 * Creation of the key-provider with default settings - RSA algorithm with key length of 2048.
38 * @see VirtualKeyPairProvider#VirtualKeyPairProvider(String, AlgorithmParameterSpec, Integer)
40 VirtualKeyPairProvider() {
44 * Creation of the key-provider with explicitly defined algorithmic settings.
46 * @param algorithm Algorithm that is used for generation of a new key-pair. Currently supported algorithms:
47 * {@link KeyUtils#RSA_ALGORITHM}, {@link KeyUtils#DSS_ALGORITHM},
48 * {@link KeyUtils#EC_ALGORITHM}.
49 * @param keySpecification Algorithm-specific settings.
50 * @param keySize To be generated key length (must be adjusted against selected algorithm).
52 @SuppressWarnings("WeakerAccess")
53 VirtualKeyPairProvider(final String algorithm,
54 final AlgorithmParameterSpec keySpecification,
55 final Integer keySize) {
56 this.algorithm = algorithm;
57 this.keySpecification = keySpecification;
58 this.keySize = keySize;
62 public synchronized Iterable<KeyPair> loadKeys(final SessionContext session) {
63 if (generatedKeyPair == null) {
65 generatedKeyPair = generateKeyPair();
66 } catch (GeneralSecurityException e) {
67 LOG.error("Cannot generate key with algorithm '{}', key specification '{}', and key size '{}'.",
68 algorithm, keySpecification, keySize, e);
69 throw new IllegalArgumentException("An error occurred during generation of a new ke pair.", e);
72 return Collections.singleton(generatedKeyPair);
76 * Generating of the new key-pair using specified parameters - algorithm, key length, and key specification.
78 * @return Generated key-pair.
79 * @throws GeneralSecurityException If the generation process fails because of the wrong input parameters.
81 private KeyPair generateKeyPair() throws GeneralSecurityException {
82 final KeyPairGenerator generator = SecurityUtils.getKeyPairGenerator(algorithm);
83 if (keySpecification != null) {
84 generator.initialize(keySpecification);
85 } else if (keySize != null) {
86 generator.initialize(keySize);
87 } else if (KeyUtils.EC_ALGORITHM.equals(algorithm)) {
88 int numCurves = ECCurves.SORTED_KEY_SIZE.size();
89 ECCurves curve = ECCurves.SORTED_KEY_SIZE.get(numCurves - 1);
90 generator.initialize(curve.getParameters());
92 return generator.generateKeyPair();