1. /*
  2. * Copyright 2000,2002,2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. package org.apache.tools.ant.taskdefs;
  18. import java.util.Enumeration;
  19. import java.util.Vector;
  20. import org.apache.tools.ant.BuildException;
  21. import org.apache.tools.ant.Task;
  22. import org.apache.tools.ant.types.Commandline;
  23. import org.apache.tools.ant.util.JavaEnvUtils;
  24. /**
  25. * Generates a key in a keystore.
  26. *
  27. *
  28. * @since Ant 1.2
  29. *
  30. * @ant.task name="genkey" category="java"
  31. */
  32. public class GenerateKey extends Task {
  33. public static class DnameParam {
  34. private String name;
  35. private String value;
  36. public void setName(String name) {
  37. this.name = name;
  38. }
  39. public String getName() {
  40. return name;
  41. }
  42. public void setValue(String value) {
  43. this.value = value;
  44. }
  45. public String getValue() {
  46. return value;
  47. }
  48. }
  49. public static class DistinguishedName {
  50. private Vector params = new Vector();
  51. public Object createParam() {
  52. DnameParam param = new DnameParam();
  53. params.addElement(param);
  54. return param;
  55. }
  56. public Enumeration getParams() {
  57. return params.elements();
  58. }
  59. public String toString() {
  60. final int size = params.size();
  61. final StringBuffer sb = new StringBuffer();
  62. boolean firstPass = true;
  63. for (int i = 0; i < size; i++) {
  64. if (!firstPass) {
  65. sb.append(" ,");
  66. }
  67. firstPass = false;
  68. final DnameParam param = (DnameParam) params.elementAt(i);
  69. sb.append(encode(param.getName()));
  70. sb.append('=');
  71. sb.append(encode(param.getValue()));
  72. }
  73. return sb.toString();
  74. }
  75. public String encode(final String string) {
  76. int end = string.indexOf(',');
  77. if (-1 == end) {
  78. return string;
  79. }
  80. final StringBuffer sb = new StringBuffer();
  81. int start = 0;
  82. while (-1 != end) {
  83. sb.append(string.substring(start, end));
  84. sb.append("\\,");
  85. start = end + 1;
  86. end = string.indexOf(',', start);
  87. }
  88. sb.append(string.substring(start));
  89. return sb.toString();
  90. }
  91. }
  92. /**
  93. * The alias of signer.
  94. */
  95. protected String alias;
  96. /**
  97. * The name of keystore file.
  98. */
  99. protected String keystore;
  100. protected String storepass;
  101. protected String storetype;
  102. protected String keypass;
  103. protected String sigalg;
  104. protected String keyalg;
  105. protected String dname;
  106. protected DistinguishedName expandedDname;
  107. protected int keysize;
  108. protected int validity;
  109. protected boolean verbose;
  110. /**
  111. * Distinguished name list.
  112. *
  113. * @return Distinguished name container.
  114. * @throws BuildException If specified more than once or dname
  115. * attribute is used.
  116. */
  117. public DistinguishedName createDname() throws BuildException {
  118. if (null != expandedDname) {
  119. throw new BuildException("DName sub-element can only be "
  120. + "specified once.");
  121. }
  122. if (null != dname) {
  123. throw new BuildException("It is not possible to specify dname "
  124. + " both as attribute and element.");
  125. }
  126. expandedDname = new DistinguishedName();
  127. return expandedDname;
  128. }
  129. /**
  130. * The distinguished name for entity.
  131. *
  132. * @param dname distinguished name
  133. */
  134. public void setDname(final String dname) {
  135. if (null != expandedDname) {
  136. throw new BuildException("It is not possible to specify dname "
  137. + " both as attribute and element.");
  138. }
  139. this.dname = dname;
  140. }
  141. /**
  142. * The alias to add under.
  143. *
  144. * @param alias alias to add under
  145. */
  146. public void setAlias(final String alias) {
  147. this.alias = alias;
  148. }
  149. /**
  150. * Keystore location.
  151. *
  152. * @param keystore location
  153. */
  154. public void setKeystore(final String keystore) {
  155. this.keystore = keystore;
  156. }
  157. /**
  158. * Password for keystore integrity.
  159. * Must be at least 6 characters long.
  160. * @param storepass password
  161. */
  162. public void setStorepass(final String storepass) {
  163. this.storepass = storepass;
  164. }
  165. /**
  166. * Keystore type.
  167. *
  168. * @param storetype type
  169. */
  170. public void setStoretype(final String storetype) {
  171. this.storetype = storetype;
  172. }
  173. /**
  174. * Password for private key (if different).
  175. *
  176. * @param keypass password
  177. */
  178. public void setKeypass(final String keypass) {
  179. this.keypass = keypass;
  180. }
  181. /**
  182. * The algorithm to use in signing.
  183. *
  184. * @param sigalg algorithm
  185. */
  186. public void setSigalg(final String sigalg) {
  187. this.sigalg = sigalg;
  188. }
  189. /**
  190. * The method to use when generating name-value pair.
  191. * @param keyalg algorithm
  192. */
  193. public void setKeyalg(final String keyalg) {
  194. this.keyalg = keyalg;
  195. }
  196. /**
  197. * Indicates the size of key generated.
  198. *
  199. * @param keysize size of key
  200. * @throws BuildException If not an Integer
  201. * @todo Could convert this to a plain Integer setter.
  202. */
  203. public void setKeysize(final String keysize) throws BuildException {
  204. try {
  205. this.keysize = Integer.parseInt(keysize);
  206. } catch (final NumberFormatException nfe) {
  207. throw new BuildException("KeySize attribute should be a integer");
  208. }
  209. }
  210. /**
  211. * Indicates how many days certificate is valid.
  212. *
  213. * @param validity days valid
  214. * @throws BuildException If not an Integer
  215. */
  216. public void setValidity(final String validity) throws BuildException {
  217. try {
  218. this.validity = Integer.parseInt(validity);
  219. } catch (final NumberFormatException nfe) {
  220. throw new BuildException("Validity attribute should be a integer");
  221. }
  222. }
  223. /**
  224. * If true, verbose output when signing.
  225. * @param verbose verbose or not
  226. */
  227. public void setVerbose(final boolean verbose) {
  228. this.verbose = verbose;
  229. }
  230. public void execute() throws BuildException {
  231. if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_1)) {
  232. throw new BuildException("The genkey task is only available on JDK"
  233. + " versions 1.2 or greater");
  234. }
  235. if (null == alias) {
  236. throw new BuildException("alias attribute must be set");
  237. }
  238. if (null == storepass) {
  239. throw new BuildException("storepass attribute must be set");
  240. }
  241. if (null == dname && null == expandedDname) {
  242. throw new BuildException("dname must be set");
  243. }
  244. final StringBuffer sb = new StringBuffer();
  245. sb.append("-genkey ");
  246. if (verbose) {
  247. sb.append("-v ");
  248. }
  249. sb.append("-alias \"");
  250. sb.append(alias);
  251. sb.append("\" ");
  252. if (null != dname) {
  253. sb.append("-dname \"");
  254. sb.append(dname);
  255. sb.append("\" ");
  256. }
  257. if (null != expandedDname) {
  258. sb.append("-dname \"");
  259. sb.append(expandedDname);
  260. sb.append("\" ");
  261. }
  262. if (null != keystore) {
  263. sb.append("-keystore \"");
  264. sb.append(keystore);
  265. sb.append("\" ");
  266. }
  267. if (null != storepass) {
  268. sb.append("-storepass \"");
  269. sb.append(storepass);
  270. sb.append("\" ");
  271. }
  272. if (null != storetype) {
  273. sb.append("-storetype \"");
  274. sb.append(storetype);
  275. sb.append("\" ");
  276. }
  277. sb.append("-keypass \"");
  278. if (null != keypass) {
  279. sb.append(keypass);
  280. } else {
  281. sb.append(storepass);
  282. }
  283. sb.append("\" ");
  284. if (null != sigalg) {
  285. sb.append("-sigalg \"");
  286. sb.append(sigalg);
  287. sb.append("\" ");
  288. }
  289. if (null != keyalg) {
  290. sb.append("-keyalg \"");
  291. sb.append(keyalg);
  292. sb.append("\" ");
  293. }
  294. if (0 < keysize) {
  295. sb.append("-keysize \"");
  296. sb.append(keysize);
  297. sb.append("\" ");
  298. }
  299. if (0 < validity) {
  300. sb.append("-validity \"");
  301. sb.append(validity);
  302. sb.append("\" ");
  303. }
  304. log("Generating Key for " + alias);
  305. final ExecTask cmd = (ExecTask) getProject().createTask("exec");
  306. cmd.setExecutable(JavaEnvUtils.getJdkExecutable("keytool"));
  307. Commandline.Argument arg = cmd.createArg();
  308. arg.setLine(sb.toString());
  309. cmd.setFailonerror(true);
  310. cmd.setTaskName(getTaskName());
  311. cmd.execute();
  312. }
  313. }