You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

GenerateKey.java 11 kB

9 years ago
9 years ago
9 years ago
11 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. package org.apache.tools.ant.taskdefs;
  19. import java.util.Collections;
  20. import java.util.Enumeration;
  21. import java.util.List;
  22. import java.util.Vector;
  23. import java.util.stream.Collectors;
  24. import org.apache.tools.ant.BuildException;
  25. import org.apache.tools.ant.Task;
  26. import org.apache.tools.ant.types.Commandline;
  27. import org.apache.tools.ant.util.JavaEnvUtils;
  28. /**
  29. * Generates a key in a keystore.
  30. *
  31. * @since Ant 1.2
  32. *
  33. * @ant.task name="genkey" category="java"
  34. */
  35. public class GenerateKey extends Task {
  36. /**
  37. * A DistinguishedName parameter.
  38. * This is a nested element in a dname nested element.
  39. */
  40. public static class DnameParam {
  41. private String name;
  42. private String value;
  43. /**
  44. * Set the name attribute.
  45. * @param name a <code>String</code> value
  46. */
  47. public void setName(String name) {
  48. this.name = name;
  49. }
  50. /**
  51. * Get the name attribute.
  52. * @return the name.
  53. */
  54. public String getName() {
  55. return name;
  56. }
  57. /**
  58. * Set the value attribute.
  59. * @param value a <code>String</code> value
  60. */
  61. public void setValue(String value) {
  62. this.value = value;
  63. }
  64. /**
  65. * Get the value attribute.
  66. * @return the value.
  67. */
  68. public String getValue() {
  69. return value;
  70. }
  71. public boolean isComplete() {
  72. return name != null && value != null;
  73. }
  74. }
  75. /**
  76. * A class corresponding to the dname nested element.
  77. */
  78. public static class DistinguishedName {
  79. private List<DnameParam> params = new Vector<>();
  80. /**
  81. * Create a param nested element.
  82. * @return a DnameParam object to be configured.
  83. */
  84. public Object createParam() {
  85. DnameParam param = new DnameParam();
  86. params.add(param);
  87. return param;
  88. }
  89. /**
  90. * Get the nested parameters.
  91. * @return an enumeration of the nested parameters.
  92. */
  93. public Enumeration<DnameParam> getParams() {
  94. return Collections.enumeration(params);
  95. }
  96. /**
  97. * Generate a string rep of this distinguished name.
  98. * The format is each of the parameters (name = value)
  99. * separated by ','.
  100. * This is used on the command line.
  101. * @return a string rep of this name
  102. */
  103. @Override
  104. public String toString() {
  105. return params.stream().map(p -> encode(p.getName()) + "=" + encode(p.getValue()))
  106. .collect(Collectors.joining(", "));
  107. }
  108. /**
  109. * Encode a name or value.
  110. * The encoded result is the same as the input string
  111. * except that each ',' is replaced by a '\,'.
  112. * @param string the value to be encoded
  113. * @return the encoded value.
  114. */
  115. public String encode(final String string) {
  116. return String.join("\\,", string.split(","));
  117. }
  118. }
  119. // CheckStyle:VisibilityModifier OFF - bc
  120. /**
  121. * The alias of signer.
  122. */
  123. protected String alias;
  124. /**
  125. * The name of keystore file.
  126. */
  127. protected String keystore;
  128. protected String storepass;
  129. protected String storetype;
  130. protected String keypass;
  131. protected String sigalg;
  132. protected String keyalg;
  133. protected String saname;
  134. protected String dname;
  135. protected DistinguishedName expandedDname;
  136. protected int keysize;
  137. protected int validity;
  138. protected boolean verbose;
  139. // CheckStyle:VisibilityModifier ON
  140. /**
  141. * Distinguished name list.
  142. *
  143. * @return Distinguished name container.
  144. * @throws BuildException If specified more than once or dname
  145. * attribute is used.
  146. */
  147. public DistinguishedName createDname() throws BuildException {
  148. if (null != expandedDname) {
  149. throw new BuildException("DName sub-element can only be specified once.");
  150. }
  151. if (null != dname) {
  152. throw new BuildException(
  153. "It is not possible to specify dname both as attribute and element.");
  154. }
  155. expandedDname = new DistinguishedName();
  156. return expandedDname;
  157. }
  158. /**
  159. * The distinguished name for entity.
  160. *
  161. * @param dname distinguished name
  162. */
  163. public void setDname(final String dname) {
  164. if (null != expandedDname) {
  165. throw new BuildException(
  166. "It is not possible to specify dname both as attribute and element.");
  167. }
  168. this.dname = dname;
  169. }
  170. /**
  171. * The subject alternative name for entity.
  172. *
  173. * @param saname subject alternative name
  174. * @since Ant 1.9.14
  175. */
  176. public void setSaname(final String saname) {
  177. if (JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_1_7)) {
  178. this.saname = saname;
  179. } else {
  180. log("The SubjectAlternativeName extension is not available for "
  181. +"the Java Version being used.");
  182. }
  183. }
  184. /**
  185. * The alias to add under.
  186. *
  187. * @param alias alias to add under
  188. */
  189. public void setAlias(final String alias) {
  190. this.alias = alias;
  191. }
  192. /**
  193. * Keystore location.
  194. *
  195. * @param keystore location
  196. */
  197. public void setKeystore(final String keystore) {
  198. this.keystore = keystore;
  199. }
  200. /**
  201. * Password for keystore integrity.
  202. * Must be at least 6 characters long.
  203. * @param storepass password
  204. */
  205. public void setStorepass(final String storepass) {
  206. this.storepass = storepass;
  207. }
  208. /**
  209. * Keystore type.
  210. *
  211. * @param storetype type
  212. */
  213. public void setStoretype(final String storetype) {
  214. this.storetype = storetype;
  215. }
  216. /**
  217. * Password for private key (if different).
  218. *
  219. * @param keypass password
  220. */
  221. public void setKeypass(final String keypass) {
  222. this.keypass = keypass;
  223. }
  224. /**
  225. * The algorithm to use in signing.
  226. *
  227. * @param sigalg algorithm
  228. */
  229. public void setSigalg(final String sigalg) {
  230. this.sigalg = sigalg;
  231. }
  232. /**
  233. * The method to use when generating name-value pair.
  234. * @param keyalg algorithm
  235. */
  236. public void setKeyalg(final String keyalg) {
  237. this.keyalg = keyalg;
  238. }
  239. /**
  240. * Indicates the size of key generated.
  241. *
  242. * @param keysize size of key
  243. * @throws BuildException If not an Integer
  244. * @todo Could convert this to a plain Integer setter.
  245. */
  246. public void setKeysize(final String keysize) throws BuildException {
  247. try {
  248. this.keysize = Integer.parseInt(keysize);
  249. } catch (final NumberFormatException nfe) {
  250. throw new BuildException("KeySize attribute should be a integer");
  251. }
  252. }
  253. /**
  254. * Indicates how many days certificate is valid.
  255. *
  256. * @param validity days valid
  257. * @throws BuildException If not an Integer
  258. */
  259. public void setValidity(final String validity) throws BuildException {
  260. try {
  261. this.validity = Integer.parseInt(validity);
  262. } catch (final NumberFormatException nfe) {
  263. throw new BuildException("Validity attribute should be a integer");
  264. }
  265. }
  266. /**
  267. * If true, verbose output when signing.
  268. * @param verbose verbose or not
  269. */
  270. public void setVerbose(final boolean verbose) {
  271. this.verbose = verbose;
  272. }
  273. /**
  274. * Execute the task.
  275. * @throws BuildException on error
  276. */
  277. @Override
  278. public void execute() throws BuildException {
  279. if (null == alias) {
  280. throw new BuildException("alias attribute must be set");
  281. }
  282. if (null == storepass) {
  283. throw new BuildException("storepass attribute must be set");
  284. }
  285. if (null == dname && null == expandedDname) {
  286. throw new BuildException("dname must be set");
  287. }
  288. final StringBuilder sb = new StringBuilder();
  289. sb.append("-genkey ");
  290. if (verbose) {
  291. sb.append("-v ");
  292. }
  293. sb.append("-alias \"");
  294. sb.append(alias);
  295. sb.append("\" ");
  296. if (null != dname) {
  297. sb.append("-dname \"");
  298. sb.append(dname);
  299. sb.append("\" ");
  300. }
  301. if (null != expandedDname) {
  302. sb.append("-dname \"");
  303. sb.append(expandedDname);
  304. sb.append("\" ");
  305. }
  306. if (null != keystore) {
  307. sb.append("-keystore \"");
  308. sb.append(keystore);
  309. sb.append("\" ");
  310. }
  311. if (null != storepass) {
  312. sb.append("-storepass \"");
  313. sb.append(storepass);
  314. sb.append("\" ");
  315. }
  316. if (null != storetype) {
  317. sb.append("-storetype \"");
  318. sb.append(storetype);
  319. sb.append("\" ");
  320. }
  321. sb.append("-keypass \"");
  322. if (null != keypass) {
  323. sb.append(keypass);
  324. } else {
  325. sb.append(storepass);
  326. }
  327. sb.append("\" ");
  328. if (null != sigalg) {
  329. sb.append("-sigalg \"");
  330. sb.append(sigalg);
  331. sb.append("\" ");
  332. }
  333. if (null != keyalg) {
  334. sb.append("-keyalg \"");
  335. sb.append(keyalg);
  336. sb.append("\" ");
  337. }
  338. if (0 < keysize) {
  339. sb.append("-keysize \"");
  340. sb.append(keysize);
  341. sb.append("\" ");
  342. }
  343. if (0 < validity) {
  344. sb.append("-validity \"");
  345. sb.append(validity);
  346. sb.append("\" ");
  347. }
  348. if (null != saname) {
  349. sb.append("-ext ");
  350. sb.append("\"san=");
  351. sb.append(saname);
  352. sb.append("\" ");
  353. }
  354. log("Generating Key for " + alias);
  355. final ExecTask cmd = new ExecTask(this);
  356. cmd.setExecutable(JavaEnvUtils.getJdkExecutable("keytool"));
  357. Commandline.Argument arg = cmd.createArg();
  358. arg.setLine(sb.toString());
  359. cmd.setFailonerror(true);
  360. cmd.setTaskName(getTaskName());
  361. cmd.execute();
  362. }
  363. }