Merge "Removed `which` dependency, now using proper shell builtin."
[controller.git] / opendaylight / netconf / netconf-ssh / src / main / java / org / opendaylight / controller / netconf / ssh / authentication / PEMGenerator.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  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.controller.netconf.ssh.authentication;
10
11 import com.google.common.annotations.VisibleForTesting;
12 import java.io.FileInputStream;
13 import java.security.NoSuchAlgorithmException;
14 import org.apache.commons.io.FileUtils;
15 import org.apache.commons.io.IOUtils;
16 import org.bouncycastle.openssl.PEMWriter;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
19
20 import java.io.File;
21 import java.io.IOException;
22 import java.io.StringWriter;
23 import java.security.Key;
24 import java.security.KeyPair;
25 import java.security.KeyPairGenerator;
26 import java.security.SecureRandom;
27
28 public class PEMGenerator {
29     private static final Logger logger = LoggerFactory.getLogger(PEMGenerator.class);
30     private static final int KEY_SIZE = 4096;
31
32
33     public static String readOrGeneratePK(File privateKeyFile) throws IOException {
34         if (privateKeyFile.exists() == false) {
35             // generate & save to file
36             try {
37                 return generateTo(privateKeyFile);
38             } catch (Exception e) {
39                 logger.error("Exception occurred while generating PEM string to {}", privateKeyFile, e);
40                 throw new IllegalStateException("Error generating RSA key from file " + privateKeyFile);
41             }
42         } else {
43             // read from file
44             try (FileInputStream fis = new FileInputStream(privateKeyFile)) {
45                 return IOUtils.toString(fis);
46             } catch (final IOException e) {
47                 logger.error("Error reading RSA key from file {}", privateKeyFile, e);
48                 throw new IOException("Error reading RSA key from file " + privateKeyFile, e);
49             }
50         }
51     }
52
53     /**
54      * Generate private key to a file and return its content as string.
55      *
56      * @param privateFile path where private key should be generated
57      * @return String representation of private key
58      * @throws IOException
59      * @throws NoSuchAlgorithmException
60      */
61     @VisibleForTesting
62     public static String generateTo(File privateFile) throws IOException, NoSuchAlgorithmException {
63         logger.info("Generating private key to {}", privateFile.getAbsolutePath());
64         String privatePEM = generate();
65         FileUtils.write(privateFile, privatePEM);
66         return privatePEM;
67     }
68
69     @VisibleForTesting
70     public static String generate() throws NoSuchAlgorithmException, IOException {
71         KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
72         SecureRandom sr = new SecureRandom();
73         keyGen.initialize(KEY_SIZE, sr);
74         KeyPair keypair = keyGen.generateKeyPair();
75         return toString(keypair.getPrivate());
76     }
77
78     /**
79      * Get string representation of a key.
80      */
81     private static String toString(Key key) throws IOException {
82         try (StringWriter writer = new StringWriter()) {
83             try (PEMWriter pemWriter = new PEMWriter(writer)) {
84                 pemWriter.writeObject(key);
85             }
86             return writer.toString();
87         }
88     }
89
90 }