f9238e2e7f10d4663b8d6b75fc02e2330726e148
[netconf.git] / netconf / tools / netconf-testtool / src / main / java / org / opendaylight / netconf / test / tool / VirtualKeyPairProvider.java
1 /*
2  * Copyright © 2019 FRINX s.r.o. All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.netconf.test.tool;
10
11 import java.security.GeneralSecurityException;
12 import java.security.KeyPair;
13 import java.security.KeyPairGenerator;
14 import java.security.spec.AlgorithmParameterSpec;
15 import java.util.Collections;
16 import java.util.Objects;
17 import org.apache.sshd.common.cipher.ECCurves;
18 import org.apache.sshd.common.config.keys.KeyUtils;
19 import org.apache.sshd.common.keyprovider.KeyPairProvider;
20 import org.apache.sshd.common.session.SessionContext;
21 import org.apache.sshd.common.util.security.SecurityUtils;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25 /**
26  * Key provider that allows to create exactly one key-pair in memory (key-pair is not persisted in memory).
27  * If the key-pair has already been generated, the existing one is used.
28  */
29 public class VirtualKeyPairProvider implements KeyPairProvider {
30
31     private static final Logger LOG = LoggerFactory.getLogger(VirtualKeyPairProvider.class);
32
33     private KeyPair generatedKeyPair;
34     private String algorithm = KeyUtils.RSA_ALGORITHM;
35     private AlgorithmParameterSpec keySpecification;
36     private Integer keySize;
37
38     /**
39      * Creation of the key-provider with default settings - RSA algorithm with key length of 2048.
40      *
41      * @see VirtualKeyPairProvider#VirtualKeyPairProvider(String, AlgorithmParameterSpec, Integer)
42      */
43     VirtualKeyPairProvider() {
44     }
45
46     /**
47      * Creation of the key-provider with explicitly defined algorithmic settings.
48      *
49      * @param algorithm        Algorithm that is used for generation of a new key-pair. Currently supported algorithms:
50      *                         {@link KeyUtils#RSA_ALGORITHM}, {@link KeyUtils#DSS_ALGORITHM},
51      *                         {@link KeyUtils#EC_ALGORITHM}.
52      * @param keySpecification Algorithm-specific settings.
53      * @param keySize          To be generated key length (must be adjusted against selected algorithm).
54      */
55     @SuppressWarnings({"unused", "WeakerAccess"})
56     VirtualKeyPairProvider(final String algorithm,
57                            final AlgorithmParameterSpec keySpecification,
58                            final Integer keySize) {
59         this.algorithm = algorithm;
60         this.keySpecification = keySpecification;
61         this.keySize = keySize;
62     }
63
64     @Override
65     public synchronized Iterable<KeyPair> loadKeys(final SessionContext session) {
66         if (Objects.isNull(generatedKeyPair)) {
67             try {
68                 generatedKeyPair = generateKeyPair();
69             } catch (GeneralSecurityException exception) {
70                 LOG.error("Cannot generate key with algorithm '{}', key specification '{}', and key size '{}'.",
71                         algorithm, keySpecification, keySize, exception);
72                 throw new IllegalArgumentException("An error occurred during generation of a new ke pair.", exception);
73             }
74         } else {
75             return Collections.singleton(generatedKeyPair);
76         }
77         return Collections.emptyList();
78     }
79
80     /**
81      * Generating of the new key-pair using specified parameters - algorithm, key length, and key specification.
82      *
83      * @return Generated key-pair.
84      * @throws GeneralSecurityException If the generation process fails because of the wrong input parameters.
85      */
86     private KeyPair generateKeyPair() throws GeneralSecurityException {
87         final KeyPairGenerator generator = SecurityUtils.getKeyPairGenerator(algorithm);
88         if (Objects.nonNull(keySpecification)) {
89             generator.initialize(keySpecification);
90         } else if (Objects.nonNull(keySize)) {
91             generator.initialize(keySize);
92         } else if (KeyUtils.EC_ALGORITHM.equals(algorithm)) {
93             int numCurves = ECCurves.SORTED_KEY_SIZE.size();
94             ECCurves curve = ECCurves.SORTED_KEY_SIZE.get(numCurves - 1);
95             generator.initialize(curve.getParameters());
96         }
97         return generator.generateKeyPair();
98     }
99 }