View Javadoc

1   /**
2    * Copyright (c) 2012-2013, JCabi.com
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met: 1) Redistributions of source code must retain the above
8    * copyright notice, this list of conditions and the following
9    * disclaimer. 2) Redistributions in binary form must reproduce the above
10   * copyright notice, this list of conditions and the following
11   * disclaimer in the documentation and/or other materials provided
12   * with the distribution. 3) Neither the name of the jcabi.com nor
13   * the names of its contributors may be used to endorse or promote
14   * products derived from this software without specific prior written
15   * permission.
16   *
17   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
19   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21   * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28   * OF THE POSSIBILITY OF SUCH DAMAGE.
29   */
30  package com.jcabi.ssl.maven.plugin;
31  
32  import com.jcabi.aspects.Immutable;
33  import com.jcabi.aspects.Loggable;
34  import com.jcabi.log.Logger;
35  import com.jcabi.log.VerboseProcess;
36  import java.io.File;
37  import java.io.IOException;
38  import java.io.OutputStreamWriter;
39  import java.io.PrintWriter;
40  import java.util.ArrayList;
41  import java.util.List;
42  import lombok.EqualsAndHashCode;
43  import lombok.ToString;
44  import org.apache.commons.io.FileUtils;
45  
46  /**
47   * Keytool abstraction.
48   *
49   * @author Yegor Bugayenko (yegor@tpc2.com)
50   * @version $Id$
51   * @since 0.5
52   */
53  @Immutable
54  @ToString
55  @EqualsAndHashCode(of = { "keystore", "password" })
56  final class Keytool {
57  
58      /**
59       * Keystore location.
60       */
61      private final transient String keystore;
62  
63      /**
64       * Keystore password.
65       */
66      private final transient String password;
67  
68      /**
69       * Public ctor.
70       * @param store The location of keystore
71       * @param pwd The password
72       */
73      public Keytool(final File store, final String pwd) {
74          this.keystore = store.getAbsolutePath();
75          this.password = pwd;
76      }
77  
78      /**
79       * List content of the keystore.
80       * @return The content of it
81       * @throws IOException If fails
82       */
83      @Loggable(Loggable.DEBUG)
84      public String list() throws IOException {
85          return new VerboseProcess(this.proc("-list", "-v")).stdout();
86      }
87  
88      /**
89       * Generate key.
90       * @throws IOException If fails
91       */
92      @Loggable(Loggable.DEBUG)
93      public void genkey() throws IOException {
94          final Process proc = this.proc(
95              "-genkeypair",
96              "-alias",
97              "localhost",
98              "-keyalg",
99              "RSA",
100             "-keysize",
101             "2048",
102             "-keypass",
103             this.password
104         ).start();
105         final PrintWriter writer = new PrintWriter(
106             new OutputStreamWriter(proc.getOutputStream())
107         );
108         writer.print("localhost\n");
109         writer.print("ACME Co.\n");
110         writer.print("software developers\n");
111         writer.print("San Francisco\n");
112         writer.print("California\n");
113         writer.print("US\n");
114         writer.print("yes\n");
115         writer.close();
116         new VerboseProcess(proc).stdout();
117         Logger.info(
118             this,
119             "Keystore created in '%s' (%s)",
120             this.keystore,
121             FileUtils.byteCountToDisplaySize(this.keystore.length())
122         );
123     }
124 
125     /**
126      * Import certificate into this store.
127      * @param file The file to import
128      * @param pwd The password there
129      * @throws IOException If fails
130      */
131     @Loggable(Loggable.DEBUG)
132     public void imprt(final File file, final String pwd) throws IOException {
133         new VerboseProcess(
134             this.proc(
135                 "-importkeystore",
136                 "-srckeystore",
137                 file.getAbsolutePath(),
138                 "-srcstorepass",
139                 pwd,
140                 "-destkeystore",
141                 this.keystore,
142                 "-deststorepass",
143                 this.password
144             )
145         ).stdout();
146     }
147 
148     /**
149      * Create process builder.
150      * @param args Arguments
151      * @return Process just created and started
152      * @throws IOException If fails
153      */
154     private ProcessBuilder proc(final String... args) throws IOException {
155         final List<String> cmds = new ArrayList<String>(args.length + 1);
156         cmds.add(
157             String.format(
158                 "%s/bin/keytool",
159                 System.getProperty("java.home")
160             )
161         );
162         for (String arg : args) {
163             cmds.add(arg);
164         }
165         cmds.add("-storetype");
166         cmds.add("jks");
167         cmds.add("-noprompt");
168         cmds.add("-storepass");
169         cmds.add(this.password);
170         cmds.add("-keystore");
171         cmds.add(this.keystore);
172         return new ProcessBuilder(cmds);
173     }
174 
175 }