Produced by Araxis Merge on 9/25/2018 2:13:27 PM Central Daylight Time. See www.araxis.com for information about Merge. This report uses XHTML and CSS2, and is best viewed with a modern standards-compliant browser. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.
# | Location | File | Last Modified |
---|---|---|---|
1 | build 3.zip\build 3\MHLTH_YS_137_Source\JavaScript\resources\javaJDF-1.8.0\src\sun\security\tools\keytool | Main.java | Mon Jan 22 14:46:54 2018 UTC |
2 | build 3.zip\build 3\MHLTH_YS_137_Source\JavaScript\resources\javaJDF-1.8.0\src\sun\security\tools\keytool | Main.java | Wed Sep 12 17:55:14 2018 UTC |
Description | Between Files 1 and 2 |
|
---|---|---|
Text Blocks | Lines | |
Unchanged | 7 | 9076 |
Changed | 6 | 12 |
Inserted | 0 | 0 |
Removed | 0 | 0 |
Whitespace | |
---|---|
Character case | Differences in character case are significant |
Line endings | Differences in line endings (CR and LF characters) are ignored |
CR/LF characters | Not shown in the comparison detail |
No regular expressions were active.
1 | /* | |
2 | * Copyrig ht (c) 199 7, 2017, O racle and/ or its aff iliates. A ll rights reserved. | |
3 | * DO NOT ALTER OR R EMOVE COPY RIGHT NOTI CES OR THI S FILE HEA DER. | |
4 | * | |
5 | * This co de is free software; you can r edistribut e it and/o r modify i t | |
6 | * under t he terms o f the GNU General Pu blic Licen se version 2 only, a s | |
7 | * publish ed by the Free Softw are Founda tion. Ora cle design ates this | |
8 | * particu lar file a s subject to the "Cl asspath" e xception a s provided | |
9 | * by Orac le in the LICENSE fi le that ac companied this code. | |
10 | * | |
11 | * This co de is dist ributed in the hope that it wi ll be usef ul, but WI THOUT | |
12 | * ANY WAR RANTY; wit hout even the implie d warranty of MERCHA NTABILITY or | |
13 | * FITNESS FOR A PAR TICULAR PU RPOSE. Se e the GNU General Pu blic Licen se | |
14 | * version 2 for mor e details (a copy is included in the LIC ENSE file that | |
15 | * accompa nied this code). | |
16 | * | |
17 | * You sho uld have r eceived a copy of th e GNU Gene ral Public License v ersion | |
18 | * 2 along with this work; if not, write to the Fr ee Softwar e Foundati on, | |
19 | * Inc., 5 1 Franklin St, Fifth Floor, Bo ston, MA 0 2110-1301 USA. | |
20 | * | |
21 | * Please contact Or acle, 500 Oracle Par kway, Redw ood Shores , CA 94065 USA | |
22 | * or visi t www.orac le.com if you need a dditional informatio n or have any | |
23 | * questio ns. | |
24 | */ | |
25 | ||
26 | package su n.security .tools.key tool; | |
27 | ||
28 | import jav a.io.*; | |
29 | import jav a.nio.file .Files; | |
30 | import jav a.nio.file .Paths; | |
31 | import jav a.security .CodeSigne r; | |
32 | import jav a.security .CryptoPri mitive; | |
33 | import jav a.security .KeyStore; | |
34 | import jav a.security .KeyStoreE xception; | |
35 | import jav a.security .MessageDi gest; | |
36 | import jav a.security .Key; | |
37 | import jav a.security .PublicKey ; | |
38 | import jav a.security .PrivateKe y; | |
39 | import jav a.security .Security; | |
40 | import jav a.security .Signature ; | |
41 | import jav a.security .Timestamp ; | |
42 | import jav a.security .Unrecover ableEntryE xception; | |
43 | import jav a.security .Unrecover ableKeyExc eption; | |
44 | import jav a.security .NoSuchAlg orithmExce ption; | |
45 | import jav a.security .Principal ; | |
46 | import jav a.security .Provider; | |
47 | import jav a.security .cert.Cert ificate; | |
48 | import jav a.security .cert.Cert ificateFac tory; | |
49 | import jav a.security .cert.Cert StoreExcep tion; | |
50 | import jav a.security .cert.CRL; | |
51 | import jav a.security .cert.X509 Certificat e; | |
52 | import jav a.security .cert.Cert ificateExc eption; | |
53 | import jav a.text.Col lator; | |
54 | import jav a.text.Mes sageFormat ; | |
55 | import jav a.util.*; | |
56 | import jav a.util.jar .JarEntry; | |
57 | import jav a.util.jar .JarFile; | |
58 | import jav a.lang.ref lect.Const ructor; | |
59 | import jav a.math.Big Integer; | |
60 | import jav a.net.URI; | |
61 | import jav a.net.URL; | |
62 | import jav a.net.URLC lassLoader ; | |
63 | import jav a.security .cert.Cert Store; | |
64 | ||
65 | import jav a.security .cert.X509 CRL; | |
66 | import jav a.security .cert.X509 CRLEntry; | |
67 | import jav a.security .cert.X509 CRLSelecto r; | |
68 | import jav ax.securit y.auth.x50 0.X500Prin cipal; | |
69 | import jav a.util.Bas e64; | |
70 | ||
71 | import sun .security. util.Disab ledAlgorit hmConstrai nts; | |
72 | import sun .security. util.KeyUt il; | |
73 | import sun .security. util.Objec tIdentifie r; | |
74 | import sun .security. pkcs10.PKC S10; | |
75 | import sun .security. pkcs10.PKC S10Attribu te; | |
76 | import sun .security. provider.X 509Factory ; | |
77 | import sun .security. provider.c ertpath.Ce rtStoreHel per; | |
78 | import sun .security. util.Passw ord; | |
79 | import sun .security. util.Secur ityProvide rConstants ; | |
80 | import jav ax.crypto. KeyGenerat or; | |
81 | import jav ax.crypto. SecretKey; | |
82 | import jav ax.crypto. SecretKeyF actory; | |
83 | import jav ax.crypto. spec.PBEKe ySpec; | |
84 | ||
85 | import sun .security. pkcs.PKCS9 Attribute; | |
86 | import sun .security. tools.KeyS toreUtil; | |
87 | import sun .security. tools.Path List; | |
88 | import sun .security. util.DerVa lue; | |
89 | import sun .security. util.Pem; | |
90 | import sun .security. x509.*; | |
91 | ||
92 | import sta tic java.s ecurity.Ke yStore.*; | |
93 | import sta tic sun.se curity.too ls.keytool .Main.Comm and.*; | |
94 | import sta tic sun.se curity.too ls.keytool .Main.Opti on.*; | |
95 | ||
96 | /** | |
97 | * This to ol manages keystores . | |
98 | * | |
99 | * @author Jan Luehe | |
100 | * | |
101 | * | |
102 | * @see ja va.securit y.KeyStore | |
103 | * @see su n.security .provider. KeyProtect or | |
104 | * @see su n.security .provider. JavaKeySto re | |
105 | * | |
106 | * @since 1.2 | |
107 | */ | |
108 | public fin al class M ain { | |
109 | ||
110 | privat e static f inal byte[ ] CRLF = n ew byte[] {'\r', '\n '}; | |
111 | ||
112 | privat e boolean debug = fa lse; | |
113 | privat e Command command = null; | |
114 | privat e String s igAlgName = null; | |
115 | privat e String k eyAlgName = null; | |
116 | privat e boolean verbose = false; | |
117 | privat e int keys ize = -1; | |
118 | privat e boolean rfc = fals e; | |
119 | privat e long val idity = (l ong)90; | |
120 | privat e String a lias = nul l; | |
121 | privat e String d name = nul l; | |
122 | privat e String d est = null ; | |
123 | privat e String f ilename = null; | |
124 | privat e String i nfilename = null; | |
125 | privat e String o utfilename = null; | |
126 | privat e String s rcksfname = null; | |
127 | privat e boolean systemLine Endings = false; | |
128 | ||
129 | // Use r-specifie d provider s are adde d before a ny command is called . | |
130 | // How ever, they are not r emoved bef ore the en d of the m ain() meth od. | |
131 | // If you're cal ling KeyTo ol.main() directly i n your own Java prog ram, | |
132 | // ple ase progra mtically a dd any pro viders you need and do not spe cify | |
133 | // the m through the comman d line. | |
134 | ||
135 | privat e Set<Pair <String, String>> p roviders = null; | |
136 | privat e String s toretype = null; | |
137 | privat e String s rcProvider Name = nul l; | |
138 | privat e String p roviderNam e = null; | |
139 | privat e String p athlist = null; | |
140 | privat e char[] s torePass = null; | |
141 | privat e char[] s torePassNe w = null; | |
142 | privat e char[] k eyPass = n ull; | |
143 | privat e char[] k eyPassNew = null; | |
144 | privat e char[] n ewPass = n ull; | |
145 | privat e char[] d estKeyPass = null; | |
146 | privat e char[] s rckeyPass = null; | |
147 | privat e String k sfname = n ull; | |
148 | privat e File ksf ile = null ; | |
149 | privat e InputStr eam ksStre am = null; // keysto re stream | |
150 | privat e String s slserver = null; | |
151 | privat e String j arfile = n ull; | |
152 | privat e KeyStore keyStore = null; | |
153 | privat e boolean token = fa lse; | |
154 | privat e boolean nullStream = false; | |
155 | privat e boolean kssave = f alse; | |
156 | privat e boolean noprompt = false; | |
157 | privat e boolean trustcacer ts = false ; | |
158 | privat e boolean nowarn = f alse; | |
159 | privat e boolean protectedP ath = fals e; | |
160 | privat e boolean srcprotect edPath = f alse; | |
161 | privat e Certific ateFactory cf = null ; | |
162 | privat e KeyStore caks = nu ll; // "ca certs" key store | |
163 | privat e char[] s rcstorePas s = null; | |
164 | privat e String s rcstoretyp e = null; | |
165 | privat e Set<char []> passwo rds = new HashSet<>( ); | |
166 | privat e String s tartDate = null; | |
167 | ||
168 | privat e List<Str ing> ids = new Array List<>(); // used in GENCRL | |
169 | privat e List<Str ing> v3ext = new Arr ayList<>() ; | |
170 | ||
171 | // In- place impo rtkeystore is specia l. | |
172 | // A b ackup is n eeded, and no need t o prompt f or deststo repass. | |
173 | privat e boolean inplaceImp ort = fals e; | |
174 | privat e String i nplaceBack upName = n ull; | |
175 | ||
176 | // War nings on w eak algori thms etc | |
177 | privat e List<Str ing> weakW arnings = new ArrayL ist<>(); | |
178 | ||
179 | privat e static f inal Disab ledAlgorit hmConstrai nts DISABL ED_CHECK = | |
180 | new Disa bledAlgori thmConstra ints( | |
181 | DisabledAl gorithmCon straints.P ROPERTY_CE RTPATH_DIS ABLED_ALGS ); | |
182 | ||
183 | privat e static f inal Set<C ryptoPrimi tive> SIG_ PRIMITIVE_ SET = Coll ections | |
184 | .unmodif iableSet(E numSet.of( CryptoPrim itive.SIGN ATURE)); | |
185 | ||
186 | enum C ommand { | |
187 | CE RTREQ("Gen erates.a.c ertificate .request", | |
188 | ALIAS, S IGALG, FIL EOUT, KEYP ASS, KEYST ORE, DNAME , | |
189 | STOREPAS S, STORETY PE, PROVID ERNAME, PR OVIDERCLAS S, | |
190 | PROVIDER ARG, PROVI DERPATH, S YSTEMLINEE NDINGS, V, PROTECTED ), | |
191 | CH ANGEALIAS( "Changes.a n.entry.s. alias", | |
192 | ALIAS, D ESTALIAS, KEYPASS, K EYSTORE, S TOREPASS, | |
193 | STORETYP E, PROVIDE RNAME, PRO VIDERCLASS , PROVIDER ARG, | |
194 | PROVIDER PATH, V, P ROTECTED), | |
195 | DE LETE("Dele tes.an.ent ry", | |
196 | ALIAS, K EYSTORE, S TOREPASS, STORETYPE, | |
197 | PROVIDER NAME, PROV IDERCLASS, PROVIDERA RG, | |
198 | PROVIDER PATH, V, P ROTECTED), | |
199 | EX PORTCERT(" Exports.ce rtificate" , | |
200 | RFC, ALI AS, FILEOU T, KEYSTOR E, STOREPA SS, | |
201 | STORETYP E, PROVIDE RNAME, PRO VIDERCLASS , PROVIDER ARG, | |
202 | PROVIDER PATH, V, P ROTECTED), | |
203 | GE NKEYPAIR(" Generates. a.key.pair ", | |
204 | ALIAS, K EYALG, KEY SIZE, SIGA LG, DESTAL IAS, DNAME , | |
205 | STARTDAT E, EXT, VA LIDITY, KE YPASS, KEY STORE, | |
206 | STOREPAS S, STORETY PE, PROVID ERNAME, PR OVIDERCLAS S, | |
207 | PROVIDER ARG, PROVI DERPATH, V , PROTECTE D), | |
208 | GENSECKEY( "Generates .a. PW .key", | |
209 | ALIAS, K EYPASS, KE YALG, KEYS IZE, KEYST ORE, | |
210 | STOREPAS S, STORETY PE, PROVID ERNAME, PR OVIDERCLAS S, | |
211 | PROVIDER ARG, PROVI DERPATH, V , PROTECTE D), | |
212 | GE NCERT("Gen erates.cer tificate.f rom.a.cert ificate.re quest", | |
213 | RFC, INF ILE, OUTFI LE, ALIAS, SIGALG, D NAME, | |
214 | STARTDAT E, EXT, VA LIDITY, KE YPASS, KEY STORE, | |
215 | STOREPAS S, STORETY PE, PROVID ERNAME, PR OVIDERCLAS S, | |
216 | PROVIDER ARG, PROVI DERPATH, V , PROTECTE D), | |
217 | IM PORTCERT(" Imports.a. certificat e.or.a.cer tificate.c hain", | |
218 | NOPROMPT , TRUSTCAC ERTS, PROT ECTED, ALI AS, FILEIN , | |
219 | KEYPASS, KEYSTORE, STOREPASS , STORETYP E, | |
220 | PROVIDER NAME, PROV IDERCLASS, PROVIDERA RG, | |
221 | PROVIDER PATH, V), | |
222 | IM PORTPASS(" Imports.a. password", | |
223 | ALIAS, K EYPASS, KE YALG, KEYS IZE, KEYST ORE, | |
224 | STOREPAS S, STORETY PE, PROVID ERNAME, PR OVIDERCLAS S, | |
225 | PROVIDER ARG, PROVI DERPATH, V , PROTECTE D), | |
226 | IM PORTKEYSTO RE("Import s.one.or.a ll.entries .from.anot her.keysto re", | |
227 | SRCKEYST ORE, DESTK EYSTORE, S RCSTORETYP E, | |
228 | DESTSTOR ETYPE, SRC STOREPASS, DESTSTORE PASS, | |
229 | SRCPROTE CTED, SRCP ROVIDERNAM E, DESTPRO VIDERNAME, | |
230 | SRCALIAS , DESTALIA S, SRCKEYP ASS, DESTK EYPASS, | |
231 | NOPROMPT , PROVIDER CLASS, PRO VIDERARG, PROVIDERPA TH, | |
232 | V), | |
233 | KE YPASSWD("C hanges.the .key.passw ord.of.an. entry", | |
234 | ALIAS, K EYPASS, NE W, KEYSTOR E, STOREPA SS, | |
235 | STORETYP E, PROVIDE RNAME, PRO VIDERCLASS , PROVIDER ARG, | |
236 | PROVIDER PATH, V), | |
237 | LI ST("Lists. entries.in .a.keystor e", | |
238 | RFC, ALI AS, KEYSTO RE, STOREP ASS, STORE TYPE, | |
239 | PROVIDER NAME, PROV IDERCLASS, PROVIDERA RG, | |
240 | PROVIDER PATH, V, P ROTECTED), | |
241 | PR INTCERT("P rints.the. content.of .a.certifi cate", | |
242 | RFC, FIL EIN, SSLSE RVER, JARF ILE, V), | |
243 | PR INTCERTREQ ("Prints.t he.content .of.a.cert ificate.re quest", | |
244 | FILEIN, V), | |
245 | PR INTCRL("Pr ints.the.c ontent.of. a.CRL.file ", | |
246 | FILEIN, V), | |
247 | ST OREPASSWD( "Changes.t he.store.p assword.of .a.keystor e", | |
248 | NEW, KEY STORE, STO REPASS, ST ORETYPE, P ROVIDERNAM E, | |
249 | PROVIDER CLASS, PRO VIDERARG, PROVIDERPA TH, V), | |
250 | ||
251 | // Undocumen ted start here, KEYC LONE is us ed a marke r in -help ; | |
252 | ||
253 | KE YCLONE("Cl ones.a.key .entry", | |
254 | ALIAS, D ESTALIAS, KEYPASS, N EW, STORET YPE, | |
255 | KEYSTORE , STOREPAS S, PROVIDE RNAME, PRO VIDERCLASS , | |
256 | PROVIDER ARG, PROVI DERPATH, V ), | |
257 | SE LFCERT("Ge nerates.a. self.signe d.certific ate", | |
258 | ALIAS, S IGALG, DNA ME, STARTD ATE, VALID ITY, KEYPA SS, | |
259 | STORETYP E, KEYSTOR E, STOREPA SS, PROVID ERNAME, | |
260 | PROVIDER CLASS, PRO VIDERARG, PROVIDERPA TH, V), | |
261 | GE NCRL("Gene rates.CRL" , | |
262 | RFC, FIL EOUT, ID, | |
263 | ALIAS, S IGALG, EXT , KEYPASS, KEYSTORE, | |
264 | STOREPAS S, STORETY PE, PROVID ERNAME, PR OVIDERCLAS S, | |
265 | PROVIDER ARG, PROVI DERPATH, V , PROTECTE D), | |
266 | ID ENTITYDB(" Imports.en tries.from .a.JDK.1.1 .x.style.i dentity.da tabase", | |
267 | FILEIN, STORETYPE, KEYSTORE, STOREPASS , PROVIDER NAME, | |
268 | PROVIDER CLASS, PRO VIDERARG, PROVIDERPA TH, V); | |
269 | ||
270 | fi nal String descripti on; | |
271 | fi nal Option [] options ; | |
272 | Co mmand(Stri ng d, Opti on... o) { | |
273 | descript ion = d; | |
274 | options = o; | |
275 | } | |
276 | @O verride | |
277 | pu blic Strin g toString () { | |
278 | return " -" + name( ).toLowerC ase(Locale .ENGLISH); | |
279 | } | |
280 | }; | |
281 | ||
282 | enum O ption { | |
283 | AL IAS("alias ", "<alias >", "alias .name.of.t he.entry.t o.process" ), | |
284 | DE STALIAS("d estalias", "<destali as>", "des tination.a lias"), | |
285 | DE STKEYPASS( "destkeypa ss", "<arg >", "desti nation.key .password" ), | |
286 | DE STKEYSTORE ("destkeys tore", "<d estkeystor e>", "dest ination.ke ystore.nam e"), | |
287 | DE STPROTECTE D("destpro tected", n ull, "dest ination.ke ystore.pas sword.prot ected"), | |
288 | DE STPROVIDER NAME("dest providerna me", "<des tprovidern ame>", "de stination. keystore.p rovider.na me"), | |
289 | DE STSTOREPAS S("deststo repass", " <arg>", "d estination .keystore. password") , | |
290 | DE STSTORETYP E("deststo retype", " <deststore type>", "d estination .keystore. type"), | |
291 | DN AME("dname ", "<dname >", "disti nguished.n ame"), | |
292 | EX T("ext", " <value>", "X.509.ext ension"), | |
293 | FI LEOUT("fil e", "<file name>", "o utput.file .name"), | |
294 | FI LEIN("file ", "<filen ame>", "in put.file.n ame"), | |
295 | ID ("id", "<i d:reason>" , "Serial. ID.of.cert .to.revoke "), | |
296 | IN FILE("infi le", "<fil ename>", " input.file .name"), | |
297 | KE YALG("keya lg", "<key alg>", "ke y.algorith m.name"), | |
298 | KE YPASS("key pass", "<a rg>", "key .password" ), | |
299 | KE YSIZE("key size", "<k eysize>", "key.bit.s ize"), | |
300 | KE YSTORE("ke ystore", " <keystore> ", "keysto re.name"), | |
301 | NE W("new", " <arg>", "n ew.passwor d"), | |
302 | NO PROMPT("no prompt", n ull, "do.n ot.prompt" ), | |
303 | OU TFILE("out file", "<f ilename>", "output.f ile.name") , | |
304 | PR OTECTED("p rotected", null, "pa ssword.thr ough.prote cted.mecha nism"), | |
305 | PR OVIDERARG( "providera rg", "<arg >", "provi der.argume nt"), | |
306 | PR OVIDERCLAS S("provide rclass", " <providerc lass>", "p rovider.cl ass.name") , | |
307 | PR OVIDERNAME ("provider name", "<p rovidernam e>", "prov ider.name" ), | |
308 | PR OVIDERPATH ("provider path", "<p athlist>", "provider .classpath "), | |
309 | RF C("rfc", n ull, "outp ut.in.RFC. style"), | |
310 | SI GALG("siga lg", "<sig alg>", "si gnature.al gorithm.na me"), | |
311 | SR CALIAS("sr calias", " <srcalias> ", "source .alias"), | |
312 | SR CKEYPASS(" srckeypass ", "<arg>" , "source. key.passwo rd"), | |
313 | SR CKEYSTORE( "srckeysto re", "<src keystore>" , "source. keystore.n ame"), | |
314 | SR CPROTECTED ("srcprote cted", nul l, "source .keystore. password.p rotected") , | |
315 | SR CPROVIDERN AME("srcpr ovidername ", "<srcpr ovidername >", "sourc e.keystore .provider. name"), | |
316 | SR CSTOREPASS ("srcstore pass", "<a rg>", "sou rce.keysto re.passwor d"), | |
317 | SR CSTORETYPE ("srcstore type", "<s rcstoretyp e>", "sour ce.keystor e.type"), | |
318 | SS LSERVER("s slserver", "<server[ :port]>", "SSL.serve r.host.and .port"), | |
319 | JA RFILE("jar file", "<f ilename>", "signed.j ar.file"), | |
320 | ST ARTDATE("s tartdate", "<startda te>", "cer tificate.v alidity.st art.date.t ime"), | |
321 | ST OREPASS("s torepass", "<arg>", "keystore. password") , | |
322 | ST ORETYPE("s toretype", "<storety pe>", "key store.type "), | |
323 | SY STEMLINEEN DINGS("sys temlineend ings", nul l, "system .line.endi ngs"), | |
324 | TR USTCACERTS ("trustcac erts", nul l, "trust. certificat es.from.ca certs"), | |
325 | V( "v", null, "verbose. output"), | |
326 | VA LIDITY("va lidity", " <valDays>" , "validit y.number.o f.days"); | |
327 | ||
328 | fi nal String name, arg , descript ion; | |
329 | Op tion(Strin g name, St ring arg, String des cription) { | |
330 | this.nam e = name; | |
331 | this.arg = arg; | |
332 | this.des cription = descripti on; | |
333 | } | |
334 | @O verride | |
335 | pu blic Strin g toString () { | |
336 | return " -" + name; | |
337 | } | |
338 | }; | |
339 | ||
340 | privat e static f inal Class <?>[] PARA M_STRING = { String. class }; | |
341 | ||
342 | privat e static f inal Strin g NONE = " NONE"; | |
343 | privat e static f inal Strin g P11KEYST ORE = "PKC S11"; | |
344 | privat e static f inal Strin g P12KEYST ORE = "PKC S12"; | |
345 | privat e static f inal Strin g keyAlias = "mykey" ; | |
346 | ||
347 | // for i18n | |
348 | privat e static f inal java. util.Resou rceBundle rb = | |
349 | ja va.util.Re sourceBund le.getBund le( | |
350 | "sun.sec urity.tool s.keytool. Resources" ); | |
351 | privat e static f inal Colla tor collat or = Colla tor.getIns tance(); | |
352 | static { | |
353 | // this is f or case in sensitive string com parisons | |
354 | co llator.set Strength(C ollator.PR IMARY); | |
355 | }; | |
356 | ||
357 | privat e Main() { } | |
358 | ||
359 | public static vo id main(St ring[] arg s) throws Exception { | |
360 | Ma in kt = ne w Main(); | |
361 | kt .run(args, System.ou t); | |
362 | } | |
363 | ||
364 | privat e void run (String[] args, Prin tStream ou t) throws Exception { | |
365 | tr y { | |
366 | parseArg s(args); | |
367 | if (comm and != nul l) { | |
368 | doCo mmands(out ); | |
369 | } | |
370 | } catch (Exc eption e) { | |
371 | System.o ut.println (rb.getStr ing("keyto ol.error." ) + e); | |
372 | if (verb ose) { | |
373 | e.pr intStackTr ace(System .out); | |
374 | } | |
375 | if (!deb ug) { | |
376 | Syst em.exit(1) ; | |
377 | } else { | |
378 | thro w e; | |
379 | } | |
380 | } finally { | |
381 | printWea kWarnings( false); | |
382 | for (cha r[] pass : passwords ) { | |
383 | if ( pass != nu ll) { | |
384 | Arrays.fil l(pass, ' '); | |
385 | pass = nul l; | |
386 | } | |
387 | } | |
388 | ||
389 | if (ksSt ream != nu ll) { | |
390 | ksSt ream.close (); | |
391 | } | |
392 | } | |
393 | } | |
394 | ||
395 | /** | |
396 | * Par se command line argu ments. | |
397 | */ | |
398 | void p arseArgs(S tring[] ar gs) { | |
399 | ||
400 | in t i=0; | |
401 | bo olean help = args.le ngth == 0; | |
402 | ||
403 | fo r (i=0; (i < args.le ngth) && a rgs[i].sta rtsWith("- "); i++) { | |
404 | ||
405 | String f lags = arg s[i]; | |
406 | ||
407 | // Check if the la st option needs an a rg | |
408 | if (i == args.leng th - 1) { | |
409 | for (Option op tion: Opti on.values( )) { | |
410 | // Only op tions with an arg ne ed to be c hecked | |
411 | if (collat or.compare (flags, op tion.toStr ing()) == 0) { | |
412 | if (op tion.arg ! = null) er rorNeedArg ument(flag s); | |
413 | break; | |
414 | } | |
415 | } | |
416 | } | |
417 | ||
418 | /* | |
419 | * Check modifiers | |
420 | */ | |
421 | String m odifier = null; | |
422 | int pos = flags.in dexOf(':') ; | |
423 | if (pos > 0) { | |
424 | modi fier = fla gs.substri ng(pos+1); | |
425 | flag s = flags. substring( 0, pos); | |
426 | } | |
427 | /* | |
428 | * comma nd modes | |
429 | */ | |
430 | boolean isCommand = false; | |
431 | for (Com mand c: Co mmand.valu es()) { | |
432 | if ( collator.c ompare(fla gs, c.toSt ring()) == 0) { | |
433 | command = c; | |
434 | isCommand = true; | |
435 | break; | |
436 | } | |
437 | } | |
438 | ||
439 | if (isCo mmand) { | |
440 | // a lready rec ognized as a command | |
441 | } else i f (collato r.compare( flags, "-e xport") == 0) { | |
442 | comm and = EXPO RTCERT; | |
443 | } else i f (collato r.compare( flags, "-g enkey") == 0) { | |
444 | comm and = GENK EYPAIR; | |
445 | } else i f (collato r.compare( flags, "-i mport") == 0) { | |
446 | comm and = IMPO RTCERT; | |
447 | } else i f (collato r.compare( flags, "-i mportpassw ord") == 0 ) { | |
448 | comm and = IMPO RTPASS; | |
449 | } else i f (collato r.compare( flags, "-h elp") == 0 ) { | |
450 | help = true; | |
451 | } else i f (collato r.compare( flags, "-n owarn") == 0) { | |
452 | nowa rn = true; | |
453 | } | |
454 | ||
455 | /* | |
456 | * speci fiers | |
457 | */ | |
458 | else if (collator. compare(fl ags, "-key store") == 0 || | |
459 | collator.c ompare(fla gs, "-dest keystore") == 0) { | |
460 | ksfn ame = args [++i]; | |
461 | } else i f (collato r.compare( flags, "-s torepass") == 0 || | |
462 | collator.c ompare(fla gs, "-dest storepass" ) == 0) { | |
463 | stor ePass = ge tPass(modi fier, args [++i]); | |
464 | pass words.add( storePass) ; | |
465 | } else i f (collato r.compare( flags, "-s toretype") == 0 || | |
466 | collator.c ompare(fla gs, "-dest storetype" ) == 0) { | |
467 | stor etype = ar gs[++i]; | |
468 | } else i f (collato r.compare( flags, "-s rcstorepas s") == 0) { | |
469 | srcs torePass = getPass(m odifier, a rgs[++i]); | |
470 | pass words.add( srcstorePa ss); | |
471 | } else i f (collato r.compare( flags, "-s rcstoretyp e") == 0) { | |
472 | srcs toretype = args[++i] ; | |
473 | } else i f (collato r.compare( flags, "-s rckeypass" ) == 0) { | |
474 | srck eyPass = g etPass(mod ifier, arg s[++i]); | |
475 | pass words.add( srckeyPass ); | |
476 | } else i f (collato r.compare( flags, "-s rcprovider name") == 0) { | |
477 | srcP roviderNam e = args[+ +i]; | |
478 | } else i f (collato r.compare( flags, "-p rovidernam e") == 0 | | | |
479 | collator.c ompare(fla gs, "-dest providerna me") == 0) { | |
480 | prov iderName = args[++i] ; | |
481 | } else i f (collato r.compare( flags, "-p roviderpat h") == 0) { | |
482 | path list = arg s[++i]; | |
483 | } else i f (collato r.compare( flags, "-k eypass") = = 0) { | |
484 | keyP ass = getP ass(modifi er, args[+ +i]); | |
485 | pass words.add( keyPass); | |
486 | } else i f (collato r.compare( flags, "-n ew") == 0) { | |
487 | newP ass = getP ass(modifi er, args[+ +i]); | |
488 | pass words.add( newPass); | |
489 | } else i f (collato r.compare( flags, "-d estkeypass ") == 0) { | |
490 | dest KeyPass = getPass(mo difier, ar gs[++i]); | |
491 | pass words.add( destKeyPas s); | |
492 | } else i f (collato r.compare( flags, "-a lias") == 0 || | |
493 | collator.c ompare(fla gs, "-srca lias") == 0) { | |
494 | alia s = args[+ +i]; | |
495 | } else i f (collato r.compare( flags, "-d est") == 0 || | |
496 | collator.c ompare(fla gs, "-dest alias") == 0) { | |
497 | dest = args[++ i]; | |
498 | } else i f (collato r.compare( flags, "-d name") == 0) { | |
499 | dnam e = args[+ +i]; | |
500 | } else i f (collato r.compare( flags, "-k eysize") = = 0) { | |
501 | keys ize = Inte ger.parseI nt(args[++ i]); | |
502 | } else i f (collato r.compare( flags, "-k eyalg") == 0) { | |
503 | keyA lgName = a rgs[++i]; | |
504 | } else i f (collato r.compare( flags, "-s igalg") == 0) { | |
505 | sigA lgName = a rgs[++i]; | |
506 | } else i f (collato r.compare( flags, "-s tartdate") == 0) { | |
507 | star tDate = ar gs[++i]; | |
508 | } else i f (collato r.compare( flags, "-v alidity") == 0) { | |
509 | vali dity = Lon g.parseLon g(args[++i ]); | |
510 | } else i f (collato r.compare( flags, "-e xt") == 0) { | |
511 | v3ex t.add(args [++i]); | |
512 | } else i f (collato r.compare( flags, "-i d") == 0) { | |
513 | ids. add(args[+ +i]); | |
514 | } else i f (collato r.compare( flags, "-f ile") == 0 ) { | |
515 | file name = arg s[++i]; | |
516 | } else i f (collato r.compare( flags, "-i nfile") == 0) { | |
517 | infi lename = a rgs[++i]; | |
518 | } else i f (collato r.compare( flags, "-o utfile") = = 0) { | |
519 | outf ilename = args[++i]; | |
520 | } else i f (collato r.compare( flags, "-s slserver") == 0) { | |
521 | ssls erver = ar gs[++i]; | |
522 | } else i f (collato r.compare( flags, "-j arfile") = = 0) { | |
523 | jarf ile = args [++i]; | |
524 | } else i f (collato r.compare( flags, "-s rckeystore ") == 0) { | |
525 | srck sfname = a rgs[++i]; | |
526 | } else i f ((collat or.compare (flags, "- provider") == 0) || | |
527 | (colla tor.compar e(flags, " -providerc lass") == 0)) { | |
528 | if ( providers == null) { | |
529 | providers = new Hash Set<Pair < String, St ring>> (3) ; | |
530 | } | |
531 | Stri ng provide rClass = a rgs[++i]; | |
532 | Stri ng provide rArg = nul l; | |
533 | ||
534 | if ( args.lengt h > (i+1)) { | |
535 | flags = ar gs[i+1]; | |
536 | if (collat or.compare (flags, "- providerar g") == 0) { | |
537 | if (ar gs.length == (i+2)) errorNeedA rgument(fl ags); | |
538 | provid erArg = ar gs[i+2]; | |
539 | i += 2 ; | |
540 | } | |
541 | } | |
542 | prov iders.add( | |
543 | Pair.o f(provider Class, pro viderArg)) ; | |
544 | } | |
545 | ||
546 | /* | |
547 | * optio ns | |
548 | */ | |
549 | else if (collator. compare(fl ags, "-v") == 0) { | |
550 | verb ose = true ; | |
551 | } else i f (collato r.compare( flags, "-d ebug") == 0) { | |
552 | debu g = true; | |
553 | } else i f (collato r.compare( flags, "-r fc") == 0) { | |
554 | rfc = true; | |
555 | } else i f (collato r.compare( flags, "-n oprompt") == 0) { | |
556 | nopr ompt = tru e; | |
557 | } else i f (collato r.compare( flags, "-t rustcacert s") == 0) { | |
558 | trus tcacerts = true; | |
559 | } else i f (collato r.compare( flags, "-p rotected") == 0 || | |
560 | collator.c ompare(fla gs, "-dest protected" ) == 0) { | |
561 | prot ectedPath = true; | |
562 | } else i f (collato r.compare( flags, "-s rcprotecte d") == 0) { | |
563 | srcp rotectedPa th = true; | |
564 | } else i f (collato r.compare( flags, "-s ystemlinee ndings") = = 0) { | |
565 | syst emLineEndi ngs = true ; | |
566 | } else { | |
567 | Syst em.err.pri ntln(rb.ge tString("I llegal.opt ion.") + f lags); | |
568 | tiny Help(); | |
569 | } | |
570 | } | |
571 | ||
572 | if (i<args.l ength) { | |
573 | System.e rr.println (rb.getStr ing("Illeg al.option. ") + args[ i]); | |
574 | tinyHelp (); | |
575 | } | |
576 | ||
577 | if (command == null) { | |
578 | if (help ) { | |
579 | usag e(); | |
580 | } else { | |
581 | Syst em.err.pri ntln(rb.ge tString("U sage.error .no.comman d.provided ")); | |
582 | tiny Help(); | |
583 | } | |
584 | } else if (h elp) { | |
585 | usage(); | |
586 | command = null; | |
587 | } | |
588 | } | |
589 | ||
590 | boolea n isKeySto reRelated( Command cm d) { | |
591 | re turn cmd ! = PRINTCER T && cmd ! = PRINTCER TREQ; | |
592 | } | |
593 | ||
594 | ||
595 | /** | |
596 | * Exe cute the c ommands. | |
597 | */ | |
598 | void d oCommands( PrintStrea m out) thr ows Except ion { | |
599 | if (storetyp e == null) { | |
600 | storetyp e = KeySto re.getDefa ultType(); | |
601 | } | |
602 | st oretype = KeyStoreUt il.niceSto reTypeName (storetype ); | |
603 | ||
604 | if (srcstore type == nu ll) { | |
605 | srcstore type = Key Store.getD efaultType (); | |
606 | } | |
607 | sr cstoretype = KeyStor eUtil.nice StoreTypeN ame(srcsto retype); | |
608 | ||
609 | if (P11KEYST ORE.equals IgnoreCase (storetype ) || | |
610 | KeyS toreUtil.i sWindowsKe yStore(sto retype)) { | |
611 | token = true; | |
612 | if (ksfn ame == nul l) { | |
613 | ksfn ame = NONE ; | |
614 | } | |
615 | } | |
616 | if (NONE.equ als(ksfnam e)) { | |
617 | nullStre am = true; | |
618 | } | |
619 | ||
620 | if (token && !nullStre am) { | |
621 | System.e rr.println (MessageFo rmat.forma t(rb.getSt ring | |
622 | (".k eystore.mu st.be.NONE .if.storet ype.is.{0} "), storet ype)); | |
623 | System.e rr.println (); | |
624 | tinyHelp (); | |
625 | } | |
626 | ||
627 | if (token && | |
628 | (command == KEYPAS SWD || com mand == ST OREPASSWD) ) { | |
629 | throw ne w Unsuppor tedOperati onExceptio n(MessageF ormat.form at(rb.getS tring | |
630 | (".sto repasswd.a nd.keypass wd.command s.not.supp orted.if.s toretype.i s.{0}"), s toretype)) ; | |
631 | } | |
632 | ||
633 | if (P12KEYST ORE.equals IgnoreCase (storetype ) && comma nd == KEYP ASSWD) { | |
634 | throw ne w Unsuppor tedOperati onExceptio n(rb.getSt ring | |
635 | (".key passwd.com mands.not. supported. if.storety pe.is.PKCS 12")); | |
636 | } | |
637 | ||
638 | if (token && (keyPass != null || newPass ! = null || destKeyPas s != null) ) { | |
639 | throw ne w IllegalA rgumentExc eption(Mes sageFormat .format(rb .getString | |
640 | (".k eypass.and .new.can.n ot.be.spec ified.if.s toretype.i s.{0}"), s toretype)) ; | |
641 | } | |
642 | ||
643 | if (protecte dPath) { | |
644 | if (stor ePass != n ull || key Pass != nu ll || | |
645 | newPass != null || d estKeyPass != null) { | |
646 | thro w new Ille galArgumen tException (rb.getStr ing | |
647 | ("if.p rotected.i s.specifie d.then.sto repass.key pass.and.n ew.must.no t.be.speci fied")); | |
648 | } | |
649 | } | |
650 | ||
651 | if (srcprote ctedPath) { | |
652 | if (srcs torePass ! = null || srckeyPass != null) { | |
653 | thro w new Ille galArgumen tException (rb.getStr ing | |
654 | ("if.s rcprotecte d.is.speci fied.then. srcstorepa ss.and.src keypass.mu st.not.be. specified" )); | |
655 | } | |
656 | } | |
657 | ||
658 | if (KeyStore Util.isWin dowsKeySto re(storety pe)) { | |
659 | if (stor ePass != n ull || key Pass != nu ll || | |
660 | newPass != null || d estKeyPass != null) { | |
661 | thro w new Ille galArgumen tException (rb.getStr ing | |
662 | ("if.k eystore.is .not.passw ord.protec ted.then.s torepass.k eypass.and .new.must. not.be.spe cified")); | |
663 | } | |
664 | } | |
665 | ||
666 | if (KeyStore Util.isWin dowsKeySto re(srcstor etype)) { | |
667 | if (srcs torePass ! = null || srckeyPass != null) { | |
668 | thro w new Ille galArgumen tException (rb.getStr ing | |
669 | ("if.s ource.keys tore.is.no t.password .protected .then.srcs torepass.a nd.srckeyp ass.must.n ot.be.spec ified")); | |
670 | } | |
671 | } | |
672 | ||
673 | if (validity <= (long) 0) { | |
674 | throw ne w Exceptio n | |
675 | (rb. getString( "Validity. must.be.gr eater.than .zero")); | |
676 | } | |
677 | ||
678 | // Try to lo ad and ins tall speci fied provi der | |
679 | if (provider s != null) { | |
680 | ClassLoa der cl = n ull; | |
681 | if (path list != nu ll) { | |
682 | Stri ng path = null; | |
683 | path = PathLis t.appendPa th( | |
684 | path, System.get Property(" java.class .path")); | |
685 | path = PathLis t.appendPa th( | |
686 | path, System.get Property(" env.class. path")); | |
687 | path = PathLis t.appendPa th(path, p athlist); | |
688 | ||
689 | URL[ ] urls = P athList.pa thToURLs(p ath); | |
690 | cl = new URLCl assLoader( urls); | |
691 | } else { | |
692 | cl = ClassLoad er.getSyst emClassLoa der(); | |
693 | } | |
694 | ||
695 | for (Pai r <String, String> p rovider: p roviders) { | |
696 | Stri ng provNam e = provid er.fst; | |
697 | Clas s<?> provC lass; | |
698 | if ( cl != null ) { | |
699 | provClass = cl.loadC lass(provN ame); | |
700 | } el se { | |
701 | provClass = Class.fo rName(prov Name); | |
702 | } | |
703 | ||
704 | Stri ng provArg = provide r.snd; | |
705 | Obje ct obj; | |
706 | if ( provArg == null) { | |
707 | obj = prov Class.newI nstance(); | |
708 | } el se { | |
709 | Constructo r<?> c = p rovClass.g etConstruc tor(PARAM_ STRING); | |
710 | obj = c.ne wInstance( provArg); | |
711 | } | |
712 | if ( !(obj inst anceof Pro vider)) { | |
713 | MessageFor mat form = new Messa geFormat | |
714 | (rb.ge tString("p rovName.no t.a.provid er")); | |
715 | Object[] s ource = {p rovName}; | |
716 | throw new Exception( form.forma t(source)) ; | |
717 | } | |
718 | Secu rity.addPr ovider((Pr ovider)obj ); | |
719 | } | |
720 | } | |
721 | ||
722 | if (command == LIST && verbose & & rfc) { | |
723 | System.e rr.println (rb.getStr ing | |
724 | ("Mu st.not.spe cify.both. v.and.rfc. with.list. command")) ; | |
725 | tinyHelp (); | |
726 | } | |
727 | ||
728 | // Make sure provided passwords are at lea st 6 chara cters long | |
729 | if (command == GENKEYP AIR && key Pass!=null && keyPas s.length < 6) { | |
730 | throw ne w Exceptio n(rb.getSt ring | |
731 | ("Ke y.password .must.be.a t.least.6. characters ")); | |
732 | } | |
733 | if (newPass != null && newPass.l ength < 6) { | |
734 | throw ne w Exceptio n(rb.getSt ring | |
735 | ("Ne w.password .must.be.a t.least.6. characters ")); | |
736 | } | |
737 | if (destKeyP ass != nul l && destK eyPass.len gth < 6) { | |
738 | throw ne w Exceptio n(rb.getSt ring | |
739 | ("Ne w.password .must.be.a t.least.6. characters ")); | |
740 | } | |
741 | ||
742 | // Set this before inp laceImport check so we can com pare name. | |
743 | if (ksfname == null) { | |
744 | ksfname = System.g etProperty ("user.hom e") + File .separator | |
745 | + ".keysto re"; | |
746 | } | |
747 | ||
748 | Ke yStore src KeyStore = null; | |
749 | if (command == IMPORTK EYSTORE) { | |
750 | inplaceI mport = in placeImpor tCheck(); | |
751 | if (inpl aceImport) { | |
752 | // W e load src keystore f irst so we have srcs torePass t hat | |
753 | // c an be assi gned to st orePass | |
754 | srcK eyStore = loadSource KeyStore() ; | |
755 | if ( storePass == null) { | |
756 | storePass = srcstore Pass; | |
757 | } | |
758 | } | |
759 | } | |
760 | ||
761 | // Check if keystore e xists. | |
762 | // If no key store has been speci fied at th e command line, try to use | |
763 | // the defau lt, which is located in $HOME/ .keystore. | |
764 | // If the co mmand is " genkey", " identitydb ", "import ", or "pri ntcert", | |
765 | // it is OK not to hav e a keysto re. | |
766 | ||
767 | // DO NOT op en the exi sting keys tore if th is is an i n-place im port. | |
768 | // The keyst ore should be create d as brand new. | |
769 | if (isKeySto reRelated( command) & & !nullStr eam && !in placeImpor t) { | |
770 | try { | |
771 | ksfile = n ew File(ks fname); | |
772 | // Check i f keystore file is e mpty | |
773 | if (ksfile .exists() && ksfile. length() = = 0) { | |
774 | throw new Except ion(rb.get String | |
775 | ("Keys tore.file. exists.but .is.empty. ") + ksfna me); | |
776 | } | |
777 | ksStream = new FileI nputStream (ksfile); | |
778 | } ca tch (FileN otFoundExc eption e) { | |
779 | if (comman d != GENKE YPAIR && | |
780 | comman d != GENSE CKEY && | |
781 | comman d != IDENT ITYDB && | |
782 | comman d != IMPOR TCERT && | |
783 | comman d != IMPOR TPASS && | |
784 | comman d != IMPOR TKEYSTORE && | |
785 | comman d != PRINT CRL) { | |
786 | throw new Except ion(rb.get String | |
787 | ("Keysto re.file.do es.not.exi st.") + ks fname); | |
788 | } | |
789 | } | |
790 | } | |
791 | ||
792 | if ((command == KEYCLO NE || comm and == CHA NGEALIAS) | |
793 | && d est == nul l) { | |
794 | dest = g etAlias("d estination "); | |
795 | if ("".e quals(dest )) { | |
796 | thro w new Exce ption(rb.g etString | |
797 | ("Must .specify.d estination .alias")); | |
798 | } | |
799 | } | |
800 | ||
801 | if (command == DELETE && alias = = null) { | |
802 | alias = getAlias(n ull); | |
803 | if ("".e quals(alia s)) { | |
804 | thro w new Exce ption(rb.g etString(" Must.speci fy.alias") ); | |
805 | } | |
806 | } | |
807 | ||
808 | // Create ne w keystore | |
809 | if (provider Name == nu ll) { | |
810 | keyStore = KeyStor e.getInsta nce(storet ype); | |
811 | } else { | |
812 | keyStore = KeyStor e.getInsta nce(storet ype, provi derName); | |
813 | } | |
814 | ||
815 | /* | |
816 | * Load the keystore d ata. | |
817 | * | |
818 | * At this p oint, it's OK if no keystore p assword ha s been pro vided. | |
819 | * We want t o make sur e that we can load t he keystor e data, i. e., | |
820 | * the keyst ore data h as the rig ht format. If we can not load t he | |
821 | * keystore, why bothe r asking t he user fo r his or h er passwor d? | |
822 | * Only if w e were abl e to load the keysto re, and no keystore | |
823 | * password has been p rovided, w ill we pro mpt the us er for the | |
824 | * keystore password t o verify t he keystor e integrit y. | |
825 | * This mean s that the keystore is loaded twice: fir st load op eration | |
826 | * checks th e keystore format, s econd load operation verifies the | |
827 | * keystore integrity. | |
828 | * | |
829 | * If the ke ystore pas sword has already be en provide d (at the | |
830 | * command l ine), howe ver, the k eystore is loaded on ly once, a nd the | |
831 | * keystore format and integrity are check ed "at the same time ". | |
832 | * | |
833 | * Null stre am keystor es are loa ded later. | |
834 | * / | |
835 | if (!nullStr eam) { | |
836 | if (inpl aceImport) { | |
837 | keyS tore.load( null, stor ePass); | |
838 | } else { | |
839 | keyStore .load(ksSt ream, stor ePass); | |
840 | } | |
841 | if (ksSt ream != nu ll) { | |
842 | ksSt ream.close (); | |
843 | } | |
844 | } | |
845 | ||
846 | // All comma nds that c reate or m odify the keystore r equire a k eystore | |
847 | // password. | |
848 | ||
849 | if (nullStre am && stor ePass != n ull) { | |
850 | keyStore .load(null , storePas s); | |
851 | } else if (! nullStream && storeP ass != nul l) { | |
852 | // If we are creat ing a new non nullSt ream-based keystore, | |
853 | // insis t that the password be at leas t 6 charac ters | |
854 | if (ksSt ream == nu ll && stor ePass.leng th < 6) { | |
855 | thro w new Exce ption(rb.g etString | |
856 | ("Keys tore.passw ord.must.b e.at.least .6.charact ers")); | |
857 | } | |
858 | } else if (s torePass = = null) { | |
859 | ||
860 | // only prompt if (protected Path == fa lse) | |
861 | ||
862 | if (!pro tectedPath && !KeySt oreUtil.is WindowsKey Store(stor etype) && | |
863 | (com mand == CE RTREQ || | |
864 | comman d == DELET E || | |
865 | comman d == GENKE YPAIR || | |
866 | comman d == GENSE CKEY || | |
867 | comman d == IMPOR TCERT || | |
868 | comman d == IMPOR TPASS || | |
869 | comman d == IMPOR TKEYSTORE || | |
870 | comman d == KEYCL ONE || | |
871 | comman d == CHANG EALIAS || | |
872 | comman d == SELFC ERT || | |
873 | comman d == STORE PASSWD || | |
874 | comman d == KEYPA SSWD || | |
875 | comman d == IDENT ITYDB)) { | |
876 | int count = 0; | |
877 | do { | |
878 | if (comman d == IMPOR TKEYSTORE) { | |
879 | System .err.print | |
880 | (rb.getS tring("Ent er.destina tion.keyst ore.passwo rd.")); | |
881 | } else { | |
882 | System .err.print | |
883 | (rb.getS tring("Ent er.keystor e.password .")); | |
884 | } | |
885 | System.err .flush(); | |
886 | storePass = Password .readPassw ord(System .in); | |
887 | passwords. add(storeP ass); | |
888 | ||
889 | // If we a re creatin g a new no n nullStre am-based k eystore, | |
890 | // insist that the p assword be at least 6 characte rs | |
891 | if (!nullS tream && ( storePass == null || storePass .length < 6)) { | |
892 | System .err.print ln(rb.getS tring | |
893 | ("Keysto re.passwor d.is.too.s hort.must. be.at.leas t.6.charac ters")); | |
894 | storeP ass = null ; | |
895 | } | |
896 | ||
897 | // If the keystore f ile does n ot exist a nd needs t o be | |
898 | // created , the stor epass shou ld be prom pted twice . | |
899 | if (storeP ass != nul l && !null Stream && ksStream = = null) { | |
900 | System .err.print (rb.getStr ing("Re.en ter.new.pa ssword.")) ; | |
901 | char[] storePass Again = Pa ssword.rea dPassword( System.in) ; | |
902 | passwo rds.add(st orePassAga in); | |
903 | if (!A rrays.equa ls(storePa ss, storeP assAgain)) { | |
904 | Sy stem.err.p rintln | |
905 | (rb.getS tring("The y.don.t.ma tch.Try.ag ain")); | |
906 | st orePass = null; | |
907 | } | |
908 | } | |
909 | ||
910 | count++; | |
911 | } wh ile ((stor ePass == n ull) && co unt < 3); | |
912 | ||
913 | ||
914 | if ( storePass == null) { | |
915 | System.err .println | |
916 | (rb.ge tString("T oo.many.fa ilures.try .later")); | |
917 | return; | |
918 | } | |
919 | } else i f (!protec tedPath | |
920 | && !KeySto reUtil.isW indowsKeyS tore(store type) | |
921 | && isKeySt oreRelated (command)) { | |
922 | // h ere we hav e EXPORTCE RT and LIS T (info va lid until STOREPASSW D) | |
923 | if ( command != PRINTCRL) { | |
924 | System.err .print(rb. getString( "Enter.key store.pass word.")); | |
925 | System.err .flush(); | |
926 | storePass = Password .readPassw ord(System .in); | |
927 | passwords. add(storeP ass); | |
928 | } | |
929 | } | |
930 | ||
931 | // Now l oad a null Stream-bas ed keystor e, | |
932 | // or ve rify the i ntegrity o f an input stream-ba sed keysto re | |
933 | if (null Stream) { | |
934 | keyS tore.load( null, stor ePass); | |
935 | } else i f (ksStrea m != null) { | |
936 | ksSt ream = new FileInput Stream(ksf ile); | |
937 | keyS tore.load( ksStream, storePass) ; | |
938 | ksSt ream.close (); | |
939 | } | |
940 | } | |
941 | ||
942 | if (storePas s != null && P12KEYS TORE.equal sIgnoreCas e(storetyp e)) { | |
943 | MessageF ormat form = new Mes sageFormat (rb.getStr ing( | |
944 | "War ning.Diffe rent.store .and.key.p asswords.n ot.support ed.for.PKC S12.KeySto res.Ignori ng.user.sp ecified.co mmand.valu e.")); | |
945 | if (keyP ass != nul l && !Arra ys.equals( storePass, keyPass)) { | |
946 | Obje ct[] sourc e = {"-key pass"}; | |
947 | Syst em.err.pri ntln(form. format(sou rce)); | |
948 | keyP ass = stor ePass; | |
949 | } | |
950 | if (newP ass != nul l && !Arra ys.equals( storePass, newPass)) { | |
951 | Obje ct[] sourc e = {"-new "}; | |
952 | Syst em.err.pri ntln(form. format(sou rce)); | |
953 | newP ass = stor ePass; | |
954 | } | |
955 | if (dest KeyPass != null && ! Arrays.equ als(storeP ass, destK eyPass)) { | |
956 | Obje ct[] sourc e = {"-des tkeypass"} ; | |
957 | Syst em.err.pri ntln(form. format(sou rce)); | |
958 | dest KeyPass = storePass; | |
959 | } | |
960 | } | |
961 | ||
962 | // Create a certificat e factory | |
963 | if (command == PRINTCE RT || comm and == IMP ORTCERT | |
964 | || c ommand == IDENTITYDB || comman d == PRINT CRL) { | |
965 | cf = Cer tificateFa ctory.getI nstance("X 509"); | |
966 | } | |
967 | ||
968 | // -trustcac erts can o nly be spe cified on -importcer t. | |
969 | // Reset it so that wa rnings on CA cert wi ll remain for | |
970 | // -printcer t, etc. | |
971 | if (command != IMPORTC ERT) { | |
972 | trustcac erts = fal se; | |
973 | } | |
974 | ||
975 | if (trustcac erts) { | |
976 | caks = K eyStoreUti l.getCacer tsKeyStore (); | |
977 | } | |
978 | ||
979 | // Perform t he specifi ed command | |
980 | if (command == CERTREQ ) { | |
981 | if (file name != nu ll) { | |
982 | try (PrintStre am ps = ne w PrintStr eam(new Fi leOutputSt ream | |
983 | (filen ame))) { | |
984 | doCertReq( alias, sig AlgName, p s); | |
985 | } | |
986 | } else { | |
987 | doCe rtReq(alia s, sigAlgN ame, out); | |
988 | } | |
989 | if (verb ose && fil ename != n ull) { | |
990 | Mess ageFormat form = new MessageFo rmat(rb.ge tString | |
991 | ("Cert ification. request.st ored.in.fi le.filenam e.")); | |
992 | Obje ct[] sourc e = {filen ame}; | |
993 | Syst em.err.pri ntln(form. format(sou rce)); | |
994 | Syst em.err.pri ntln(rb.ge tString("S ubmit.this .to.your.C A")); | |
995 | } | |
996 | } else if (c ommand == DELETE) { | |
997 | doDelete Entry(alia s); | |
998 | kssave = true; | |
999 | } else if (c ommand == EXPORTCERT ) { | |
1000 | if (file name != nu ll) { | |
1001 | try (PrintStre am ps = ne w PrintStr eam(new Fi leOutputSt ream | |
1002 | (filename ))) { | |
1003 | doExportCe rt(alias, ps); | |
1004 | } | |
1005 | } else { | |
1006 | doEx portCert(a lias, out) ; | |
1007 | } | |
1008 | if (file name != nu ll) { | |
1009 | Mess ageFormat form = new MessageFo rmat(rb.ge tString | |
1010 | ("Cert ificate.st ored.in.fi le.filenam e.")); | |
1011 | Obje ct[] sourc e = {filen ame}; | |
1012 | Syst em.err.pri ntln(form. format(sou rce)); | |
1013 | } | |
1014 | } else if (c ommand == GENKEYPAIR ) { | |
1015 | if (keyA lgName == null) { | |
1016 | keyA lgName = " DSA"; | |
1017 | } | |
1018 | doGenKey Pair(alias , dname, k eyAlgName, keysize, sigAlgName ); | |
1019 | kssave = true; | |
1020 | } else if (c ommand == GENSECKEY) { | |
1021 | if (keyA lgName == null) { | |
1022 | keyA lgName = " DES"; | |
1023 | } | |
1024 | doGenSec retKey(ali as, keyAlg Name, keys ize); | |
1025 | kssave = true; | |
1026 | } else if (c ommand == IMPORTPASS ) { | |
1027 | if (keyA lgName == null) { | |
1028 | keyA lgName = " PBE"; | |
1029 | } | |
1030 | // passwor d is store d as a PW key | |
1031 | doGenSec retKey(ali as, keyAlg Name, keys ize); | |
1032 | kssave = true; | |
1033 | } else if (c ommand == IDENTITYDB ) { | |
1034 | if (file name != nu ll) { | |
1035 | try (InputStre am inStrea m = new Fi leInputStr eam(filena me)) { | |
1036 | doImportId entityData base(inStr eam); | |
1037 | } | |
1038 | } else { | |
1039 | doIm portIdenti tyDatabase (System.in ); | |
1040 | } | |
1041 | } else if (c ommand == IMPORTCERT ) { | |
1042 | InputStr eam inStre am = Syste m.in; | |
1043 | if (file name != nu ll) { | |
1044 | inSt ream = new FileInput Stream(fil ename); | |
1045 | } | |
1046 | String i mportAlias = (alias! =null)?ali as:keyAlia s; | |
1047 | try { | |
1048 | if ( keyStore.e ntryInstan ceOf( | |
1049 | import Alias, Key Store.Priv ateKeyEntr y.class)) { | |
1050 | kssave = i nstallRepl y(importAl ias, inStr eam); | |
1051 | if (kssave ) { | |
1052 | System .err.print ln(rb.getS tring | |
1053 | (" Certificat e.reply.wa s.installe d.in.keyst ore")); | |
1054 | } else { | |
1055 | System .err.print ln(rb.getS tring | |
1056 | (" Certificat e.reply.wa s.not.inst alled.in.k eystore")) ; | |
1057 | } | |
1058 | } el se if (!ke yStore.con tainsAlias (importAli as) || | |
1059 | keySto re.entryIn stanceOf(i mportAlias , | |
1060 | Ke yStore.Tru stedCertif icateEntry .class)) { | |
1061 | kssave = a ddTrustedC ert(import Alias, inS tream); | |
1062 | if (kssave ) { | |
1063 | System .err.print ln(rb.getS tring | |
1064 | (" Certificat e.was.adde d.to.keyst ore")); | |
1065 | } else { | |
1066 | System .err.print ln(rb.getS tring | |
1067 | (" Certificat e.was.not. added.to.k eystore")) ; | |
1068 | } | |
1069 | } | |
1070 | } finall y { | |
1071 | if ( inStream ! = System.i n) { | |
1072 | inStream.c lose(); | |
1073 | } | |
1074 | } | |
1075 | } else if (c ommand == IMPORTKEYS TORE) { | |
1076 | // When not in-pla ce import, srcKeySto re is not loaded yet . | |
1077 | if (srcK eyStore == null) { | |
1078 | srcK eyStore = loadSource KeyStore() ; | |
1079 | } | |
1080 | doImport KeyStore(s rcKeyStore ); | |
1081 | kssave = true; | |
1082 | } else if (c ommand == KEYCLONE) { | |
1083 | keyPassN ew = newPa ss; | |
1084 | ||
1085 | // added to make s ure only k ey can go thru | |
1086 | if (alia s == null) { | |
1087 | alia s = keyAli as; | |
1088 | } | |
1089 | if (keyS tore.conta insAlias(a lias) == f alse) { | |
1090 | Mess ageFormat form = new MessageFo rmat | |
1091 | (rb.getStr ing("Alias .alias.doe s.not.exis t")); | |
1092 | Obje ct[] sourc e = {alias }; | |
1093 | thro w new Exce ption(form .format(so urce)); | |
1094 | } | |
1095 | if (!key Store.entr yInstanceO f(alias, K eyStore.Pr ivateKeyEn try.class) ) { | |
1096 | Mess ageFormat form = new MessageFo rmat(rb.ge tString( | |
1097 | "Alias .alias.ref erences.an .entry.typ e.that.is. not.a.priv ate.key.en try.The.ke yclone.com mand.only. supports.c loning.of. private.ke y")); | |
1098 | Obje ct[] sourc e = {alias }; | |
1099 | thro w new Exce ption(form .format(so urce)); | |
1100 | } | |
1101 | ||
1102 | doCloneE ntry(alias , dest, tr ue); // N ow everyth ing can be cloned | |
1103 | kssave = true; | |
1104 | } else if (c ommand == CHANGEALIA S) { | |
1105 | if (alia s == null) { | |
1106 | alia s = keyAli as; | |
1107 | } | |
1108 | doCloneE ntry(alias , dest, fa lse); | |
1109 | // in PK CS11, clon e a Privat eKeyEntry will delet e the old one | |
1110 | if (keyS tore.conta insAlias(a lias)) { | |
1111 | doDe leteEntry( alias); | |
1112 | } | |
1113 | kssave = true; | |
1114 | } else if (c ommand == KEYPASSWD) { | |
1115 | keyPassN ew = newPa ss; | |
1116 | doChange KeyPasswd( alias); | |
1117 | kssave = true; | |
1118 | } else if (c ommand == LIST) { | |
1119 | if (stor ePass == n ull | |
1120 | && !KeySto reUtil.isW indowsKeyS tore(store type)) { | |
1121 | prin tNoIntegri tyWarning( ); | |
1122 | } | |
1123 | ||
1124 | if (alia s != null) { | |
1125 | doPr intEntry(r b.getStrin g("the.cer tificate") , alias, o ut); | |
1126 | } else { | |
1127 | doPr intEntries (out); | |
1128 | } | |
1129 | } else if (c ommand == PRINTCERT) { | |
1130 | doPrintC ert(out); | |
1131 | } else if (c ommand == SELFCERT) { | |
1132 | doSelfCe rt(alias, dname, sig AlgName); | |
1133 | kssave = true; | |
1134 | } else if (c ommand == STOREPASSW D) { | |
1135 | storePas sNew = new Pass; | |
1136 | if (stor ePassNew = = null) { | |
1137 | stor ePassNew = getNewPas swd("keyst ore passwo rd", store Pass); | |
1138 | } | |
1139 | kssave = true; | |
1140 | } else if (c ommand == GENCERT) { | |
1141 | if (alia s == null) { | |
1142 | alia s = keyAli as; | |
1143 | } | |
1144 | InputStr eam inStre am = Syste m.in; | |
1145 | if (infi lename != null) { | |
1146 | inSt ream = new FileInput Stream(inf ilename); | |
1147 | } | |
1148 | PrintStr eam ps = n ull; | |
1149 | if (outf ilename != null) { | |
1150 | ps = new Print Stream(new FileOutpu tStream(ou tfilename) ); | |
1151 | out = ps; | |
1152 | } | |
1153 | try { | |
1154 | doGe nCert(alia s, sigAlgN ame, inStr eam, out); | |
1155 | } finall y { | |
1156 | if ( inStream ! = System.i n) { | |
1157 | inStream.c lose(); | |
1158 | } | |
1159 | if ( ps != null ) { | |
1160 | ps.close() ; | |
1161 | } | |
1162 | } | |
1163 | } else if (c ommand == GENCRL) { | |
1164 | if (alia s == null) { | |
1165 | alia s = keyAli as; | |
1166 | } | |
1167 | if (file name != nu ll) { | |
1168 | try (PrintStre am ps = | |
1169 | new P rintStream (new FileO utputStrea m(filename ))) { | |
1170 | doGenCRL(p s); | |
1171 | } | |
1172 | } else { | |
1173 | doGe nCRL(out); | |
1174 | } | |
1175 | } else if (c ommand == PRINTCERTR EQ) { | |
1176 | if (file name != nu ll) { | |
1177 | try (InputStre am inStrea m = new Fi leInputStr eam(filena me)) { | |
1178 | doPrintCer tReq(inStr eam, out); | |
1179 | } | |
1180 | } else { | |
1181 | doPr intCertReq (System.in , out); | |
1182 | } | |
1183 | } else if (c ommand == PRINTCRL) { | |
1184 | doPrintC RL(filenam e, out); | |
1185 | } | |
1186 | ||
1187 | // If we nee d to save the keysto re, do so. | |
1188 | if (kssave) { | |
1189 | if (verb ose) { | |
1190 | Mess ageFormat form = new MessageFo rmat | |
1191 | (rb.ge tString(". Storing.ks fname.")); | |
1192 | Obje ct[] sourc e = {nullS tream ? "k eystore" : ksfname}; | |
1193 | Syst em.err.pri ntln(form. format(sou rce)); | |
1194 | } | |
1195 | ||
1196 | if (toke n) { | |
1197 | keyS tore.store (null, nul l); | |
1198 | } else { | |
1199 | char [] pass = (storePass New!=null) ? storePa ssNew : st orePass; | |
1200 | if ( nullStream ) { | |
1201 | keyStore.s tore(null, pass); | |
1202 | } el se { | |
1203 | ByteArrayO utputStrea m bout = n ew ByteArr ayOutputSt ream(); | |
1204 | keyStore.s tore(bout, pass); | |
1205 | try (FileO utputStrea m fout = n ew FileOut putStream( ksfname)) { | |
1206 | fout.w rite(bout. toByteArra y()); | |
1207 | } | |
1208 | } | |
1209 | } | |
1210 | } | |
1211 | ||
1212 | if (isKeySto reRelated( command) | |
1213 | && ! token && ! nullStream && ksfnam e != null) { | |
1214 | ||
1215 | // JKS s toretype w arning on the final result key store | |
1216 | File f = new File( ksfname); | |
1217 | if (f.ex ists()) { | |
1218 | // R ead the fi rst 4 byte s to deter mine | |
1219 | // i f we're de aling with JKS/JCEKS type stor e | |
1220 | Stri ng realTyp e = keySto reType(f); | |
1221 | if ( realType.e qualsIgnor eCase("JKS ") | |
1222 | || realTyp e.equalsIg noreCase(" JCEKS")) { | |
1223 | boolean al lCerts = t rue; | |
1224 | for (Strin g a : Coll ections.li st(keyStor e.aliases( ))) { | |
1225 | if (!k eyStore.en tryInstanc eOf( | |
1226 | a, Trust edCertific ateEntry.c lass)) { | |
1227 | al lCerts = f alse; | |
1228 | br eak; | |
1229 | } | |
1230 | } | |
1231 | // Don't w arn for "c acerts" st yle keysto re. | |
1232 | if (!allCe rts) { | |
1233 | weakWa rnings.add (String.fo rmat( | |
1234 | rb.getSt ring("jks. storetype. warning"), | |
1235 | realType , ksfname) ); | |
1236 | } | |
1237 | } | |
1238 | if ( inplaceImp ort) { | |
1239 | String rea lSourceSto reType = | |
1240 | keySto reType(new File(inpl aceBackupN ame)); | |
1241 | String for mat = | |
1242 | re alType.equ alsIgnoreC ase(realSo urceStoreT ype) ? | |
1243 | rb .getString ("backup.k eystore.wa rning") : | |
1244 | rb .getString ("migrate. keystore.w arning"); | |
1245 | weakWarnin gs.add( | |
1246 | St ring.forma t(format, | |
1247 | srck sfname, | |
1248 | real SourceStor eType, | |
1249 | inpl aceBackupN ame, | |
1250 | real Type)); | |
1251 | } | |
1252 | } | |
1253 | } | |
1254 | } | |
1255 | ||
1256 | privat e String k eyStoreTyp e(File f) throws IOE xception { | |
1257 | in t MAGIC = 0xfeedfeed ; | |
1258 | in t JCEKS_MA GIC = 0xce cecece; | |
1259 | tr y (DataInp utStream d is = new D ataInputSt ream( | |
1260 | new File InputStrea m(f))) { | |
1261 | int xMag ic = dis.r eadInt(); | |
1262 | if (xMag ic == MAGI C) { | |
1263 | retu rn "JKS"; | |
1264 | } else i f (xMagic == JCEKS_M AGIC) { | |
1265 | retu rn "JCEKS" ; | |
1266 | } else { | |
1267 | retu rn "Non JK S/JCEKS"; | |
1268 | } | |
1269 | } | |
1270 | } | |
1271 | ||
1272 | /** | |
1273 | * Gen erate a ce rtificate: Read PKCS 10 request from in, and print | |
1274 | * cer tificate t o out. Use alias as CA, sigAlg Name as th e signatur e | |
1275 | * typ e. | |
1276 | */ | |
1277 | privat e void doG enCert(Str ing alias, String si gAlgName, InputStrea m in, Prin tStream ou t) | |
1278 | throws E xception { | |
1279 | ||
1280 | ||
1281 | if (keyStore .containsA lias(alias ) == false ) { | |
1282 | MessageF ormat form = new Mes sageFormat | |
1283 | (rb.getStr ing("Alias .alias.doe s.not.exis t")); | |
1284 | Object[] source = {alias}; | |
1285 | throw ne w Exceptio n(form.for mat(source )); | |
1286 | } | |
1287 | Ce rtificate signerCert = keyStor e.getCerti ficate(ali as); | |
1288 | by te[] encod ed = signe rCert.getE ncoded(); | |
1289 | X5 09CertImpl signerCer tImpl = ne w X509Cert Impl(encod ed); | |
1290 | X5 09CertInfo signerCer tInfo = (X 509CertInf o)signerCe rtImpl.get ( | |
1291 | X509 CertImpl.N AME + "." + X509Cert Impl.INFO) ; | |
1292 | X5 00Name iss uer = (X50 0Name)sign erCertInfo .get(X509C ertInfo.SU BJECT + ". " + | |
1293 | X509Cer tInfo.DN_N AME); | |
1294 | ||
1295 | Da te firstDa te = getSt artDate(st artDate); | |
1296 | Da te lastDat e = new Da te(); | |
1297 | la stDate.set Time(first Date.getTi me() + val idity*1000 L*24L*60L* 60L); | |
1298 | Ce rtificateV alidity in terval = n ew Certifi cateValidi ty(firstDa te, | |
1299 | lastDat e); | |
1300 | ||
1301 | Pr ivateKey p rivateKey = | |
1302 | (Pri vateKey)re coverKey(a lias, stor ePass, key Pass).fst; | |
1303 | if (sigAlgNa me == null ) { | |
1304 | sigAlgNa me = getCo mpatibleSi gAlgName(p rivateKey. getAlgorit hm()); | |
1305 | } | |
1306 | Si gnature si gnature = Signature. getInstanc e(sigAlgNa me); | |
1307 | si gnature.in itSign(pri vateKey); | |
1308 | ||
1309 | X5 09CertInfo info = ne w X509Cert Info(); | |
1310 | in fo.set(X50 9CertInfo. VALIDITY, interval); | |
1311 | in fo.set(X50 9CertInfo. SERIAL_NUM BER, new C ertificate SerialNumb er( | |
1312 | new java.u til.Random ().nextInt () & 0x7ff fffff)); | |
1313 | in fo.set(X50 9CertInfo. VERSION, | |
1314 | new Certif icateVersi on(Certifi cateVersio n.V3)); | |
1315 | in fo.set(X50 9CertInfo. ALGORITHM_ ID, | |
1316 | new Certif icateAlgor ithmId( | |
1317 | Algori thmId.get( sigAlgName ))); | |
1318 | in fo.set(X50 9CertInfo. ISSUER, is suer); | |
1319 | ||
1320 | Bu fferedRead er reader = new Buff eredReader (new Input StreamRead er(in)); | |
1321 | bo olean canR ead = fals e; | |
1322 | St ringBuffer sb = new StringBuff er(); | |
1323 | wh ile (true) { | |
1324 | String s = reader. readLine() ; | |
1325 | if (s == null) bre ak; | |
1326 | // OpenS SL does no t use NEW | |
1327 | //if (s. startsWith ("-----BEG IN NEW CER TIFICATE R EQUEST---- -")) { | |
1328 | if (s.st artsWith(" -----BEGIN ") && s.in dexOf("REQ UEST") >= 0) { | |
1329 | canR ead = true ; | |
1330 | //} else if (s.sta rtsWith("- ----END NE W CERTIFIC ATE REQUES T-----")) { | |
1331 | } else i f (s.start sWith("--- --END") && s.indexOf ("REQUEST" ) >= 0) { | |
1332 | brea k; | |
1333 | } else i f (canRead ) { | |
1334 | sb.a ppend(s); | |
1335 | } | |
1336 | } | |
1337 | by te[] rawRe q = Pem.de code(new S tring(sb)) ; | |
1338 | PK CS10 req = new PKCS1 0(rawReq); | |
1339 | ||
1340 | ch eckWeak(rb .getString ("the.cert ificate.re quest"), r eq); | |
1341 | ||
1342 | in fo.set(X50 9CertInfo. KEY, new C ertificate X509Key(re q.getSubje ctPublicKe yInfo())); | |
1343 | in fo.set(X50 9CertInfo. SUBJECT, | |
1344 | dname==nul l?req.getS ubjectName ():new X50 0Name(dnam e)); | |
1345 | Ce rtificateE xtensions reqex = nu ll; | |
1346 | It erator<PKC S10Attribu te> attrs = req.getA ttributes( ).getAttri butes().it erator(); | |
1347 | wh ile (attrs .hasNext() ) { | |
1348 | PKCS10At tribute at tr = attrs .next(); | |
1349 | if (attr .getAttrib uteId().eq uals((Obje ct)PKCS9At tribute.EX TENSION_RE QUEST_OID) ) { | |
1350 | reqe x = (Certi ficateExte nsions)att r.getAttri buteValue( ); | |
1351 | } | |
1352 | } | |
1353 | Ce rtificateE xtensions ext = crea teV3Extens ions( | |
1354 | reqe x, | |
1355 | null , | |
1356 | v3ex t, | |
1357 | req. getSubject PublicKeyI nfo(), | |
1358 | sign erCert.get PublicKey( )); | |
1359 | in fo.set(X50 9CertInfo. EXTENSIONS , ext); | |
1360 | X5 09CertImpl cert = ne w X509Cert Impl(info) ; | |
1361 | ce rt.sign(pr ivateKey, sigAlgName ); | |
1362 | du mpCert(cer t, out); | |
1363 | fo r (Certifi cate ca: k eyStore.ge tCertifica teChain(al ias)) { | |
1364 | if (ca i nstanceof X509Certif icate) { | |
1365 | X509 Certificat e xca = (X 509Certifi cate)ca; | |
1366 | if ( !isSelfSig ned(xca)) { | |
1367 | dumpCert(x ca, out); | |
1368 | } | |
1369 | } | |
1370 | } | |
1371 | ||
1372 | ch eckWeak(rb .getString ("the.issu er"), keyS tore.getCe rtificateC hain(alias )); | |
1373 | ch eckWeak(rb .getString ("the.gene rated.cert ificate"), cert); | |
1374 | } | |
1375 | ||
1376 | privat e void doG enCRL(Prin tStream ou t) | |
1377 | throws E xception { | |
1378 | if (ids == n ull) { | |
1379 | throw ne w Exceptio n("Must pr ovide -id when -genc rl"); | |
1380 | } | |
1381 | Ce rtificate signerCert = keyStor e.getCerti ficate(ali as); | |
1382 | by te[] encod ed = signe rCert.getE ncoded(); | |
1383 | X5 09CertImpl signerCer tImpl = ne w X509Cert Impl(encod ed); | |
1384 | X5 09CertInfo signerCer tInfo = (X 509CertInf o)signerCe rtImpl.get ( | |
1385 | X509 CertImpl.N AME + "." + X509Cert Impl.INFO) ; | |
1386 | X5 00Name own er = (X500 Name)signe rCertInfo. get(X509Ce rtInfo.SUB JECT + "." + | |
1387 | X509Ce rtInfo.DN_ NAME); | |
1388 | ||
1389 | Da te firstDa te = getSt artDate(st artDate); | |
1390 | Da te lastDat e = (Date) firstDate .clone(); | |
1391 | la stDate.set Time(lastD ate.getTim e() + vali dity*1000* 24*60*60); | |
1392 | Ce rtificateV alidity in terval = n ew Certifi cateValidi ty(firstDa te, | |
1393 | lastDat e); | |
1394 | ||
1395 | ||
1396 | Pr ivateKey p rivateKey = | |
1397 | (Pri vateKey)re coverKey(a lias, stor ePass, key Pass).fst; | |
1398 | if (sigAlgNa me == null ) { | |
1399 | sigAlgNa me = getCo mpatibleSi gAlgName(p rivateKey. getAlgorit hm()); | |
1400 | } | |
1401 | ||
1402 | X5 09CRLEntry [] badCert s = new X5 09CRLEntry [ids.size( )]; | |
1403 | fo r (int i=0 ; i<ids.si ze(); i++) { | |
1404 | String i d = ids.ge t(i); | |
1405 | int d = id.indexOf (':'); | |
1406 | if (d >= 0) { | |
1407 | CRLE xtensions ext = new CRLExtensi ons(); | |
1408 | ext. set("Reaso n", new CR LReasonCod eExtension (Integer.p arseInt(id .substring (d+1)))); | |
1409 | badC erts[i] = new X509CR LEntryImpl (new BigIn teger(id.s ubstring(0 , d)), | |
1410 | firstD ate, ext); | |
1411 | } else { | |
1412 | badC erts[i] = new X509CR LEntryImpl (new BigIn teger(ids. get(i)), f irstDate); | |
1413 | } | |
1414 | } | |
1415 | X5 09CRLImpl crl = new X509CRLImp l(owner, f irstDate, lastDate, badCerts); | |
1416 | cr l.sign(pri vateKey, s igAlgName) ; | |
1417 | if (rfc) { | |
1418 | out.prin tln("----- BEGIN X509 CRL-----" ); | |
1419 | out.prin tln(Base64 .getMimeEn coder(64, CRLF).enco deToString (crl.getEn codedInter nal())); | |
1420 | out.prin tln("----- END X509 C RL-----"); | |
1421 | } else { | |
1422 | out.writ e(crl.getE ncodedInte rnal()); | |
1423 | } | |
1424 | ch eckWeak(rb .getString ("the.gene rated.crl" ), crl, pr ivateKey); | |
1425 | } | |
1426 | ||
1427 | /** | |
1428 | * Cre ates a PKC S#10 cert signing re quest, cor responding to the | |
1429 | * key s (and nam e) associa ted with a given ali as. | |
1430 | */ | |
1431 | privat e void doC ertReq(Str ing alias, String si gAlgName, PrintStrea m out) | |
1432 | th rows Excep tion | |
1433 | { | |
1434 | if (alias == null) { | |
1435 | alias = keyAlias; | |
1436 | } | |
1437 | ||
1438 | Pa ir<Key,cha r[]> objs = recoverK ey(alias, storePass, keyPass); | |
1439 | Pr ivateKey p rivKey = ( PrivateKey )objs.fst; | |
1440 | if (keyPass == null) { | |
1441 | keyPass = objs.snd ; | |
1442 | } | |
1443 | ||
1444 | Ce rtificate cert = key Store.getC ertificate (alias); | |
1445 | if (cert == null) { | |
1446 | MessageF ormat form = new Mes sageFormat | |
1447 | (rb. getString( "alias.has .no.public .key.certi ficate.")) ; | |
1448 | Object[] source = {alias}; | |
1449 | throw ne w Exceptio n(form.for mat(source )); | |
1450 | } | |
1451 | PK CS10 reque st = new P KCS10(cert .getPublic Key()); | |
1452 | Ce rtificateE xtensions ext = crea teV3Extens ions(null, null, v3e xt, cert.g etPublicKe y(), null) ; | |
1453 | // Attribute name is n ot signifi cant | |
1454 | re quest.getA ttributes( ).setAttri bute(X509C ertInfo.EX TENSIONS, | |
1455 | new PKCS10Attr ibute(PKCS 9Attribute .EXTENSION _REQUEST_O ID, ext)); | |
1456 | ||
1457 | // Construct a Signatu re object, so that w e can sign the reque st | |
1458 | if (sigAlgNa me == null ) { | |
1459 | sigAlgNa me = getCo mpatibleSi gAlgName(p rivKey.get Algorithm( )); | |
1460 | } | |
1461 | ||
1462 | Si gnature si gnature = Signature. getInstanc e(sigAlgNa me); | |
1463 | si gnature.in itSign(pri vKey); | |
1464 | X5 00Name sub ject = dna me == null ? | |
1465 | new X500Name(( (X509Certi ficate)cer t).getSubj ectDN().to String()): | |
1466 | new X500Name(d name); | |
1467 | ||
1468 | // Sign the request an d base-64 encode it | |
1469 | re quest.enco deAndSign( subject, s ignature); | |
1470 | re quest.prin t(out, sys temLineEnd ings); | |
1471 | ||
1472 | ch eckWeak(rb .getString ("the.gene rated.cert ificate.re quest"), r equest); | |
1473 | } | |
1474 | ||
1475 | /** | |
1476 | * Del etes an en try from t he keystor e. | |
1477 | */ | |
1478 | privat e void doD eleteEntry (String al ias) throw s Exceptio n { | |
1479 | if (keyStore .containsA lias(alias ) == false ) { | |
1480 | MessageF ormat form = new Mes sageFormat | |
1481 | (rb. getString( "Alias.ali as.does.no t.exist")) ; | |
1482 | Object[] source = {alias}; | |
1483 | throw ne w Exceptio n(form.for mat(source )); | |
1484 | } | |
1485 | ke yStore.del eteEntry(a lias); | |
1486 | } | |
1487 | ||
1488 | /** | |
1489 | * Exp orts a cer tificate f rom the ke ystore. | |
1490 | */ | |
1491 | privat e void doE xportCert( String ali as, PrintS tream out) | |
1492 | th rows Excep tion | |
1493 | { | |
1494 | if (storePas s == null | |
1495 | && ! KeyStoreUt il.isWindo wsKeyStore (storetype )) { | |
1496 | printNoI ntegrityWa rning(); | |
1497 | } | |
1498 | if (alias == null) { | |
1499 | alias = keyAlias; | |
1500 | } | |
1501 | if (keyStore .containsA lias(alias ) == false ) { | |
1502 | MessageF ormat form = new Mes sageFormat | |
1503 | (rb. getString( "Alias.ali as.does.no t.exist")) ; | |
1504 | Object[] source = {alias}; | |
1505 | throw ne w Exceptio n(form.for mat(source )); | |
1506 | } | |
1507 | ||
1508 | X5 09Certific ate cert = (X509Cert ificate)ke yStore.get Certificat e(alias); | |
1509 | if (cert == null) { | |
1510 | MessageF ormat form = new Mes sageFormat | |
1511 | (rb. getString( "Alias.ali as.has.no. certificat e")); | |
1512 | Object[] source = {alias}; | |
1513 | throw ne w Exceptio n(form.for mat(source )); | |
1514 | } | |
1515 | du mpCert(cer t, out); | |
1516 | ch eckWeak(rb .getString ("the.cert ificate"), cert); | |
1517 | } | |
1518 | ||
1519 | /** | |
1520 | * Pro mpt the us er for a k eypass whe n generati ng a key e ntry. | |
1521 | * @pa ram alias the entry we will se t password for | |
1522 | * @pa ram orig t he origina l entry of doing a d up, null i f generate new | |
1523 | * @pa ram origPa ss the pas sword to c opy from i f user pre ss ENTER | |
1524 | */ | |
1525 | privat e char[] p romptForKe yPass(Stri ng alias, String ori g, char[] origPass) throws Exc eption{ | |
1526 | if (P12KEYST ORE.equals IgnoreCase (storetype )) { | |
1527 | return o rigPass; | |
1528 | } else if (! token && ! protectedP ath) { | |
1529 | // Promp t for key password | |
1530 | int coun t; | |
1531 | for (cou nt = 0; co unt < 3; c ount++) { | |
1532 | Mess ageFormat form = new MessageFo rmat(rb.ge tString | |
1533 | ("Ente r.key.pass word.for.a lias.")); | |
1534 | Obje ct[] sourc e = {alias }; | |
1535 | Syst em.err.pri ntln(form. format(sou rce)); | |
1536 | if ( orig == nu ll) { | |
1537 | System.err .print(rb. getString | |
1538 | (" .RETURN.if .same.as.k eystore.pa ssword.")) ; | |
1539 | } el se { | |
1540 | form = new MessageFo rmat(rb.ge tString | |
1541 | (" .RETURN.if .same.as.f or.otherAl ias.")); | |
1542 | Object[] s rc = {orig }; | |
1543 | System.err .print(for m.format(s rc)); | |
1544 | } | |
1545 | Syst em.err.flu sh(); | |
1546 | char [] entered = Passwor d.readPass word(Syste m.in); | |
1547 | pass words.add( entered); | |
1548 | if ( entered == null) { | |
1549 | return ori gPass; | |
1550 | } el se if (ent ered.lengt h >= 6) { | |
1551 | System.err .print(rb. getString( "Re.enter. new.passwo rd.")); | |
1552 | char[] pas sAgain = P assword.re adPassword (System.in ); | |
1553 | passwords. add(passAg ain); | |
1554 | if (!Array s.equals(e ntered, pa ssAgain)) { | |
1555 | System .err.print ln | |
1556 | (r b.getStrin g("They.do n.t.match. Try.again" )); | |
1557 | contin ue; | |
1558 | } | |
1559 | return ent ered; | |
1560 | } el se { | |
1561 | System.err .println(r b.getStrin g | |
1562 | ("Key. password.i s.too.shor t.must.be. at.least.6 .character s")); | |
1563 | } | |
1564 | } | |
1565 | if (coun t == 3) { | |
1566 | if ( command == KEYCLONE) { | |
1567 | throw new Exception( rb.getStri ng | |
1568 | ("Too. many.failu res.Key.en try.not.cl oned")); | |
1569 | } el se { | |
1570 | throw new Exception( rb.getStri ng | |
1571 | (" Too.many.f ailures.ke y.not.adde d.to.keyst ore")); | |
1572 | } | |
1573 | } | |
1574 | } | |
1575 | re turn null; // PKC S11, MSCAP I, or -pro tected | |
1576 | } | |
1577 | ||
1578 | /* | |
1579 | * Pro mpt the us er for the password credential to be sto red. | |
1580 | */ | |
1581 | privat e char[] p romptForCr edential() throws Ex ception { | |
1582 | // Handle pa ssword sup plied via stdin | |
1583 | if (System.c onsole() = = null) { | |
1584 | char[] i mportPass = Password .readPassw ord(System .in); | |
1585 | password s.add(impo rtPass); | |
1586 | return i mportPass; | |
1587 | } | |
1588 | ||
1589 | in t count; | |
1590 | fo r (count = 0; count < 3; count ++) { | |
1591 | System.e rr.print( | |
1592 | rb.g etString(" Enter.the. password.t o.be.store d.")); | |
1593 | System.e rr.flush() ; | |
1594 | char[] e ntered = P assword.re adPassword (System.in ); | |
1595 | password s.add(ente red); | |
1596 | System.e rr.print(r b.getStrin g("Re.ente r.password .")); | |
1597 | char[] p assAgain = Password. readPasswo rd(System. in); | |
1598 | password s.add(pass Again); | |
1599 | if (!Arr ays.equals (entered, passAgain) ) { | |
1600 | Syst em.err.pri ntln(rb.ge tString("T hey.don.t. match.Try. again")); | |
1601 | cont inue; | |
1602 | } | |
1603 | return e ntered; | |
1604 | } | |
1605 | ||
1606 | if (count == 3) { | |
1607 | throw ne w Exceptio n(rb.getSt ring | |
1608 | ("To o.many.fai lures.key. not.added. to.keystor e")); | |
1609 | } | |
1610 | ||
1611 | re turn null; | |
1612 | } | |
1613 | ||
1614 | /** | |
1615 | * Creates a new PW key. | |
1616 | */ | |
1617 | privat e void doG enSecretKe y(String a lias, Stri ng keyAlgN ame, | |
1618 | int keysiz e) | |
1619 | th rows Excep tion | |
1620 | { | |
1621 | if (alias == null) { | |
1622 | alias = keyAlias; | |
1623 | } | |
1624 | if (keyStore .containsA lias(alias )) { | |
1625 | MessageF ormat form = new Mes sageFormat (rb.getStr ing | |
1626 | ("Se cret.key.n ot.generat ed.alias.a lias.alrea dy.exists" )); | |
1627 | Object[] source = {alias}; | |
1628 | throw ne w Exceptio n(form.for mat(source )); | |
1629 | } | |
1630 | ||
1631 | // Use the k eystore's default PB E algorith m for entr y protecti on | |
1632 | bo olean useD efaultPBEA lgorithm = true; | |
1633 | Se cretKey se cKey = nul l; | |
1634 | ||
1635 | if (keyAlgNa me.toUpper Case(Local e.ENGLISH) .startsWit h("PBE")) { | |
1636 | SecretKe yFactory f actory = S ecretKeyFa ctory.getI nstance("P BE"); | |
1637 | ||
1638 | // User is prompte d for PBE credential | |
1639 | secKey = | |
1640 | fact ory.genera teSecret(n ew PBEKeyS pec(prompt ForCredent ial())); | |
1641 | ||
1642 | // Check whether a specific PBE algori thm was sp ecified | |
1643 | if (!"PB E".equalsI gnoreCase( keyAlgName )) { | |
1644 | useD efaultPBEA lgorithm = false; | |
1645 | } | |
1646 | ||
1647 | if (verb ose) { | |
1648 | Mess ageFormat form = new MessageFo rmat(rb.ge tString( | |
1649 | "Generated .keyAlgNam e. PW .key")); | |
1650 | Obje ct[] sourc e = | |
1651 | {useDefaul tPBEAlgori thm ? "PBE " : secKey .getAlgori thm()}; | |
1652 | Syst em.err.pri ntln(form. format(sou rce)); | |
1653 | } | |
1654 | } else { | |
1655 | KeyGener ator keyge n = KeyGen erator.get Instance(k eyAlgName) ; | |
1656 | if (keys ize == -1) { | |
1657 | if ( "DES".equa lsIgnoreCa se(keyAlgN ame)) { | |
1658 | keysize = 56; | |
1659 | } el se if ("DE Sede".equa lsIgnoreCa se(keyAlgN ame)) { | |
1660 | keysize = 168; | |
1661 | } el se { | |
1662 | throw new Exception( rb.getStri ng | |
1663 | ("Please.p rovide.key size.for. PW .key.gener ation")); | |
1664 | } | |
1665 | } | |
1666 | keygen.i nit(keysiz e); | |
1667 | secKey = keygen.ge nerateKey( ); | |
1668 | ||
1669 | if (verb ose) { | |
1670 | Mess ageFormat form = new MessageFo rmat(rb.ge tString | |
1671 | ("Generate d.keysize. bit.keyAlg Name. PW .key")); | |
1672 | Obje ct[] sourc e = {new I nteger(key size), | |
1673 | secK ey.getAlgo rithm()}; | |
1674 | Syst em.err.pri ntln(form. format(sou rce)); | |
1675 | } | |
1676 | } | |
1677 | ||
1678 | if (keyPass == null) { | |
1679 | keyPass = promptFo rKeyPass(a lias, null , storePas s); | |
1680 | } | |
1681 | ||
1682 | if (useDefau ltPBEAlgor ithm) { | |
1683 | keyStore .setKeyEnt ry(alias, secKey, ke yPass, nul l); | |
1684 | } else { | |
1685 | keyStore .setEntry( alias, new KeyStore. SecretKeyE ntry(secKe y), | |
1686 | new KeyStore.P asswordPro tection(ke yPass, key AlgName, n ull)); | |
1687 | } | |
1688 | } | |
1689 | ||
1690 | /** | |
1691 | * If no signatu re algorit hm was spe cified at the comman d line, | |
1692 | * we choose one that is c ompatible with the s elected pr ivate key | |
1693 | */ | |
1694 | privat e static S tring getC ompatibleS igAlgName( String key AlgName) | |
1695 | throws E xception { | |
1696 | if ("DSA".eq ualsIgnore Case(keyAl gName)) { | |
1697 | return " SHA256With DSA"; | |
1698 | } else if (" RSA".equal sIgnoreCas e(keyAlgNa me)) { | |
1699 | return " SHA256With RSA"; | |
1700 | } else if (" EC".equals IgnoreCase (keyAlgNam e)) { | |
1701 | return " SHA256with ECDSA"; | |
1702 | } else { | |
1703 | throw ne w Exceptio n(rb.getSt ring | |
1704 | ("Cannot.d erive.sign ature.algo rithm")); | |
1705 | } | |
1706 | } | |
1707 | /** | |
1708 | * Cre ates a new key pair and self-s igned cert ificate. | |
1709 | */ | |
1710 | privat e void doG enKeyPair( String ali as, String dname, St ring keyAl gName, | |
1711 | int keysiz e, String sigAlgName ) | |
1712 | th rows Excep tion | |
1713 | { | |
1714 | if (keysize == -1) { | |
1715 | if ("EC" .equalsIgn oreCase(ke yAlgName)) { | |
1716 | keys ize = Secu rityProvid erConstant s.DEF_EC_K EY_SIZE; | |
1717 | } else i f ("RSA".e qualsIgnor eCase(keyA lgName)) { | |
1718 | keys ize = Secu rityProvid erConstant s.DEF_RSA_ KEY_SIZE; | |
1719 | } else i f ("DSA".e qualsIgnor eCase(keyA lgName)) { | |
1720 | keys ize = Secu rityProvid erConstant s.DEF_DSA_ KEY_SIZE; | |
1721 | } | |
1722 | } | |
1723 | ||
1724 | if (alias == null) { | |
1725 | alias = keyAlias; | |
1726 | } | |
1727 | ||
1728 | if (keyStore .containsA lias(alias )) { | |
1729 | MessageF ormat form = new Mes sageFormat (rb.getStr ing | |
1730 | ("Ke y.pair.not .generated .alias.ali as.already .exists")) ; | |
1731 | Object[] source = {alias}; | |
1732 | throw ne w Exceptio n(form.for mat(source )); | |
1733 | } | |
1734 | ||
1735 | if (sigAlgNa me == null ) { | |
1736 | sigAlgNa me = getCo mpatibleSi gAlgName(k eyAlgName) ; | |
1737 | } | |
1738 | Ce rtAndKeyGe n keypair = | |
1739 | new CertAndKey Gen(keyAlg Name, sigA lgName, pr oviderName ); | |
1740 | ||
1741 | ||
1742 | // If DN is provided, parse it. Otherwise, prompt th e user for it. | |
1743 | X5 00Name x50 0Name; | |
1744 | if (dname == null) { | |
1745 | x500Name = getX500 Name(); | |
1746 | } else { | |
1747 | x500Name = new X50 0Name(dnam e); | |
1748 | } | |
1749 | ||
1750 | ke ypair.gene rate(keysi ze); | |
1751 | Pr ivateKey p rivKey = k eypair.get PrivateKey (); | |
1752 | ||
1753 | Ce rtificateE xtensions ext = crea teV3Extens ions( | |
1754 | null , | |
1755 | null , | |
1756 | v3ex t, | |
1757 | keyp air.getPub licKeyAnyw ay(), | |
1758 | null ); | |
1759 | ||
1760 | X5 09Certific ate[] chai n = new X5 09Certific ate[1]; | |
1761 | ch ain[0] = k eypair.get SelfCertif icate( | |
1762 | x500 Name, getS tartDate(s tartDate), validity* 24L*60L*60 L, ext); | |
1763 | ||
1764 | if (verbose) { | |
1765 | MessageF ormat form = new Mes sageFormat (rb.getStr ing | |
1766 | ("Ge nerating.k eysize.bit .keyAlgNam e.key.pair .and.self. signed.cer tificate.s igAlgName. with.a.val idity.of.v alidality. days.for") ); | |
1767 | Object[] source = {new Integ er(keysize ), | |
1768 | privKey. getAlgorit hm(), | |
1769 | chain[0] .getSigAlg Name(), | |
1770 | new Long (validity) , | |
1771 | x500Name }; | |
1772 | System.e rr.println (form.form at(source) ); | |
1773 | } | |
1774 | ||
1775 | if (keyPass == null) { | |
1776 | keyPass = promptFo rKeyPass(a lias, null , storePas s); | |
1777 | } | |
1778 | ch eckWeak(rb .getString ("the.gene rated.cert ificate"), chain[0]) ; | |
1779 | ke yStore.set KeyEntry(a lias, priv Key, keyPa ss, chain) ; | |
1780 | } | |
1781 | ||
1782 | /** | |
1783 | * Clo nes an ent ry | |
1784 | * @pa ram orig o riginal al ias | |
1785 | * @pa ram dest d estination alias | |
1786 | * @ch angePasswo rd if the password c an be chan ged | |
1787 | */ | |
1788 | privat e void doC loneEntry( String ori g, String dest, bool ean change Password) | |
1789 | th rows Excep tion | |
1790 | { | |
1791 | if (orig == null) { | |
1792 | orig = k eyAlias; | |
1793 | } | |
1794 | ||
1795 | if (keyStore .containsA lias(dest) ) { | |
1796 | MessageF ormat form = new Mes sageFormat | |
1797 | (rb. getString( "Destinati on.alias.d est.alread y.exists") ); | |
1798 | Object[] source = {dest}; | |
1799 | throw ne w Exceptio n(form.for mat(source )); | |
1800 | } | |
1801 | ||
1802 | Pa ir<Entry,c har[]> obj s = recove rEntry(key Store, ori g, storePa ss, keyPas s); | |
1803 | En try entry = objs.fst ; | |
1804 | ke yPass = ob js.snd; | |
1805 | ||
1806 | Pa sswordProt ection pp = null; | |
1807 | ||
1808 | if (keyPass != null) { // prote cted | |
1809 | if (!cha ngePasswor d || P12KE YSTORE.equ alsIgnoreC ase(storet ype)) { | |
1810 | keyP assNew = k eyPass; | |
1811 | } else { | |
1812 | if ( keyPassNew == null) { | |
1813 | keyPassNew = promptF orKeyPass( dest, orig , keyPass) ; | |
1814 | } | |
1815 | } | |
1816 | pp = new PasswordP rotection( keyPassNew ); | |
1817 | } | |
1818 | ke yStore.set Entry(dest , entry, p p); | |
1819 | } | |
1820 | ||
1821 | /** | |
1822 | * Cha nges a key password. | |
1823 | */ | |
1824 | privat e void doC hangeKeyPa sswd(Strin g alias) t hrows Exce ption | |
1825 | { | |
1826 | ||
1827 | if (alias == null) { | |
1828 | alias = keyAlias; | |
1829 | } | |
1830 | Pa ir<Key,cha r[]> objs = recoverK ey(alias, storePass, keyPass); | |
1831 | Ke y privKey = objs.fst ; | |
1832 | if (keyPass == null) { | |
1833 | keyPass = objs.snd ; | |
1834 | } | |
1835 | ||
1836 | if (keyPassN ew == null ) { | |
1837 | MessageF ormat form = new Mes sageFormat | |
1838 | (rb. getString( "key.passw ord.for.al ias.")); | |
1839 | Object[] source = {alias}; | |
1840 | keyPassN ew = getNe wPasswd(fo rm.format( source), k eyPass); | |
1841 | } | |
1842 | ke yStore.set KeyEntry(a lias, priv Key, keyPa ssNew, | |
1843 | k eyStore.ge tCertifica teChain(al ias)); | |
1844 | } | |
1845 | ||
1846 | /** | |
1847 | * Imp orts a JDK 1.1-style identity database. We can onl y store on e | |
1848 | * cer tificate p er identit y, because we use th e identity 's name as the | |
1849 | * ali as (which references a keystor e entry), and aliase s must be unique. | |
1850 | */ | |
1851 | privat e void doI mportIdent ityDatabas e(InputStr eam in) | |
1852 | th rows Excep tion | |
1853 | { | |
1854 | Sy stem.err.p rintln(rb. getString | |
1855 | ("No.ent ries.from. identity.d atabase.ad ded")); | |
1856 | } | |
1857 | ||
1858 | /** | |
1859 | * Pri nts a sing le keystor e entry. | |
1860 | */ | |
1861 | privat e void doP rintEntry( String lab el, String alias, Pr intStream out) | |
1862 | th rows Excep tion | |
1863 | { | |
1864 | if (keyStore .containsA lias(alias ) == false ) { | |
1865 | MessageF ormat form = new Mes sageFormat | |
1866 | (rb. getString( "Alias.ali as.does.no t.exist")) ; | |
1867 | Object[] source = {alias}; | |
1868 | throw ne w Exceptio n(form.for mat(source )); | |
1869 | } | |
1870 | ||
1871 | if (verbose || rfc || debug) { | |
1872 | MessageF ormat form = new Mes sageFormat | |
1873 | (rb. getString( "Alias.nam e.alias")) ; | |
1874 | Object[] source = {alias}; | |
1875 | out.prin tln(form.f ormat(sour ce)); | |
1876 | ||
1877 | if (!tok en) { | |
1878 | form = new Mes sageFormat (rb.getStr ing | |
1879 | ("Creation .date.keyS tore.getCr eationDate .alias.")) ; | |
1880 | Obje ct[] src = {keyStore .getCreati onDate(ali as)}; | |
1881 | out. println(fo rm.format( src)); | |
1882 | } | |
1883 | } else { | |
1884 | if (!tok en) { | |
1885 | Mess ageFormat form = new MessageFo rmat | |
1886 | (rb.getStr ing("alias .keyStore. getCreatio nDate.alia s.")); | |
1887 | Obje ct[] sourc e = {alias , keyStore .getCreati onDate(ali as)}; | |
1888 | out. print(form .format(so urce)); | |
1889 | } else { | |
1890 | Mess ageFormat form = new MessageFo rmat | |
1891 | (rb.getStr ing("alias .")); | |
1892 | Obje ct[] sourc e = {alias }; | |
1893 | out. print(form .format(so urce)); | |
1894 | } | |
1895 | } | |
1896 | ||
1897 | if (keyStore .entryInst anceOf(ali as, KeySto re.SecretK eyEntry.cl ass)) { | |
1898 | if (verb ose || rfc || debug) { | |
1899 | Obje ct[] sourc e = {"Secr etKeyEntry "}; | |
1900 | out. println(ne w MessageF ormat( | |
1901 | rb.get String("En try.type.t ype.")).fo rmat(sourc e)); | |
1902 | } else { | |
1903 | out. println("S ecretKeyEn try, "); | |
1904 | } | |
1905 | } else if (k eyStore.en tryInstanc eOf(alias, KeyStore. PrivateKey Entry.clas s)) { | |
1906 | if (verb ose || rfc || debug) { | |
1907 | Obje ct[] sourc e = {"Priv ateKeyEntr y"}; | |
1908 | out. println(ne w MessageF ormat( | |
1909 | rb.get String("En try.type.t ype.")).fo rmat(sourc e)); | |
1910 | } else { | |
1911 | out. println("P rivateKeyE ntry, "); | |
1912 | } | |
1913 | ||
1914 | // Get t he chain | |
1915 | Certific ate[] chai n = keySto re.getCert ificateCha in(alias); | |
1916 | if (chai n != null) { | |
1917 | if ( verbose || rfc || de bug) { | |
1918 | out.printl n(rb.getSt ring | |
1919 | ("Cert ificate.ch ain.length .") + chai n.length); | |
1920 | for (int i = 0; i < chain.leng th; i ++) { | |
1921 | Messag eFormat fo rm = new M essageForm at | |
1922 | (rb.getS tring("Cer tificate.i .1.")); | |
1923 | Object [] source = {new Int eger((i + 1))}; | |
1924 | out.pr intln(form .format(so urce)); | |
1925 | if (ve rbose && ( chain[i] i nstanceof X509Certif icate)) { | |
1926 | pr intX509Cer t((X509Cer tificate)( chain[i]), out); | |
1927 | } else if (debug ) { | |
1928 | ou t.println( chain[i].t oString()) ; | |
1929 | } else { | |
1930 | du mpCert(cha in[i], out ); | |
1931 | } | |
1932 | checkW eak(label, chain[i]) ; | |
1933 | } | |
1934 | } el se { | |
1935 | // Print t he digest of the use r cert onl y | |
1936 | out.printl n | |
1937 | (rb.ge tString("C ertificate .fingerpri nt.SHA1.") + | |
1938 | getCer tFingerPri nt("SHA1", chain[0]) ); | |
1939 | checkWeak( label, cha in[0]); | |
1940 | } | |
1941 | } | |
1942 | } else if (k eyStore.en tryInstanc eOf(alias, | |
1943 | KeyS tore.Trust edCertific ateEntry.c lass)) { | |
1944 | // We ha ve a trust ed certifi cate entry | |
1945 | Certific ate cert = keyStore. getCertifi cate(alias ); | |
1946 | Object[] source = {"trustedC ertEntry"} ; | |
1947 | String m f = new Me ssageForma t( | |
1948 | rb.getStri ng("Entry. type.type. ")).format (source) + "\n"; | |
1949 | if (verb ose && (ce rt instanc eof X509Ce rtificate) ) { | |
1950 | out. println(mf ); | |
1951 | prin tX509Cert( (X509Certi ficate)cer t, out); | |
1952 | } else i f (rfc) { | |
1953 | out. println(mf ); | |
1954 | dump Cert(cert, out); | |
1955 | } else i f (debug) { | |
1956 | out. println(ce rt.toStrin g()); | |
1957 | } else { | |
1958 | out. println("t rustedCert Entry, "); | |
1959 | out. println(rb .getString ("Certific ate.finger print.SHA1 .") | |
1960 | + getCertFin gerPrint(" SHA1", cer t)); | |
1961 | } | |
1962 | checkWea k(label, c ert); | |
1963 | } else { | |
1964 | out.prin tln(rb.get String("Un known.Entr y.Type")); | |
1965 | } | |
1966 | } | |
1967 | ||
1968 | boolea n inplaceI mportCheck () throws Exception { | |
1969 | if (P11KEYST ORE.equals IgnoreCase (srcstoret ype) || | |
1970 | KeyS toreUtil.i sWindowsKe yStore(src storetype) ) { | |
1971 | return f alse; | |
1972 | } | |
1973 | ||
1974 | if (srcksfna me != null ) { | |
1975 | File src ksfile = n ew File(sr cksfname); | |
1976 | if (srck sfile.exis ts() && sr cksfile.le ngth() == 0) { | |
1977 | thro w new Exce ption(rb.g etString | |
1978 | ("Sour ce.keystor e.file.exi sts.but.is .empty.") + | |
1979 | srcksf name); | |
1980 | } | |
1981 | if (srck sfile.getC anonicalFi le() | |
1982 | .equals(ne w File(ksf name).getC anonicalFi le())) { | |
1983 | retu rn true; | |
1984 | } else { | |
1985 | // I nformation al, especi ally if de stkeystore is not | |
1986 | // p rovided, w hich defau lt to ~/.k eystore. | |
1987 | Syst em.err.pri ntln(Strin g.format(r b.getStrin g( | |
1988 | "impor ting.keyst ore.status "), srcksf name, ksfn ame)); | |
1989 | retu rn false; | |
1990 | } | |
1991 | } else { | |
1992 | throw ne w Exceptio n(rb.getSt ring | |
1993 | ("Please.s pecify.src keystore") ); | |
1994 | } | |
1995 | } | |
1996 | ||
1997 | /** | |
1998 | * Loa d the srck eystore fr om a strea m, used in -importke ystore | |
1999 | * @re turns the src KeySto re | |
2000 | */ | |
2001 | KeySto re loadSou rceKeyStor e() throws Exception { | |
2002 | ||
2003 | In putStream is = null; | |
2004 | Fi le srcksfi le = null; | |
2005 | ||
2006 | if (P11KEYST ORE.equals IgnoreCase (srcstoret ype) || | |
2007 | KeyS toreUtil.i sWindowsKe yStore(src storetype) ) { | |
2008 | if (!NON E.equals(s rcksfname) ) { | |
2009 | Syst em.err.pri ntln(Messa geFormat.f ormat(rb.g etString | |
2010 | (".keystor e.must.be. NONE.if.st oretype.is .{0}"), sr cstoretype )); | |
2011 | Syst em.err.pri ntln(); | |
2012 | tiny Help(); | |
2013 | } | |
2014 | } else { | |
2015 | srcksfil e = new Fi le(srcksfn ame); | |
2016 | is = new FileI nputStream (srcksfile ); | |
2017 | } | |
2018 | ||
2019 | Ke yStore sto re; | |
2020 | tr y { | |
2021 | if (srcP roviderNam e == null) { | |
2022 | stor e = KeySto re.getInst ance(srcst oretype); | |
2023 | } else { | |
2024 | stor e = KeySto re.getInst ance(srcst oretype, s rcProvider Name); | |
2025 | } | |
2026 | ||
2027 | if (srcs torePass = = null | |
2028 | && !srcpro tectedPath | |
2029 | && !KeySto reUtil.isW indowsKeyS tore(srcst oretype)) { | |
2030 | Syst em.err.pri nt(rb.getS tring("Ent er.source. keystore.p assword.") ); | |
2031 | Syst em.err.flu sh(); | |
2032 | srcs torePass = Password. readPasswo rd(System. in); | |
2033 | pass words.add( srcstorePa ss); | |
2034 | } | |
2035 | ||
2036 | // alway s let keyp ass be sto repass whe n using pk cs12 | |
2037 | if (P12K EYSTORE.eq ualsIgnore Case(srcst oretype)) { | |
2038 | if ( srckeyPass != null & & srcstore Pass != nu ll && | |
2039 | !Array s.equals(s rcstorePas s, srckeyP ass)) { | |
2040 | MessageFor mat form = new Messa geFormat(r b.getStrin g( | |
2041 | "Warni ng.Differe nt.store.a nd.key.pas swords.not .supported .for.PKCS1 2.KeyStore s.Ignoring .user.spec ified.comm and.value. ")); | |
2042 | Object[] s ource = {" -srckeypas s"}; | |
2043 | System.err .println(f orm.format (source)); | |
2044 | srckeyPass = srcstor ePass; | |
2045 | } | |
2046 | } | |
2047 | ||
2048 | store.lo ad(is, src storePass) ; // "is " already null in PK CS11 | |
2049 | } finally { | |
2050 | if (is ! = null) { | |
2051 | is.c lose(); | |
2052 | } | |
2053 | } | |
2054 | ||
2055 | if (srcstore Pass == nu ll | |
2056 | && ! KeyStoreUt il.isWindo wsKeyStore (srcstoret ype)) { | |
2057 | // anti refactorin g, copied from print NoIntegrit yWarning() , | |
2058 | // but c hange 2 li nes | |
2059 | System.e rr.println (); | |
2060 | System.e rr.println (rb.getStr ing | |
2061 | (".W ARNING.WAR NING.WARNI NG.")); | |
2062 | System.e rr.println (rb.getStr ing | |
2063 | (".T he.integri ty.of.the. informatio n.stored.i n.the.srck eystore.") ); | |
2064 | System.e rr.println (rb.getStr ing | |
2065 | (".W ARNING.WAR NING.WARNI NG.")); | |
2066 | System.e rr.println (); | |
2067 | } | |
2068 | ||
2069 | re turn store ; | |
2070 | } | |
2071 | ||
2072 | /** | |
2073 | * imp ort all ke ys and cer ts from im portkeysto re. | |
2074 | * kee p alias un changed if no name c onflict, o therwise, prompt. | |
2075 | * kee p keypass unchanged for keys | |
2076 | */ | |
2077 | privat e void doI mportKeySt ore(KeySto re srcKS) throws Exc eption { | |
2078 | ||
2079 | if (alias != null) { | |
2080 | doImport KeyStoreSi ngle(srcKS , alias); | |
2081 | } else { | |
2082 | if (dest != null | | srckeyPa ss != null ) { | |
2083 | thro w new Exce ption(rb.g etString( | |
2084 | "if.al ias.not.sp ecified.de stalias.an d.srckeypa ss.must.no t.be.speci fied")); | |
2085 | } | |
2086 | doImport KeyStoreAl l(srcKS); | |
2087 | } | |
2088 | ||
2089 | if (inplaceI mport) { | |
2090 | // Backu p to file. old or fil e.old2... | |
2091 | // The k eystore is not rewri tten yet n ow. | |
2092 | for (int n = 1; /* forever * /; n++) { | |
2093 | inpl aceBackupN ame = srck sfname + " .old" + (n == 1 ? "" : n); | |
2094 | File bkFile = new File(i nplaceBack upName); | |
2095 | if ( !bkFile.ex ists()) { | |
2096 | Files.copy (Paths.get (srcksfnam e), bkFile .toPath()) ; | |
2097 | break; | |
2098 | } | |
2099 | } | |
2100 | ||
2101 | } | |
2102 | ||
2103 | /* | |
2104 | * Informati on display rule of - importkeys tore | |
2105 | * 1. inside single, s hows failu re | |
2106 | * 2. inside all, show s sucess | |
2107 | * 3. inside all where there is a failure, prompt fo r continue | |
2108 | * 4. at the final of all, shows summary | |
2109 | * / | |
2110 | } | |
2111 | ||
2112 | /** | |
2113 | * Imp ort a sing le entry n amed alias from srck eystore | |
2114 | * @re turns 1 if the impor t action s ucceed | |
2115 | * 0 if user choo se to igno re an alia s-dumplica ted entry | |
2116 | * 2 if setEntry throws Exc eption | |
2117 | */ | |
2118 | privat e int doIm portKeySto reSingle(K eyStore sr ckeystore, String al ias) | |
2119 | throws E xception { | |
2120 | ||
2121 | St ring newAl ias = (des t==null) ? alias : d est; | |
2122 | ||
2123 | if (keyStore .containsA lias(newAl ias)) { | |
2124 | Object[] source = {alias}; | |
2125 | if (nopr ompt) { | |
2126 | Syst em.err.pri ntln(new M essageForm at(rb.getS tring( | |
2127 | "Warni ng.Overwri ting.exist ing.alias. alias.in.d estination .keystore" )).format( source)); | |
2128 | } else { | |
2129 | Stri ng reply = getYesNoR eply(new M essageForm at(rb.getS tring( | |
2130 | "Exist ing.entry. alias.alia s.exists.o verwrite.n o.")).form at(source) ); | |
2131 | if ( "NO".equal s(reply)) { | |
2132 | newAlias = inputStri ngFromStdi n(rb.getSt ring | |
2133 | (" Enter.new. alias.name .RETURN.to .cancel.im port.for.t his.entry. ")); | |
2134 | if ("".equ als(newAli as)) { | |
2135 | System .err.print ln(new Mes sageFormat (rb.getStr ing( | |
2136 | "Entry.f or.alias.a lias.not.i mported.") ).format( | |
2137 | source)) ; | |
2138 | return 0; | |
2139 | } | |
2140 | } | |
2141 | } | |
2142 | } | |
2143 | ||
2144 | Pa ir<Entry,c har[]> obj s = recove rEntry(src keystore, alias, src storePass, srckeyPas s); | |
2145 | En try entry = objs.fst ; | |
2146 | ||
2147 | Pa sswordProt ection pp = null; | |
2148 | ||
2149 | // According to keytoo l.html, "T he destina tion entry will be p rotected | |
2150 | // using des tkeypass. If destkey pass is no t provided , the dest ination | |
2151 | // entry wil l be prote cted with the source entry pas sword." | |
2152 | // so always try to pr otect with destKeyPa ss. | |
2153 | ch ar[] newPa ss = null; | |
2154 | if (destKeyP ass != nul l) { | |
2155 | newPass = destKeyP ass; | |
2156 | pp = new PasswordP rotection( destKeyPas s); | |
2157 | } else if (o bjs.snd != null) { | |
2158 | newPass = objs.snd ; | |
2159 | pp = new PasswordP rotection( objs.snd); | |
2160 | } | |
2161 | ||
2162 | tr y { | |
2163 | Certific ate c = sr ckeystore. getCertifi cate(alias ); | |
2164 | if (c != null) { | |
2165 | chec kWeak("<" + newAlias + ">", c) ; | |
2166 | } | |
2167 | keyStore .setEntry( newAlias, entry, pp) ; | |
2168 | // Place the check so that o nly succes sful impor ts are blo cked. | |
2169 | // For e xample, we don't blo ck a faile d SecretEn try import . | |
2170 | if (P12K EYSTORE.eq ualsIgnore Case(store type)) { | |
2171 | if ( newPass != null && ! Arrays.equ als(newPas s, storePa ss)) { | |
2172 | throw new Exception( rb.getStri ng( | |
2173 | "T he.destina tion.pkcs1 2.keystore .has.diffe rent.store pass.and.k eypass.Ple ase.retry. with.destk eypass.spe cified.")) ; | |
2174 | } | |
2175 | } | |
2176 | return 1 ; | |
2177 | } catch (Key StoreExcep tion kse) { | |
2178 | Object[] source2 = {alias, k se.toStrin g()}; | |
2179 | MessageF ormat form = new Mes sageFormat (rb.getStr ing( | |
2180 | "Problem.i mporting.e ntry.for.a lias.alias .exception .Entry.for .alias.ali as.not.imp orted.")); | |
2181 | System.e rr.println (form.form at(source2 )); | |
2182 | return 2 ; | |
2183 | } | |
2184 | } | |
2185 | ||
2186 | privat e void doI mportKeySt oreAll(Key Store srck eystore) t hrows Exce ption { | |
2187 | ||
2188 | in t ok = 0; | |
2189 | in t count = srckeystor e.size(); | |
2190 | fo r (Enumera tion<Strin g> e = src keystore.a liases(); | |
2191 | e.hasMoreE lements(); ) { | |
2192 | String a lias = e.n extElement (); | |
2193 | int resu lt = doImp ortKeyStor eSingle(sr ckeystore, alias); | |
2194 | if (resu lt == 1) { | |
2195 | ok++ ; | |
2196 | Obje ct[] sourc e = {alias }; | |
2197 | Mess ageFormat form = new MessageFo rmat(rb.ge tString("E ntry.for.a lias.alias .successfu lly.import ed.")); | |
2198 | Syst em.err.pri ntln(form. format(sou rce)); | |
2199 | } else i f (result == 2) { | |
2200 | if ( !noprompt) { | |
2201 | String rep ly = getYe sNoReply(" Do you wan t to quit the import process? [no]: "); | |
2202 | if ("YES". equals(rep ly)) { | |
2203 | break; | |
2204 | } | |
2205 | } | |
2206 | } | |
2207 | } | |
2208 | Ob ject[] sou rce = {ok, count-ok} ; | |
2209 | Me ssageForma t form = n ew Message Format(rb. getString( | |
2210 | "Imp ort.comman d.complete d.ok.entri es.success fully.impo rted.fail. entries.fa iled.or.ca ncelled")) ; | |
2211 | Sy stem.err.p rintln(for m.format(s ource)); | |
2212 | } | |
2213 | ||
2214 | /** | |
2215 | * Pri nts all ke ystore ent ries. | |
2216 | */ | |
2217 | privat e void doP rintEntrie s(PrintStr eam out) | |
2218 | th rows Excep tion | |
2219 | { | |
2220 | ou t.println( rb.getStri ng("Keysto re.type.") + keyStor e.getType( )); | |
2221 | ou t.println( rb.getStri ng("Keysto re.provide r.") + | |
2222 | keyS tore.getPr ovider().g etName()); | |
2223 | ou t.println( ); | |
2224 | ||
2225 | Me ssageForma t form; | |
2226 | fo rm = (keyS tore.size( ) == 1) ? | |
2227 | new MessageFor mat(rb.get String | |
2228 | ("Your .keystore. contains.k eyStore.si ze.entry") ) : | |
2229 | new MessageFor mat(rb.get String | |
2230 | ("Your .keystore. contains.k eyStore.si ze.entries ")); | |
2231 | Ob ject[] sou rce = {new Integer(k eyStore.si ze())}; | |
2232 | ou t.println( form.forma t(source)) ; | |
2233 | ou t.println( ); | |
2234 | ||
2235 | fo r (Enumera tion<Strin g> e = key Store.alia ses(); | |
2236 | e.hasMoreE lements(); ) { | |
2237 | String a lias = e.n extElement (); | |
2238 | doPrintE ntry("<" + alias + " >", alias, out); | |
2239 | if (verb ose || rfc ) { | |
2240 | out. println(rb .getString ("NEWLINE" )); | |
2241 | out. println(rb .getString | |
2242 | ("STAR ")); | |
2243 | out. println(rb .getString | |
2244 | ("STAR NN")); | |
2245 | } | |
2246 | } | |
2247 | } | |
2248 | ||
2249 | privat e static < T> Iterabl e<T> e2i(f inal Enume ration<T> e) { | |
2250 | re turn new I terable<T> () { | |
2251 | @Overrid e | |
2252 | public I terator<T> iterator( ) { | |
2253 | retu rn new Ite rator<T>() { | |
2254 | @Override | |
2255 | public boo lean hasNe xt() { | |
2256 | return e.hasMore Elements() ; | |
2257 | } | |
2258 | @Override | |
2259 | public T n ext() { | |
2260 | return e.nextEle ment(); | |
2261 | } | |
2262 | public voi d remove() { | |
2263 | throw new Unsupp ortedOpera tionExcept ion("Not s upported y et."); | |
2264 | } | |
2265 | }; | |
2266 | } | |
2267 | }; | |
2268 | } | |
2269 | ||
2270 | /** | |
2271 | * Loa ds CRLs fr om a sourc e. This me thod is al so called in JarSign er. | |
2272 | * @pa ram src th e source, which mean s System.i n if null, or a URI, | |
2273 | * or a b are file p ath name | |
2274 | */ | |
2275 | public static Co llection<? extends C RL> loadCR Ls(String src) throw s Exceptio n { | |
2276 | In putStream in = null; | |
2277 | UR I uri = nu ll; | |
2278 | if (src == n ull) { | |
2279 | in = Sys tem.in; | |
2280 | } else { | |
2281 | try { | |
2282 | uri = new URI( src); | |
2283 | if ( uri.getSch eme().equa ls("ldap") ) { | |
2284 | // No inpu t stream f or LDAP | |
2285 | } el se { | |
2286 | in = uri.t oURL().ope nStream(); | |
2287 | } | |
2288 | } catch (Exception e) { | |
2289 | try { | |
2290 | in = new F ileInputSt ream(src); | |
2291 | } ca tch (Excep tion e2) { | |
2292 | if (uri == null || u ri.getSche me() == nu ll) { | |
2293 | throw e2; // M ore likely a bare fi le path | |
2294 | } else { | |
2295 | throw e; // M ore likely a protoco l or netwo rk problem | |
2296 | } | |
2297 | } | |
2298 | } | |
2299 | } | |
2300 | if (in != nu ll) { | |
2301 | try { | |
2302 | // R ead the fu ll stream before fee ding to X5 09Factory, | |
2303 | // o therwise, keytool -g encrl | ke ytool -pri ntcrl | |
2304 | // m ight not w ork proper ly, since -gencrl is slow | |
2305 | // a nd there's no data i n the pipe at the be ginning. | |
2306 | Byte ArrayOutpu tStream bo ut = new B yteArrayOu tputStream (); | |
2307 | byte [] b = new byte[4096 ]; | |
2308 | whil e (true) { | |
2309 | int len = in.read(b) ; | |
2310 | if (len < 0) break; | |
2311 | bout.write (b, 0, len ); | |
2312 | } | |
2313 | retu rn Certifi cateFactor y.getInsta nce("X509" ).generate CRLs( | |
2314 | new By teArrayInp utStream(b out.toByte Array())); | |
2315 | } finall y { | |
2316 | if ( in != Syst em.in) { | |
2317 | in.close() ; | |
2318 | } | |
2319 | } | |
2320 | } else { // must be LDAP, and uri is no t null | |
2321 | // Lazil y load LDA PCertStore Helper if present | |
2322 | CertStor eHelper he lper = Cer tStoreHelp er.getInst ance("LDAP "); | |
2323 | String p ath = uri. getPath(); | |
2324 | if (path .charAt(0) == '/') p ath = path .substring (1); | |
2325 | CertStor e s = help er.getCert Store(uri) ; | |
2326 | X509CRLS elector se l = | |
2327 | helper.wra p(new X509 CRLSelecto r(), null, path); | |
2328 | return s .getCRLs(s el); | |
2329 | } | |
2330 | } | |
2331 | ||
2332 | /** | |
2333 | * Ret urns CRLs described in a X509C ertificate 's CRLDist ributionPo ints | |
2334 | * Ext ension. On ly those c ontaining a general name of ty pe URI are read. | |
2335 | */ | |
2336 | public static Li st<CRL> re adCRLsFrom Cert(X509C ertificate cert) | |
2337 | throws E xception { | |
2338 | Li st<CRL> cr ls = new A rrayList<> (); | |
2339 | CR LDistribut ionPointsE xtension e xt = | |
2340 | X509 CertImpl.t oImpl(cert ).getCRLDi stribution PointsExte nsion(); | |
2341 | if (ext == n ull) retur n crls; | |
2342 | Li st<Distrib utionPoint > distPoin ts = | |
2343 | ext. get(CRLDis tributionP ointsExten sion.POINT S); | |
2344 | fo r (Distrib utionPoint o: distPo ints) { | |
2345 | GeneralN ames names = o.getFu llName(); | |
2346 | if (name s != null) { | |
2347 | for (GeneralNa me name: n ames.names ()) { | |
2348 | if (name.g etType() = = GeneralN ameInterfa ce.NAME_UR I) { | |
2349 | URINam e uriName = (URIName )name.getN ame(); | |
2350 | for (C RL crl: lo adCRLs(uri Name.getNa me())) { | |
2351 | if (crl inst anceof X50 9CRL) { | |
2352 | crls.add ((X509CRL) crl); | |
2353 | } | |
2354 | } | |
2355 | break; // Diffe rent name should poi nt to same CRL | |
2356 | } | |
2357 | } | |
2358 | } | |
2359 | } | |
2360 | re turn crls; | |
2361 | } | |
2362 | ||
2363 | privat e static S tring veri fyCRL(KeyS tore ks, C RL crl) | |
2364 | throws E xception { | |
2365 | X5 09CRLImpl xcrl = (X5 09CRLImpl) crl; | |
2366 | X5 00Principa l issuer = xcrl.getI ssuerX500P rincipal() ; | |
2367 | fo r (String s: e2i(ks. aliases()) ) { | |
2368 | Certific ate cert = ks.getCer tificate(s ); | |
2369 | if (cert instanceo f X509Cert ificate) { | |
2370 | X509 Certificat e xcert = (X509Certi ficate)cer t; | |
2371 | if ( xcert.getS ubjectX500 Principal( ).equals(i ssuer)) { | |
2372 | try { | |
2373 | ((X509 CRLImpl)cr l).verify( cert.getPu blicKey()) ; | |
2374 | return s; | |
2375 | } catch (E xception e ) { | |
2376 | } | |
2377 | } | |
2378 | } | |
2379 | } | |
2380 | re turn null; | |
2381 | } | |
2382 | ||
2383 | privat e void doP rintCRL(St ring src, PrintStrea m out) | |
2384 | throws E xception { | |
2385 | fo r (CRL crl : loadCRLs (src)) { | |
2386 | printCRL (crl, out) ; | |
2387 | String i ssuer = nu ll; | |
2388 | Certific ate signer = null; | |
2389 | if (caks != null) { | |
2390 | issu er = verif yCRL(caks, crl); | |
2391 | if ( issuer != null) { | |
2392 | signer = c aks.getCer tificate(i ssuer); | |
2393 | out.printf (rb.getStr ing( | |
2394 | "v erified.by .s.in.s.we ak"), | |
2395 | is suer, | |
2396 | "c acerts", | |
2397 | wi thWeak(sig ner.getPub licKey())) ; | |
2398 | out.printl n(); | |
2399 | } | |
2400 | } | |
2401 | if (issu er == null && keySto re != null ) { | |
2402 | issu er = verif yCRL(keySt ore, crl); | |
2403 | if ( issuer != null) { | |
2404 | signer = k eyStore.ge tCertifica te(issuer) ; | |
2405 | out.printf (rb.getStr ing( | |
2406 | "v erified.by .s.in.s.we ak"), | |
2407 | is suer, | |
2408 | "k eystore", | |
2409 | wi thWeak(sig ner.getPub licKey())) ; | |
2410 | out.printl n(); | |
2411 | } | |
2412 | } | |
2413 | if (issu er == null ) { | |
2414 | out. println(rb .getString | |
2415 | ("STAR ")); | |
2416 | out. println(rb .getString | |
2417 | ("warn ing.not.ve rified.mak e.sure.key store.is.c orrect")); | |
2418 | out. println(rb .getString | |
2419 | ("STAR NN")); | |
2420 | } | |
2421 | checkWea k(rb.getSt ring("the. crl"), crl , signer = = null ? n ull : sign er.getPubl icKey()); | |
2422 | } | |
2423 | } | |
2424 | ||
2425 | privat e void pri ntCRL(CRL crl, Print Stream out ) | |
2426 | throws E xception { | |
2427 | X5 09CRL xcrl = (X509CR L)crl; | |
2428 | if (rfc) { | |
2429 | out.prin tln("----- BEGIN X509 CRL-----" ); | |
2430 | out.prin tln(Base64 .getMimeEn coder(64, CRLF).enco deToString (xcrl.getE ncoded())) ; | |
2431 | out.prin tln("----- END X509 C RL-----"); | |
2432 | } else { | |
2433 | String s ; | |
2434 | if (crl instanceof X509CRLIm pl) { | |
2435 | X509 CRLImpl x5 09crl = (X 509CRLImpl ) crl; | |
2436 | s = x509crl.to StringWith AlgName(wi thWeak("" + x509crl. getSigAlgI d())); | |
2437 | } else { | |
2438 | s = crl.toStri ng(); | |
2439 | } | |
2440 | out.prin tln(s); | |
2441 | } | |
2442 | } | |
2443 | ||
2444 | privat e void doP rintCertRe q(InputStr eam in, Pr intStream out) | |
2445 | throws E xception { | |
2446 | ||
2447 | Bu fferedRead er reader = new Buff eredReader (new Input StreamRead er(in)); | |
2448 | St ringBuffer sb = new StringBuff er(); | |
2449 | bo olean star ted = fals e; | |
2450 | wh ile (true) { | |
2451 | String s = reader. readLine() ; | |
2452 | if (s == null) bre ak; | |
2453 | if (!sta rted) { | |
2454 | if ( s.startsWi th("-----" )) { | |
2455 | started = true; | |
2456 | } | |
2457 | } else { | |
2458 | if ( s.startsWi th("-----" )) { | |
2459 | break; | |
2460 | } | |
2461 | sb.a ppend(s); | |
2462 | } | |
2463 | } | |
2464 | PK CS10 req = new PKCS1 0(Pem.deco de(new Str ing(sb))); | |
2465 | ||
2466 | Pu blicKey pk ey = req.g etSubjectP ublicKeyIn fo(); | |
2467 | ou t.printf(r b.getStrin g("PKCS.10 .with.weak "), | |
2468 | req. getSubject Name(), | |
2469 | pkey .getFormat (), | |
2470 | with Weak(pkey) , | |
2471 | with Weak(req.g etSigAlg() )); | |
2472 | fo r (PKCS10A ttribute a ttr: req.g etAttribut es().getAt tributes() ) { | |
2473 | ObjectId entifier o id = attr. getAttribu teId(); | |
2474 | if (oid. equals((Ob ject)PKCS9 Attribute. EXTENSION_ REQUEST_OI D)) { | |
2475 | Cert ificateExt ensions ex ts = (Cert ificateExt ensions)at tr.getAttr ibuteValue (); | |
2476 | if ( exts != nu ll) { | |
2477 | printExten sions(rb.g etString(" Extension. Request.") , exts, ou t); | |
2478 | } | |
2479 | } else { | |
2480 | out. println("A ttribute: " + attr.g etAttribut eId()); | |
2481 | PKCS 9Attribute pkcs9Attr = | |
2482 | new PK CS9Attribu te(attr.ge tAttribute Id(), | |
2483 | attr.ge tAttribute Value()); | |
2484 | out. print(pkcs 9Attr.getN ame() + ": "); | |
2485 | Obje ct attrVal = attr.ge tAttribute Value(); | |
2486 | out. println(at trVal inst anceof Str ing[] ? | |
2487 | Ar rays.toStr ing((Strin g[]) attrV al) : | |
2488 | at trVal); | |
2489 | } | |
2490 | } | |
2491 | if (debug) { | |
2492 | out.prin tln(req); // Just to see mor e, say, pu blic key l ength... | |
2493 | } | |
2494 | ch eckWeak(rb .getString ("the.cert ificate.re quest"), r eq); | |
2495 | } | |
2496 | ||
2497 | /** | |
2498 | * Rea ds a certi ficate (or certifica te chain) and prints its conte nts in | |
2499 | * a h uman reada ble format . | |
2500 | */ | |
2501 | privat e void pri ntCertFrom Stream(Inp utStream i n, PrintSt ream out) | |
2502 | th rows Excep tion | |
2503 | { | |
2504 | Co llection<? extends C ertificate > c = null ; | |
2505 | tr y { | |
2506 | c = cf.g enerateCer tificates( in); | |
2507 | } catch (Cer tificateEx ception ce ) { | |
2508 | throw ne w Exceptio n(rb.getSt ring("Fail ed.to.pars e.input"), ce); | |
2509 | } | |
2510 | if (c.isEmpt y()) { | |
2511 | throw ne w Exceptio n(rb.getSt ring("Empt y.input")) ; | |
2512 | } | |
2513 | Ce rtificate[ ] certs = c.toArray( new Certif icate[c.si ze()]); | |
2514 | fo r (int i=0 ; i<certs. length; i+ +) { | |
2515 | X509Cert ificate x5 09Cert = n ull; | |
2516 | try { | |
2517 | x509 Cert = (X5 09Certific ate)certs[ i]; | |
2518 | } catch (ClassCast Exception cce) { | |
2519 | thro w new Exce ption(rb.g etString(" Not.X.509. certificat e")); | |
2520 | } | |
2521 | if (cert s.length > 1) { | |
2522 | Mess ageFormat form = new MessageFo rmat | |
2523 | (rb.ge tString("C ertificate .i.1.")); | |
2524 | Obje ct[] sourc e = {new I nteger(i + 1)}; | |
2525 | out. println(fo rm.format( source)); | |
2526 | } | |
2527 | if (rfc) | |
2528 | dump Cert(x509C ert, out); | |
2529 | else | |
2530 | prin tX509Cert( x509Cert, out); | |
2531 | if (i < (certs.len gth-1)) { | |
2532 | out. println(); | |
2533 | } | |
2534 | checkWea k(oneInMan y(rb.getSt ring("the. certificat e"), i, ce rts.length ), x509Cer t); | |
2535 | } | |
2536 | } | |
2537 | ||
2538 | privat e static S tring oneI nMany(Stri ng label, int i, int num) { | |
2539 | if (num == 1 ) { | |
2540 | return l abel; | |
2541 | } else { | |
2542 | return S tring.form at(rb.getS tring("one .in.many") , label, i +1, num); | |
2543 | } | |
2544 | } | |
2545 | ||
2546 | privat e void doP rintCert(f inal Print Stream out ) throws E xception { | |
2547 | if (jarfile != null) { | |
2548 | JarFile jf = new J arFile(jar file, true ); | |
2549 | Enumerat ion<JarEnt ry> entrie s = jf.ent ries(); | |
2550 | Set<Code Signer> ss = new Has hSet<>(); | |
2551 | byte[] b uffer = ne w byte[819 2]; | |
2552 | int pos = 0; | |
2553 | while (e ntries.has MoreElemen ts()) { | |
2554 | JarE ntry je = entries.ne xtElement( ); | |
2555 | try (InputStre am is = jf .getInputS tream(je)) { | |
2556 | while (is. read(buffe r) != -1) { | |
2557 | // we just read. this will throw a S ecurityExc eption | |
2558 | // if a signatur e/digest c heck fails . This als o | |
2559 | // pop ulate the signers | |
2560 | } | |
2561 | } | |
2562 | Code Signer[] s igners = j e.getCodeS igners(); | |
2563 | if ( signers != null) { | |
2564 | for (CodeS igner sign er: signer s) { | |
2565 | if (!s s.contains (signer)) { | |
2566 | ss .add(signe r); | |
2567 | ou t.printf(r b.getStrin g("Signer. d."), ++po s); | |
2568 | ou t.println( ); | |
2569 | ou t.println( ); | |
2570 | ou t.println( rb.getStri ng("Signat ure.")); | |
2571 | ou t.println( ); | |
2572 | ||
2573 | Li st<? exten ds Certifi cate> cert s | |
2574 | = si gner.getSi gnerCertPa th().getCe rtificates (); | |
2575 | in t cc = 0; | |
2576 | fo r (Certifi cate cert: certs) { | |
2577 | X509Cert ificate x = (X509Cer tificate)c ert; | |
2578 | if (rfc) { | |
2579 | out. println(rb .getString ("Certific ate.owner. ") + x.get SubjectDN( ) + "\n"); | |
2580 | dump Cert(x, ou t); | |
2581 | } else { | |
2582 | prin tX509Cert( x, out); | |
2583 | } | |
2584 | out.prin tln(); | |
2585 | checkWea k(oneInMan y(rb.getSt ring("the. certificat e"), cc++, certs.siz e()), x); | |
2586 | } | |
2587 | Ti mestamp ts = signer. getTimesta mp(); | |
2588 | if (ts != nu ll) { | |
2589 | out.prin tln(rb.get String("Ti mestamp.") ); | |
2590 | out.prin tln(); | |
2591 | certs = ts.getSign erCertPath ().getCert ificates() ; | |
2592 | cc = 0; | |
2593 | for (Cer tificate c ert: certs ) { | |
2594 | X509 Certificat e x = (X50 9Certifica te)cert; | |
2595 | if ( rfc) { | |
2596 | out.printl n(rb.getSt ring("Cert ificate.ow ner.") + x .getSubjec tDN() + "\ n"); | |
2597 | dumpCert(x , out); | |
2598 | } el se { | |
2599 | printX509C ert(x, out ); | |
2600 | } | |
2601 | out. println(); | |
2602 | chec kWeak(oneI nMany(rb.g etString(" the.tsa.ce rtificate" ), cc++, c erts.size( )), x); | |
2603 | } | |
2604 | } | |
2605 | } | |
2606 | } | |
2607 | } | |
2608 | } | |
2609 | jf.close (); | |
2610 | if (ss.i sEmpty()) { | |
2611 | out. println(rb .getString ("Not.a.si gned.jar.f ile")); | |
2612 | } | |
2613 | } else if (s slserver ! = null) { | |
2614 | // Lazil y load SSL CertStoreH elper if p resent | |
2615 | CertStor eHelper he lper = Cer tStoreHelp er.getInst ance("SSLS erver"); | |
2616 | CertStor e cs = hel per.getCer tStore(new URI("http s://" + ss lserver)); | |
2617 | Collecti on<? exten ds Certifi cate> chai n; | |
2618 | try { | |
2619 | chai n = cs.get Certificat es(null); | |
2620 | if ( chain.isEm pty()) { | |
2621 | // If the certs are not retrie ved, we co nsider it an error | |
2622 | // even if the URL c onnection is success ful. | |
2623 | throw new Exception( rb.getStri ng( | |
2624 | "No.certif icate.from .the.SSL.s erver")); | |
2625 | } | |
2626 | } catch (CertStore Exception cse) { | |
2627 | if ( cse.getCau se() insta nceof IOEx ception) { | |
2628 | throw new Exception( rb.getStri ng( | |
2629 | "No.certif icate.from .the.SSL.s erver"), | |
2630 | cse.getCau se()); | |
2631 | } el se { | |
2632 | throw cse; | |
2633 | } | |
2634 | } | |
2635 | ||
2636 | int i = 0; | |
2637 | for (Cer tificate c ert : chai n) { | |
2638 | try { | |
2639 | if (rfc) { | |
2640 | dumpCe rt(cert, o ut); | |
2641 | } else { | |
2642 | out.pr intln("Cer tificate # " + i++); | |
2643 | out.pr intln("=== ========== ========== ========== ==="); | |
2644 | printX 509Cert((X 509Certifi cate)cert, out); | |
2645 | out.pr intln(); | |
2646 | } | |
2647 | checkWeak( oneInMany( rb.getStri ng("the.ce rtificate" ), i, chai n.size()), cert); | |
2648 | } ca tch (Excep tion e) { | |
2649 | if (debug) { | |
2650 | e.prin tStackTrac e(); | |
2651 | } | |
2652 | } | |
2653 | } | |
2654 | } else { | |
2655 | if (file name != nu ll) { | |
2656 | try (FileInput Stream inS tream = ne w FileInpu tStream(fi lename)) { | |
2657 | printCertF romStream( inStream, out); | |
2658 | } | |
2659 | } else { | |
2660 | prin tCertFromS tream(Syst em.in, out ); | |
2661 | } | |
2662 | } | |
2663 | } | |
2664 | /** | |
2665 | * Cre ates a sel f-signed c ertificate , and stor es it as a single-el ement | |
2666 | * cer tificate c hain. | |
2667 | */ | |
2668 | privat e void doS elfCert(St ring alias , String d name, Stri ng sigAlgN ame) | |
2669 | th rows Excep tion | |
2670 | { | |
2671 | if (alias == null) { | |
2672 | alias = keyAlias; | |
2673 | } | |
2674 | ||
2675 | Pa ir<Key,cha r[]> objs = recoverK ey(alias, storePass, keyPass); | |
2676 | Pr ivateKey p rivKey = ( PrivateKey )objs.fst; | |
2677 | if (keyPass == null) | |
2678 | keyPass = objs.snd ; | |
2679 | ||
2680 | // Determine the signa ture algor ithm | |
2681 | if (sigAlgNa me == null ) { | |
2682 | sigAlgNa me = getCo mpatibleSi gAlgName(p rivKey.get Algorithm( )); | |
2683 | } | |
2684 | ||
2685 | // Get the o ld certifi cate | |
2686 | Ce rtificate oldCert = keyStore.g etCertific ate(alias) ; | |
2687 | if (oldCert == null) { | |
2688 | MessageF ormat form = new Mes sageFormat | |
2689 | (rb. getString( "alias.has .no.public .key")); | |
2690 | Object[] source = {alias}; | |
2691 | throw ne w Exceptio n(form.for mat(source )); | |
2692 | } | |
2693 | if (!(oldCer t instance of X509Cer tificate)) { | |
2694 | MessageF ormat form = new Mes sageFormat | |
2695 | (rb. getString( "alias.has .no.X.509. certificat e")); | |
2696 | Object[] source = {alias}; | |
2697 | throw ne w Exceptio n(form.for mat(source )); | |
2698 | } | |
2699 | ||
2700 | // convert t o X509Cert Impl, so t hat we can modify se lected fie lds | |
2701 | // (no publi c APIs ava ilable yet ) | |
2702 | by te[] encod ed = oldCe rt.getEnco ded(); | |
2703 | X5 09CertImpl certImpl = new X509 CertImpl(e ncoded); | |
2704 | X5 09CertInfo certInfo = (X509Cer tInfo)cert Impl.get(X 509CertImp l.NAME | |
2705 | + "." + | |
2706 | X 509CertImp l.INFO); | |
2707 | ||
2708 | // Extend it s validity | |
2709 | Da te firstDa te = getSt artDate(st artDate); | |
2710 | Da te lastDat e = new Da te(); | |
2711 | la stDate.set Time(first Date.getTi me() + val idity*1000 L*24L*60L* 60L); | |
2712 | Ce rtificateV alidity in terval = n ew Certifi cateValidi ty(firstDa te, | |
2713 | lastDat e); | |
2714 | ce rtInfo.set (X509CertI nfo.VALIDI TY, interv al); | |
2715 | ||
2716 | // Make new serial num ber | |
2717 | ce rtInfo.set (X509CertI nfo.SERIAL _NUMBER, n ew Certifi cateSerial Number( | |
2718 | new java.u til.Random ().nextInt () & 0x7ff fffff)); | |
2719 | ||
2720 | // Set owner and issue r fields | |
2721 | X5 00Name own er; | |
2722 | if (dname == null) { | |
2723 | // Get t he owner n ame from t he certifi cate | |
2724 | owner = (X500Name) certInfo.g et(X509Cer tInfo.SUBJ ECT + "." + | |
2725 | X509Cer tInfo.DN_N AME); | |
2726 | } else { | |
2727 | // Use t he owner n ame specif ied at the command l ine | |
2728 | owner = new X500Na me(dname); | |
2729 | certInfo .set(X509C ertInfo.SU BJECT + ". " + | |
2730 | X509C ertInfo.DN _NAME, own er); | |
2731 | } | |
2732 | // Make issu er same as owner (se lf-signed! ) | |
2733 | ce rtInfo.set (X509CertI nfo.ISSUER + "." + | |
2734 | X509CertI nfo.DN_NAM E, owner); | |
2735 | ||
2736 | // The inner and outer signature algorithm s have to match. | |
2737 | // The way w e achieve that is re ally ugly, but there seems to be no | |
2738 | // other sol ution: We first sign the cert, then retr ieve the | |
2739 | // outer sig alg and us e it to se t the inne r sigalg | |
2740 | X5 09CertImpl newCert = new X509C ertImpl(ce rtInfo); | |
2741 | ne wCert.sign (privKey, sigAlgName ); | |
2742 | Al gorithmId sigAlgid = (Algorith mId)newCer t.get(X509 CertImpl.S IG_ALG); | |
2743 | ce rtInfo.set (Certifica teAlgorith mId.NAME + "." + | |
2744 | Certifica teAlgorith mId.ALGORI THM, sigAl gid); | |
2745 | ||
2746 | ce rtInfo.set (X509CertI nfo.VERSIO N, | |
2747 | new Ce rtificateV ersion(Cer tificateVe rsion.V3)) ; | |
2748 | ||
2749 | Ce rtificateE xtensions ext = crea teV3Extens ions( | |
2750 | null , | |
2751 | (Cer tificateEx tensions)c ertInfo.ge t(X509Cert Info.EXTEN SIONS), | |
2752 | v3ex t, | |
2753 | oldC ert.getPub licKey(), | |
2754 | null ); | |
2755 | ce rtInfo.set (X509CertI nfo.EXTENS IONS, ext) ; | |
2756 | // Sign the new certif icate | |
2757 | ne wCert = ne w X509Cert Impl(certI nfo); | |
2758 | ne wCert.sign (privKey, sigAlgName ); | |
2759 | ||
2760 | // Store the new certi ficate as a single-e lement cer tificate c hain | |
2761 | ke yStore.set KeyEntry(a lias, priv Key, | |
2762 | ( keyPass != null) ? k eyPass : s torePass, | |
2763 | n ew Certifi cate[] { n ewCert } ) ; | |
2764 | ||
2765 | if (verbose) { | |
2766 | System.e rr.println (rb.getStr ing("New.c ertificate .self.sign ed.")); | |
2767 | System.e rr.print(n ewCert.toS tring()); | |
2768 | System.e rr.println (); | |
2769 | } | |
2770 | } | |
2771 | ||
2772 | /** | |
2773 | * Pro cesses a c ertificate reply fro m a certif icate auth ority. | |
2774 | * | |
2775 | * <p> Builds a c ertificate chain on top of the certifica te reply, | |
2776 | * usi ng trusted certifica tes from t he keystor e. The cha in is comp lete | |
2777 | * aft er a self- signed cer tificate h as been en countered. The self- signed | |
2778 | * cer tificate i s consider ed a root certificat e authorit y, and is stored | |
2779 | * at the end of the chain . | |
2780 | * | |
2781 | * <p> The newly generated chain repl aces the o ld chain a ssociated with the | |
2782 | * key entry. | |
2783 | * | |
2784 | * @re turn true if the cer tificate r eply was i nstalled, otherwise false. | |
2785 | */ | |
2786 | privat e boolean installRep ly(String alias, Inp utStream i n) | |
2787 | th rows Excep tion | |
2788 | { | |
2789 | if (alias == null) { | |
2790 | alias = keyAlias; | |
2791 | } | |
2792 | ||
2793 | Pa ir<Key,cha r[]> objs = recoverK ey(alias, storePass, keyPass); | |
2794 | Pr ivateKey p rivKey = ( PrivateKey )objs.fst; | |
2795 | if (keyPass == null) { | |
2796 | keyPass = objs.snd ; | |
2797 | } | |
2798 | ||
2799 | Ce rtificate userCert = keyStore. getCertifi cate(alias ); | |
2800 | if (userCert == null) { | |
2801 | MessageF ormat form = new Mes sageFormat | |
2802 | (rb. getString( "alias.has .no.public .key.certi ficate.")) ; | |
2803 | Object[] source = {alias}; | |
2804 | throw ne w Exceptio n(form.for mat(source )); | |
2805 | } | |
2806 | ||
2807 | // Read the certificat es in the reply | |
2808 | Co llection<? extends C ertificate > c = cf.g enerateCer tificates( in); | |
2809 | if (c.isEmpt y()) { | |
2810 | throw ne w Exceptio n(rb.getSt ring("Repl y.has.no.c ertificate s")); | |
2811 | } | |
2812 | Ce rtificate[ ] replyCer ts = c.toA rray(new C ertificate [c.size()] ); | |
2813 | Ce rtificate[ ] newChain ; | |
2814 | if (replyCer ts.length == 1) { | |
2815 | // singl e-cert rep ly | |
2816 | newChain = establi shCertChai n(userCert , replyCer ts[0]); | |
2817 | } else { | |
2818 | // cert- chain repl y (e.g., P KCS#7) | |
2819 | newChain = validat eReply(ali as, userCe rt, replyC erts); | |
2820 | } | |
2821 | ||
2822 | // Now store the newly establish ed chain i n the keys tore. The new | |
2823 | // chain rep laces the old one. T he chain c an be null if user c hooses no. | |
2824 | if (newChain != null) { | |
2825 | keyStore .setKeyEnt ry(alias, privKey, | |
2826 | (keyPas s != null) ? keyPass : storePa ss, | |
2827 | newChai n); | |
2828 | return t rue; | |
2829 | } else { | |
2830 | return f alse; | |
2831 | } | |
2832 | } | |
2833 | ||
2834 | /** | |
2835 | * Imp orts a cer tificate a nd adds it to the li st of trus ted certif icates. | |
2836 | * | |
2837 | * @re turn true if the cer tificate w as added, otherwise false. | |
2838 | */ | |
2839 | privat e boolean addTrusted Cert(Strin g alias, I nputStream in) | |
2840 | th rows Excep tion | |
2841 | { | |
2842 | if (alias == null) { | |
2843 | throw ne w Exceptio n(rb.getSt ring("Must .specify.a lias")); | |
2844 | } | |
2845 | if (keyStore .containsA lias(alias )) { | |
2846 | MessageF ormat form = new Mes sageFormat (rb.getStr ing | |
2847 | ("Ce rtificate. not.import ed.alias.a lias.alrea dy.exists" )); | |
2848 | Object[] source = {alias}; | |
2849 | throw ne w Exceptio n(form.for mat(source )); | |
2850 | } | |
2851 | ||
2852 | // Read the certificat e | |
2853 | X5 09Certific ate cert = null; | |
2854 | tr y { | |
2855 | cert = ( X509Certif icate)cf.g enerateCer tificate(i n); | |
2856 | } catch (Cla ssCastExce ption | Ce rtificateE xception c e) { | |
2857 | throw ne w Exceptio n(rb.getSt ring("Inpu t.not.an.X .509.certi ficate")); | |
2858 | } | |
2859 | ||
2860 | if (noprompt ) { | |
2861 | checkWea k(rb.getSt ring("the. input"), c ert); | |
2862 | keyStore .setCertif icateEntry (alias, ce rt); | |
2863 | return t rue; | |
2864 | } | |
2865 | ||
2866 | // if certif icate is s elf-signed , make sur e it verif ies | |
2867 | bo olean self Signed = f alse; | |
2868 | if (isSelfSi gned(cert) ) { | |
2869 | cert.ver ify(cert.g etPublicKe y()); | |
2870 | selfSign ed = true; | |
2871 | } | |
2872 | ||
2873 | // check if cert alrea dy exists in keystor e | |
2874 | St ring reply = null; | |
2875 | St ring trust alias = ke yStore.get Certificat eAlias(cer t); | |
2876 | if (trustali as != null ) { | |
2877 | MessageF ormat form = new Mes sageFormat (rb.getStr ing | |
2878 | ("Ce rtificate. already.ex ists.in.ke ystore.und er.alias.t rustalias. ")); | |
2879 | Object[] source = {trustalia s}; | |
2880 | System.e rr.println (form.form at(source) ); | |
2881 | checkWea k(rb.getSt ring("the. input"), c ert); | |
2882 | printWea kWarnings( true); | |
2883 | reply = getYesNoRe ply | |
2884 | (rb. getString( "Do.you.st ill.want.t o.add.it.n o.")); | |
2885 | } else if (s elfSigned) { | |
2886 | if (trus tcacerts & & (caks != null) && | |
2887 | ((trustali as=caks.ge tCertifica teAlias(ce rt)) != nu ll)) { | |
2888 | Mess ageFormat form = new MessageFo rmat(rb.ge tString | |
2889 | ("Cert ificate.al ready.exis ts.in.syst em.wide.CA .keystore. under.alia s.trustali as.")); | |
2890 | Obje ct[] sourc e = {trust alias}; | |
2891 | Syst em.err.pri ntln(form. format(sou rce)); | |
2892 | chec kWeak(rb.g etString(" the.input" ), cert); | |
2893 | prin tWeakWarni ngs(true); | |
2894 | repl y = getYes NoReply | |
2895 | (rb.ge tString("D o.you.stil l.want.to. add.it.to. your.own.k eystore.no .")); | |
2896 | } | |
2897 | if (trus talias == null) { | |
2898 | // P rint the c ert and as k user if they reall y want to add | |
2899 | // i t to their keystore | |
2900 | prin tX509Cert( cert, Syst em.out); | |
2901 | chec kWeak(rb.g etString(" the.input" ), cert); | |
2902 | prin tWeakWarni ngs(true); | |
2903 | repl y = getYes NoReply | |
2904 | (rb.ge tString("T rust.this. certificat e.no.")); | |
2905 | } | |
2906 | } | |
2907 | if (reply != null) { | |
2908 | if ("YES ".equals(r eply)) { | |
2909 | keyS tore.setCe rtificateE ntry(alias , cert); | |
2910 | retu rn true; | |
2911 | } else { | |
2912 | retu rn false; | |
2913 | } | |
2914 | } | |
2915 | ||
2916 | // Not found in this k eystore an d not self -signed | |
2917 | // Try to es tablish tr ust chain | |
2918 | tr y { | |
2919 | Certific ate[] chai n = establ ishCertCha in(null, c ert); | |
2920 | if (chai n != null) { | |
2921 | keyS tore.setCe rtificateE ntry(alias , cert); | |
2922 | retu rn true; | |
2923 | } | |
2924 | } catch (Exc eption e) { | |
2925 | // Print the cert and ask us er if they really wa nt to add it to | |
2926 | // their keystore | |
2927 | printX50 9Cert(cert , System.o ut); | |
2928 | checkWea k(rb.getSt ring("the. input"), c ert); | |
2929 | printWea kWarnings( true); | |
2930 | reply = getYesNoRe ply | |
2931 | (rb. getString( "Trust.thi s.certific ate.no.")) ; | |
2932 | if ("YES ".equals(r eply)) { | |
2933 | keyS tore.setCe rtificateE ntry(alias , cert); | |
2934 | retu rn true; | |
2935 | } else { | |
2936 | retu rn false; | |
2937 | } | |
2938 | } | |
2939 | ||
2940 | re turn false ; | |
2941 | } | |
2942 | ||
2943 | /** | |
2944 | * Pro mpts user for new pa ssword. Ne w password must be d ifferent f rom | |
2945 | * old one. | |
2946 | * | |
2947 | * @pa ram prompt the messa ge that ge ts prompte d on the s creen | |
2948 | * @pa ram oldPas swd the cu rrent (i.e ., old) pa ssword | |
2949 | */ | |
2950 | privat e char[] g etNewPassw d(String p rompt, cha r[] oldPas swd) | |
2951 | th rows Excep tion | |
2952 | { | |
2953 | ch ar[] enter ed = null; | |
2954 | ch ar[] reent ered = nul l; | |
2955 | ||
2956 | fo r (int cou nt = 0; co unt < 3; c ount++) { | |
2957 | MessageF ormat form = new Mes sageFormat | |
2958 | (rb. getString( "New.promp t.")); | |
2959 | Object[] source = {prompt}; | |
2960 | System.e rr.print(f orm.format (source)); | |
2961 | entered = Password .readPassw ord(System .in); | |
2962 | password s.add(ente red); | |
2963 | if (ente red == nul l || enter ed.length < 6) { | |
2964 | Syst em.err.pri ntln(rb.ge tString | |
2965 | ("Password .is.too.sh ort.must.b e.at.least .6.charact ers")); | |
2966 | } else i f (Arrays. equals(ent ered, oldP asswd)) { | |
2967 | Syst em.err.pri ntln(rb.ge tString("P asswords.m ust.differ ")); | |
2968 | } else { | |
2969 | form = new Mes sageFormat | |
2970 | (rb.ge tString("R e.enter.ne w.prompt." )); | |
2971 | Obje ct[] src = {prompt}; | |
2972 | Syst em.err.pri nt(form.fo rmat(src)) ; | |
2973 | reen tered = Pa ssword.rea dPassword( System.in) ; | |
2974 | pass words.add( reentered) ; | |
2975 | if ( !Arrays.eq uals(enter ed, reente red)) { | |
2976 | System.err .println | |
2977 | (rb.ge tString("T hey.don.t. match.Try. again")); | |
2978 | } el se { | |
2979 | Arrays.fil l(reentere d, ' '); | |
2980 | return ent ered; | |
2981 | } | |
2982 | } | |
2983 | if (ente red != nul l) { | |
2984 | Arra ys.fill(en tered, ' ' ); | |
2985 | ente red = null ; | |
2986 | } | |
2987 | if (reen tered != n ull) { | |
2988 | Arra ys.fill(re entered, ' '); | |
2989 | reen tered = nu ll; | |
2990 | } | |
2991 | } | |
2992 | th row new Ex ception(rb .getString ("Too.many .failures. try.later" )); | |
2993 | } | |
2994 | ||
2995 | /** | |
2996 | * Pro mpts user for alias name. | |
2997 | * @pa ram prompt the {0} o f "Enter { 0} alias n ame: " in prompt li ne | |
2998 | * @re turns the string ent ered by th e user, wi thout the \n at the end | |
2999 | */ | |
3000 | privat e String g etAlias(St ring promp t) throws Exception { | |
3001 | if (prompt ! = null) { | |
3002 | MessageF ormat form = new Mes sageFormat | |
3003 | (rb. getString( "Enter.pro mpt.alias. name.")); | |
3004 | Object[] source = {prompt}; | |
3005 | System.e rr.print(f orm.format (source)); | |
3006 | } else { | |
3007 | System.e rr.print(r b.getStrin g("Enter.a lias.name. ")); | |
3008 | } | |
3009 | re turn (new BufferedRe ader(new I nputStream Reader( | |
3010 | System.in) )).readLin e(); | |
3011 | } | |
3012 | ||
3013 | /** | |
3014 | * Pro mpts user for an inp ut string from the c ommand lin e (System. in) | |
3015 | * @pr ompt the p rompt stri ng printed | |
3016 | * @re turns the string ent ered by th e user, wi thout the \n at the end | |
3017 | */ | |
3018 | privat e String i nputString FromStdin( String pro mpt) throw s Exceptio n { | |
3019 | Sy stem.err.p rint(promp t); | |
3020 | re turn (new BufferedRe ader(new I nputStream Reader( | |
3021 | System.in) )).readLin e(); | |
3022 | } | |
3023 | ||
3024 | /** | |
3025 | * Pro mpts user for key pa ssword. Us er may sel ect to cho ose the sa me | |
3026 | * pas sword (<co de>otherKe yPass</cod e>) as for <code>oth erAlias</c ode>. | |
3027 | */ | |
3028 | privat e char[] g etKeyPassw d(String a lias, Stri ng otherAl ias, | |
3029 | char[] o therKeyPas s) | |
3030 | th rows Excep tion | |
3031 | { | |
3032 | in t count = 0; | |
3033 | ch ar[] keyPa ss = null; | |
3034 | ||
3035 | do { | |
3036 | if (othe rKeyPass ! = null) { | |
3037 | Mess ageFormat form = new MessageFo rmat(rb.ge tString | |
3038 | ("Ente r.key.pass word.for.a lias.")); | |
3039 | Obje ct[] sourc e = {alias }; | |
3040 | Syst em.err.pri ntln(form. format(sou rce)); | |
3041 | ||
3042 | form = new Mes sageFormat (rb.getStr ing | |
3043 | (".RET URN.if.sam e.as.for.o therAlias. ")); | |
3044 | Obje ct[] src = {otherAli as}; | |
3045 | Syst em.err.pri nt(form.fo rmat(src)) ; | |
3046 | } else { | |
3047 | Mess ageFormat form = new MessageFo rmat(rb.ge tString | |
3048 | ("Ente r.key.pass word.for.a lias.")); | |
3049 | Obje ct[] sourc e = {alias }; | |
3050 | Syst em.err.pri nt(form.fo rmat(sourc e)); | |
3051 | } | |
3052 | System.e rr.flush() ; | |
3053 | keyPass = Password .readPassw ord(System .in); | |
3054 | password s.add(keyP ass); | |
3055 | if (keyP ass == nul l) { | |
3056 | keyP ass = othe rKeyPass; | |
3057 | } | |
3058 | count++; | |
3059 | } while ((ke yPass == n ull) && co unt < 3); | |
3060 | ||
3061 | if (keyPass == null) { | |
3062 | throw ne w Exceptio n(rb.getSt ring("Too. many.failu res.try.la ter")); | |
3063 | } | |
3064 | ||
3065 | re turn keyPa ss; | |
3066 | } | |
3067 | ||
3068 | privat e String w ithWeak(St ring alg) { | |
3069 | if (DISABLED _CHECK.per mits(SIG_P RIMITIVE_S ET, alg, n ull)) { | |
3070 | return a lg; | |
3071 | } else { | |
3072 | return S tring.form at(rb.getS tring("wit h.weak"), alg); | |
3073 | } | |
3074 | } | |
3075 | ||
3076 | privat e String w ithWeak(Pu blicKey ke y) { | |
3077 | if (DISABLED _CHECK.per mits(SIG_P RIMITIVE_S ET, key)) { | |
3078 | return S tring.form at(rb.getS tring("key .bit"), | |
3079 | KeyUtil.ge tKeySize(k ey), key.g etAlgorith m()); | |
3080 | } else { | |
3081 | return S tring.form at(rb.getS tring("key .bit.weak" ), | |
3082 | KeyUtil.ge tKeySize(k ey), key.g etAlgorith m()); | |
3083 | } | |
3084 | } | |
3085 | ||
3086 | /** | |
3087 | * Pri nts a cert ificate in a human r eadable fo rmat. | |
3088 | */ | |
3089 | privat e void pri ntX509Cert (X509Certi ficate cer t, PrintSt ream out) | |
3090 | th rows Excep tion | |
3091 | { | |
3092 | /* | |
3093 | ou t.println( "Owner: " | |
3094 | + cert.get SubjectDN( ).toString () | |
3095 | + "\n" | |
3096 | + "Issuer: " | |
3097 | + cert.get IssuerDN() .toString( ) | |
3098 | + "\n" | |
3099 | + "Serial number: " + cert.get SerialNumb er().toStr ing(16) | |
3100 | + "\n" | |
3101 | + "Valid f rom: " + c ert.getNot Before().t oString() | |
3102 | + " until: " + cert. getNotAfte r().toStri ng() | |
3103 | + "\n" | |
3104 | + "Certifi cate finge rprints:\n " | |
3105 | + "\t MD5: " + getC ertFingerP rint("MD5" , cert) | |
3106 | + "\n" | |
3107 | + "\t SHA1 : " + getC ertFingerP rint("SHA1 ", cert)); | |
3108 | */ | |
3109 | ||
3110 | Me ssageForma t form = n ew Message Format | |
3111 | (rb. getString( ".PATTERN. printX509C ert.with.w eak")); | |
3112 | Pu blicKey pk ey = cert. getPublicK ey(); | |
3113 | St ring sigNa me = cert. getSigAlgN ame(); | |
3114 | // No need t o warn abo ut sigalg of a trust anchor | |
3115 | if (!isTrust edCert(cer t)) { | |
3116 | sigName = withWeak (sigName); | |
3117 | } | |
3118 | Ob ject[] sou rce = {cer t.getSubje ctDN().toS tring(), | |
3119 | cert.g etIssuerDN ().toStrin g(), | |
3120 | cert.g etSerialNu mber().toS tring(16), | |
3121 | cert.g etNotBefor e().toStri ng(), | |
3122 | cert.g etNotAfter ().toStrin g(), | |
3123 | getCer tFingerPri nt("MD5", cert), | |
3124 | getCer tFingerPri nt("SHA1", cert), | |
3125 | getCer tFingerPri nt("SHA-25 6", cert), | |
3126 | sigNam e, | |
3127 | withWe ak(pkey), | |
3128 | cert.g etVersion( ) | |
3129 | }; | |
3130 | ou t.println( form.forma t(source)) ; | |
3131 | ||
3132 | if (cert ins tanceof X5 09CertImpl ) { | |
3133 | X509Cert Impl impl = (X509Cer tImpl)cert ; | |
3134 | X509Cert Info certI nfo = (X50 9CertInfo) impl.get(X 509CertImp l.NAME | |
3135 | + "." + | |
3136 | X 509CertImp l.INFO); | |
3137 | Certific ateExtensi ons exts = (Certific ateExtensi ons) | |
3138 | certInfo.g et(X509Cer tInfo.EXTE NSIONS); | |
3139 | if (exts != null) { | |
3140 | prin tExtension s(rb.getSt ring("Exte nsions."), exts, out ); | |
3141 | } | |
3142 | } | |
3143 | } | |
3144 | ||
3145 | privat e static v oid printE xtensions( String tit le, Certif icateExten sions exts , PrintStr eam out) | |
3146 | throws E xception { | |
3147 | in t extnum = 0; | |
3148 | It erator<Ext ension> i1 = exts.ge tAllExtens ions().ite rator(); | |
3149 | It erator<Ext ension> i2 = exts.ge tUnparseab leExtensio ns().value s().iterat or(); | |
3150 | wh ile (i1.ha sNext() || i2.hasNex t()) { | |
3151 | Extensio n ext = i1 .hasNext() ?i1.next() :i2.next() ; | |
3152 | if (extn um == 0) { | |
3153 | out. println(); | |
3154 | out. println(ti tle); | |
3155 | out. println(); | |
3156 | } | |
3157 | out.prin t("#"+(++e xtnum)+": "+ ext); | |
3158 | if (ext. getClass() == Extens ion.class) { | |
3159 | byte [] v = ext .getExtens ionValue() ; | |
3160 | if ( v.length = = 0) { | |
3161 | out.printl n(rb.getSt ring(".Emp ty.value." )); | |
3162 | } el se { | |
3163 | new sun.mi sc.HexDump Encoder(). encodeBuff er(ext.get ExtensionV alue(), ou t); | |
3164 | out.printl n(); | |
3165 | } | |
3166 | } | |
3167 | out.prin tln(); | |
3168 | } | |
3169 | } | |
3170 | ||
3171 | /** | |
3172 | * Ret urns true if the cer tificate i s self-sig ned, false otherwise . | |
3173 | */ | |
3174 | privat e boolean isSelfSign ed(X509Cer tificate c ert) { | |
3175 | re turn signe dBy(cert, cert); | |
3176 | } | |
3177 | ||
3178 | privat e boolean signedBy(X 509Certifi cate end, X509Certif icate ca) { | |
3179 | if (!ca.getS ubjectDN() .equals(en d.getIssue rDN())) { | |
3180 | return f alse; | |
3181 | } | |
3182 | tr y { | |
3183 | end.veri fy(ca.getP ublicKey() ); | |
3184 | return t rue; | |
3185 | } catch (Exc eption e) { | |
3186 | return f alse; | |
3187 | } | |
3188 | } | |
3189 | ||
3190 | /** | |
3191 | * Loc ates a sig ner for a given cert ificate fr om a given keystore and | |
3192 | * ret urns the s igner's ce rtificate. | |
3193 | * @pa ram cert t he certifi cate whose signer is searched, not null | |
3194 | * @pa ram ks the keystore to search with, not null | |
3195 | * @re turn <code >cert</cod e> itself if it's al ready insi de <code>k s</code>, | |
3196 | * or a certific ate inside <code>ks< /code> who signs <co de>cert</c ode>, | |
3197 | * or null other wise. A la bel is add ed. | |
3198 | */ | |
3199 | privat e static P air<String ,Certifica te> | |
3200 | getSigne r(Certific ate cert, KeyStore k s) throws Exception { | |
3201 | if (ks.getCe rtificateA lias(cert) != null) { | |
3202 | return n ew Pair<>( "", cert); | |
3203 | } | |
3204 | fo r (Enumera tion<Strin g> aliases = ks.alia ses(); | |
3205 | alia ses.hasMor eElements( ); ) { | |
3206 | String n ame = alia ses.nextEl ement(); | |
3207 | Certific ate truste dCert = ks .getCertif icate(name ); | |
3208 | if (trus tedCert != null) { | |
3209 | try { | |
3210 | cert.verif y(trustedC ert.getPub licKey()); | |
3211 | return new Pair<>(na me, truste dCert); | |
3212 | } ca tch (Excep tion e) { | |
3213 | // Not ver ified, ski p to the n ext one | |
3214 | } | |
3215 | } | |
3216 | } | |
3217 | re turn null; | |
3218 | } | |
3219 | ||
3220 | /** | |
3221 | * Get s an X.500 name suit able for i nclusion i n a certif ication re quest. | |
3222 | */ | |
3223 | privat e X500Name getX500Na me() throw s IOExcept ion { | |
3224 | Bu fferedRead er in; | |
3225 | in = new Buf feredReade r(new Inpu tStreamRea der(System .in)); | |
3226 | St ring commo nName = "U nknown"; | |
3227 | St ring organ izationalU nit = "Unk nown"; | |
3228 | St ring organ ization = "Unknown"; | |
3229 | St ring city = "Unknown "; | |
3230 | St ring state = "Unknow n"; | |
3231 | St ring count ry = "Unkn own"; | |
3232 | X5 00Name nam e; | |
3233 | St ring userI nput = nul l; | |
3234 | ||
3235 | in t maxRetry = 20; | |
3236 | do { | |
3237 | if (maxR etry-- < 0 ) { | |
3238 | thro w new Runt imeExcepti on(rb.getS tring( | |
3239 | "Too.m any.retrie s.program. terminated ")); | |
3240 | } | |
3241 | commonNa me = input String(in, | |
3242 | rb.getStri ng("What.i s.your.fir st.and.las t.name."), | |
3243 | commonName ); | |
3244 | organiza tionalUnit = inputSt ring(in, | |
3245 | rb.getStri ng | |
3246 | ("What .is.the.na me.of.your .organizat ional.unit ."), | |
3247 | organizati onalUnit); | |
3248 | organiza tion = inp utString(i n, | |
3249 | rb.getStri ng("What.i s.the.name .of.your.o rganizatio n."), | |
3250 | organizati on); | |
3251 | city = i nputString (in, | |
3252 | rb.getStri ng("What.i s.the.name .of.your.C ity.or.Loc ality."), | |
3253 | city); | |
3254 | state = inputStrin g(in, | |
3255 | rb.getStri ng("What.i s.the.name .of.your.S tate.or.Pr ovince."), | |
3256 | state); | |
3257 | country = inputStr ing(in, | |
3258 | rb.getStri ng | |
3259 | ("What .is.the.tw o.letter.c ountry.cod e.for.this .unit."), | |
3260 | country); | |
3261 | name = n ew X500Nam e(commonNa me, organi zationalUn it, organi zation, | |
3262 | city, st ate, count ry); | |
3263 | MessageF ormat form = new Mes sageFormat | |
3264 | (rb. getString( "Is.name.c orrect.")) ; | |
3265 | Object[] source = {name}; | |
3266 | userInpu t = inputS tring | |
3267 | (in, form.form at(source) , rb.getSt ring("no") ); | |
3268 | } while (col lator.comp are(userIn put, rb.ge tString("y es")) != 0 && | |
3269 | col lator.comp are(userIn put, rb.ge tString("y ")) != 0); | |
3270 | ||
3271 | Sy stem.err.p rintln(); | |
3272 | re turn name; | |
3273 | } | |
3274 | ||
3275 | privat e String i nputString (BufferedR eader in, String pro mpt, | |
3276 | String de faultValue ) | |
3277 | th rows IOExc eption | |
3278 | { | |
3279 | Sy stem.err.p rintln(pro mpt); | |
3280 | Me ssageForma t form = n ew Message Format | |
3281 | (rb. getString( ".defaultV alue.")); | |
3282 | Ob ject[] sou rce = {def aultValue} ; | |
3283 | Sy stem.err.p rint(form. format(sou rce)); | |
3284 | Sy stem.err.f lush(); | |
3285 | ||
3286 | St ring value = in.read Line(); | |
3287 | if (value == null || c ollator.co mpare(valu e, "") == 0) { | |
3288 | value = defaultVal ue; | |
3289 | } | |
3290 | re turn value ; | |
3291 | } | |
3292 | ||
3293 | /** | |
3294 | * Wri tes an X.5 09 certifi cate in ba se64 or bi nary encod ing to an output | |
3295 | * str eam. | |
3296 | */ | |
3297 | privat e void dum pCert(Cert ificate ce rt, PrintS tream out) | |
3298 | th rows IOExc eption, Ce rtificateE xception | |
3299 | { | |
3300 | if (rfc) { | |
3301 | out.prin tln(X509Fa ctory.BEGI N_CERT); | |
3302 | out.prin tln(Base64 .getMimeEn coder(64, CRLF).enco deToString (cert.getE ncoded())) ; | |
3303 | out.prin tln(X509Fa ctory.END_ CERT); | |
3304 | } else { | |
3305 | out.writ e(cert.get Encoded()) ; // binar y | |
3306 | } | |
3307 | } | |
3308 | ||
3309 | /** | |
3310 | * Con verts a by te to hex digit and writes to the suppli ed buffer | |
3311 | */ | |
3312 | privat e void byt e2hex(byte b, String Buffer buf ) { | |
3313 | ch ar[] hexCh ars = { '0 ', '1', '2 ', '3', '4 ', '5', '6 ', '7', '8 ', | |
3314 | '9 ', 'A', 'B ', 'C', 'D ', 'E', 'F ' }; | |
3315 | in t high = ( (b & 0xf0) >> 4); | |
3316 | in t low = (b & 0x0f); | |
3317 | bu f.append(h exChars[hi gh]); | |
3318 | bu f.append(h exChars[lo w]); | |
3319 | } | |
3320 | ||
3321 | /** | |
3322 | * Con verts a by te array t o hex stri ng | |
3323 | */ | |
3324 | privat e String t oHexString (byte[] bl ock) { | |
3325 | St ringBuffer buf = new StringBuf fer(); | |
3326 | in t len = bl ock.length ; | |
3327 | fo r (int i = 0; i < le n; i++) { | |
3328 | byte2he x(block[i] , buf); | |
3329 | if (i < len-1) { | |
3330 | buf .append(": "); | |
3331 | } | |
3332 | } | |
3333 | re turn buf.t oString(); | |
3334 | } | |
3335 | ||
3336 | /** | |
3337 | * Rec overs (pri vate) key associated with give n alias. | |
3338 | * | |
3339 | * @re turn an ar ray of obj ects, wher e the 1st element in the array is the | |
3340 | * rec overed pri vate key, and the 2n d element is the pas sword used to | |
3341 | * rec over it. | |
3342 | */ | |
3343 | privat e Pair<Key ,char[]> r ecoverKey( String ali as, char[] storePass , | |
3344 | c har[] keyP ass) | |
3345 | th rows Excep tion | |
3346 | { | |
3347 | Ke y key = nu ll; | |
3348 | ||
3349 | if (keyStore .containsA lias(alias ) == false ) { | |
3350 | MessageF ormat form = new Mes sageFormat | |
3351 | (rb. getString( "Alias.ali as.does.no t.exist")) ; | |
3352 | Object[] source = {alias}; | |
3353 | throw ne w Exceptio n(form.for mat(source )); | |
3354 | } | |
3355 | if (!keyStor e.entryIns tanceOf(al ias, KeySt ore.Privat eKeyEntry. class) && | |
3356 | !key Store.entr yInstanceO f(alias, K eyStore.Se cretKeyEnt ry.class)) { | |
3357 | MessageF ormat form = new Mes sageFormat | |
3358 | (rb. getString( "Alias.ali as.has.no. key")); | |
3359 | Object[] source = {alias}; | |
3360 | throw ne w Exceptio n(form.for mat(source )); | |
3361 | } | |
3362 | ||
3363 | if (keyPass == null) { | |
3364 | // Try t o recover the key us ing the ke ystore pas sword | |
3365 | try { | |
3366 | key = keyStore .getKey(al ias, store Pass); | |
3367 | ||
3368 | keyP ass = stor ePass; | |
3369 | pass words.add( keyPass); | |
3370 | } catch (Unrecover ableKeyExc eption e) { | |
3371 | // D id not wor k out, so prompt use r for key password | |
3372 | if ( !token) { | |
3373 | keyPass = getKeyPass wd(alias, null, null ); | |
3374 | key = keyS tore.getKe y(alias, k eyPass); | |
3375 | } el se { | |
3376 | throw e; | |
3377 | } | |
3378 | } | |
3379 | } else { | |
3380 | key = ke yStore.get Key(alias, keyPass); | |
3381 | } | |
3382 | ||
3383 | re turn Pair. of(key, ke yPass); | |
3384 | } | |
3385 | ||
3386 | /** | |
3387 | * Rec overs entr y associat ed with gi ven alias. | |
3388 | * | |
3389 | * @re turn an ar ray of obj ects, wher e the 1st element in the array is the | |
3390 | * rec overed ent ry, and th e 2nd elem ent is the password used to | |
3391 | * rec over it (n ull if no password). | |
3392 | */ | |
3393 | privat e Pair<Ent ry,char[]> recoverEn try(KeySto re ks, | |
3394 | St ring alias , | |
3395 | ch ar[] pstor e, | |
3396 | ch ar[] pkey) throws Ex ception { | |
3397 | ||
3398 | if (ks.conta insAlias(a lias) == f alse) { | |
3399 | MessageF ormat form = new Mes sageFormat | |
3400 | (rb. getString( "Alias.ali as.does.no t.exist")) ; | |
3401 | Object[] source = {alias}; | |
3402 | throw ne w Exceptio n(form.for mat(source )); | |
3403 | } | |
3404 | ||
3405 | Pa sswordProt ection pp = null; | |
3406 | En try entry; | |
3407 | ||
3408 | tr y { | |
3409 | // First attempt t o access e ntry witho ut key pas sword | |
3410 | // (PKCS 11 entry o r trusted certificat e entry, f or example ) | |
3411 | ||
3412 | entry = ks.getEntr y(alias, p p); | |
3413 | pkey = n ull; | |
3414 | } catch (Unr ecoverable EntryExcep tion une) { | |
3415 | ||
3416 | if(P11KE YSTORE.equ alsIgnoreC ase(ks.get Type()) || | |
3417 | KeyS toreUtil.i sWindowsKe yStore(ks. getType()) ) { | |
3418 | // s hould not happen, bu t a possib ility | |
3419 | thro w une; | |
3420 | } | |
3421 | ||
3422 | // entry is protec ted | |
3423 | ||
3424 | if (pkey != null) { | |
3425 | ||
3426 | // t ry provide d key pass word | |
3427 | ||
3428 | pp = new Passw ordProtect ion(pkey); | |
3429 | entr y = ks.get Entry(alia s, pp); | |
3430 | ||
3431 | } else { | |
3432 | ||
3433 | // t ry store p ass | |
3434 | ||
3435 | try { | |
3436 | pp = new P asswordPro tection(ps tore); | |
3437 | entry = ks .getEntry( alias, pp) ; | |
3438 | pkey = pst ore; | |
3439 | } ca tch (Unrec overableEn tryExcepti on une2) { | |
3440 | if (P12KEY STORE.equa lsIgnoreCa se(ks.getT ype())) { | |
3441 | ||
3442 | // P12 keystore currently does not s upport sep arate | |
3443 | // sto re and ent ry passwor ds | |
3444 | ||
3445 | throw une2; | |
3446 | } else { | |
3447 | ||
3448 | // pro mpt for en try passwo rd | |
3449 | ||
3450 | pkey = getKeyPas swd(alias, null, nul l); | |
3451 | pp = n ew Passwor dProtectio n(pkey); | |
3452 | entry = ks.getEn try(alias, pp); | |
3453 | } | |
3454 | } | |
3455 | } | |
3456 | } | |
3457 | ||
3458 | re turn Pair. of(entry, pkey); | |
3459 | } | |
3460 | /** | |
3461 | * Get s the requ ested fing er print o f the cert ificate. | |
3462 | */ | |
3463 | privat e String g etCertFing erPrint(St ring mdAlg , Certific ate cert) | |
3464 | th rows Excep tion | |
3465 | { | |
3466 | by te[] encCe rtInfo = c ert.getEnc oded(); | |
3467 | Me ssageDiges t md = Mes sageDigest .getInstan ce(mdAlg); | |
3468 | by te[] diges t = md.dig est(encCer tInfo); | |
3469 | re turn toHex String(dig est); | |
3470 | } | |
3471 | ||
3472 | /** | |
3473 | * Pri nts warnin g about mi ssing inte grity chec k. | |
3474 | */ | |
3475 | privat e void pri ntNoIntegr ityWarning () { | |
3476 | Sy stem.err.p rintln(); | |
3477 | Sy stem.err.p rintln(rb. getString | |
3478 | (".WARNI NG.WARNING .WARNING." )); | |
3479 | Sy stem.err.p rintln(rb. getString | |
3480 | (".The.i ntegrity.o f.the.info rmation.st ored.in.yo ur.keystor e.")); | |
3481 | Sy stem.err.p rintln(rb. getString | |
3482 | (".WARNI NG.WARNING .WARNING." )); | |
3483 | Sy stem.err.p rintln(); | |
3484 | } | |
3485 | ||
3486 | /** | |
3487 | * Val idates cha in in cert ification reply, and returns t he ordered | |
3488 | * ele ments of t he chain ( with user certificat e first, a nd root | |
3489 | * cer tificate l ast in the array). | |
3490 | * | |
3491 | * @pa ram alias the alias name | |
3492 | * @pa ram userCe rt the use r certific ate of the alias | |
3493 | * @pa ram replyC erts the c hain provi ded in the reply | |
3494 | */ | |
3495 | privat e Certific ate[] vali dateReply( String ali as, | |
3496 | Certificat e userCert , | |
3497 | Certificat e[] replyC erts) | |
3498 | th rows Excep tion | |
3499 | { | |
3500 | ||
3501 | ch eckWeak(rb .getString ("reply"), replyCert s); | |
3502 | ||
3503 | // order the certs in the reply (bottom-up ). | |
3504 | // we know t hat all ce rts in the reply are of type X .509, beca use | |
3505 | // we parsed them usin g an X.509 certifica te factory | |
3506 | in t i; | |
3507 | Pu blicKey us erPubKey = userCert. getPublicK ey(); | |
3508 | fo r (i=0; i< replyCerts .length; i ++) { | |
3509 | if (user PubKey.equ als(replyC erts[i].ge tPublicKey ())) { | |
3510 | brea k; | |
3511 | } | |
3512 | } | |
3513 | if (i == rep lyCerts.le ngth) { | |
3514 | MessageF ormat form = new Mes sageFormat (rb.getStr ing | |
3515 | ("Ce rtificate. reply.does .not.conta in.public. key.for.al ias.")); | |
3516 | Object[] source = {alias}; | |
3517 | throw ne w Exceptio n(form.for mat(source )); | |
3518 | } | |
3519 | ||
3520 | Ce rtificate tmpCert = replyCerts [0]; | |
3521 | re plyCerts[0 ] = replyC erts[i]; | |
3522 | re plyCerts[i ] = tmpCer t; | |
3523 | ||
3524 | X5 09Certific ate thisCe rt = (X509 Certificat e)replyCer ts[0]; | |
3525 | ||
3526 | fo r (i=1; i < replyCer ts.length- 1; i++) { | |
3527 | // find a cert in the reply who signs thisCert | |
3528 | int j; | |
3529 | for (j=i ; j<replyC erts.lengt h; j++) { | |
3530 | if ( signedBy(t hisCert, ( X509Certif icate)repl yCerts[j]) ) { | |
3531 | tmpCert = replyCerts [i]; | |
3532 | replyCerts [i] = repl yCerts[j]; | |
3533 | replyCerts [j] = tmpC ert; | |
3534 | thisCert = (X509Cert ificate)re plyCerts[i ]; | |
3535 | break; | |
3536 | } | |
3537 | } | |
3538 | if (j == replyCert s.length) { | |
3539 | thro w new Exce ption | |
3540 | (rb.getStr ing("Incom plete.cert ificate.ch ain.in.rep ly")); | |
3541 | } | |
3542 | } | |
3543 | ||
3544 | if (noprompt ) { | |
3545 | return r eplyCerts; | |
3546 | } | |
3547 | ||
3548 | // do we tru st the cer t at the t op? | |
3549 | Ce rtificate topCert = replyCerts [replyCert s.length-1 ]; | |
3550 | bo olean from KeyStore = true; | |
3551 | Pa ir<String, Certificat e> root = getSigner( topCert, k eyStore); | |
3552 | if (root == null && tr ustcacerts && caks ! = null) { | |
3553 | root = g etSigner(t opCert, ca ks); | |
3554 | fromKeyS tore = fal se; | |
3555 | } | |
3556 | if (root == null) { | |
3557 | System.e rr.println (); | |
3558 | System.e rr.println | |
3559 | (rb.getStr ing("Top.l evel.certi ficate.in. reply.")); | |
3560 | printX50 9Cert((X50 9Certifica te)topCert , System.o ut); | |
3561 | System.e rr.println (); | |
3562 | System.e rr.print(r b.getStrin g(".is.not .trusted." )); | |
3563 | printWea kWarnings( true); | |
3564 | String r eply = get YesNoReply | |
3565 | (rb.getStr ing("Insta ll.reply.a nyway.no." )); | |
3566 | if ("NO" .equals(re ply)) { | |
3567 | retu rn null; | |
3568 | } | |
3569 | } else { | |
3570 | if (root .snd != to pCert) { | |
3571 | // a ppend the root CA ce rt to the chain | |
3572 | Cert ificate[] tmpCerts = | |
3573 | new Certif icate[repl yCerts.len gth+1]; | |
3574 | Syst em.arrayco py(replyCe rts, 0, tm pCerts, 0, | |
3575 | replyCe rts.length ); | |
3576 | tmpC erts[tmpCe rts.length -1] = root .snd; | |
3577 | repl yCerts = t mpCerts; | |
3578 | chec kWeak(Stri ng.format( rb.getStri ng(fromKey Store ? | |
3579 | "alias .in.keysto re" : | |
3580 | "alias .in.cacert s"), | |
3581 | root.fst), | |
3582 | root .snd); | |
3583 | } | |
3584 | } | |
3585 | re turn reply Certs; | |
3586 | } | |
3587 | ||
3588 | /** | |
3589 | * Est ablishes a certifica te chain ( using trus ted certif icates in the | |
3590 | * key store and cacerts), starting w ith the re ply (certT oVerify) | |
3591 | * and ending at a self-si gned certi ficate fou nd in the keystore. | |
3592 | * | |
3593 | * @pa ram userCe rt optiona l existing certifica te, mostly likely be the | |
3594 | * origina l self-sig ned cert c reated by -genkeypai r. | |
3595 | * It must have the same publi c key as c ertToVerif y | |
3596 | * but can not be the same cert . | |
3597 | * @pa ram certTo Verify the starting certificat e to build the chain | |
3598 | * @re turns the establishe d chain, m ight be nu ll if user decides n ot | |
3599 | */ | |
3600 | privat e Certific ate[] esta blishCertC hain(Certi ficate use rCert, | |
3601 | Certi ficate cer tToVerify) | |
3602 | th rows Excep tion | |
3603 | { | |
3604 | if (userCert != null) { | |
3605 | // Make sure that the public key of th e certific ate reply matches | |
3606 | // the o riginal pu blic key i n the keys tore | |
3607 | PublicKe y origPubK ey = userC ert.getPub licKey(); | |
3608 | PublicKe y replyPub Key = cert ToVerify.g etPublicKe y(); | |
3609 | if (!ori gPubKey.eq uals(reply PubKey)) { | |
3610 | thro w new Exce ption(rb.g etString | |
3611 | ("Publ ic.keys.in .reply.and .keystore. don.t.matc h")); | |
3612 | } | |
3613 | ||
3614 | // If th e two cert s are iden tical, we' re done: n o need to import | |
3615 | // anyth ing | |
3616 | if (cert ToVerify.e quals(user Cert)) { | |
3617 | thro w new Exce ption(rb.g etString | |
3618 | ("Cert ificate.re ply.and.ce rtificate. in.keystor e.are.iden tical")); | |
3619 | } | |
3620 | } | |
3621 | ||
3622 | // Build a h ash table of all cer tificates in the key store. | |
3623 | // Use the s ubject dis tinguished name as t he key int o the hash table. | |
3624 | // All certi ficates as sociated w ith the sa me subject distingui shed | |
3625 | // name are stored in the same h ash table entry as a vector. | |
3626 | Ha shtable<Pr incipal, V ector<Pair <String,X5 09Certific ate>>> cer ts = null; | |
3627 | if (keyStore .size() > 0) { | |
3628 | certs = new Hashta ble<>(11); | |
3629 | keystore certs2Hash table(keyS tore, cert s); | |
3630 | } | |
3631 | if (trustcac erts) { | |
3632 | if (caks !=null && caks.size( )>0) { | |
3633 | if ( certs == n ull) { | |
3634 | certs = ne w Hashtabl e<>(11); | |
3635 | } | |
3636 | keys torecerts2 Hashtable( caks, cert s); | |
3637 | } | |
3638 | } | |
3639 | ||
3640 | // start bui lding chai n | |
3641 | Ve ctor<Pair< String,X50 9Certifica te>> chain = new Vec tor<>(2); | |
3642 | if (buildCha in( | |
3643 | new Pair<>(rb. getString( "the.input "), | |
3644 | (X5 09Certific ate) certT oVerify), | |
3645 | chai n, certs)) { | |
3646 | for (Pai r<String,X 509Certifi cate> p : chain) { | |
3647 | chec kWeak(p.fs t, p.snd); | |
3648 | } | |
3649 | Certific ate[] newC hain = | |
3650 | new Certif icate[chai n.size()]; | |
3651 | // build Chain() re turns chai n with sel f-signed r oot-cert f irst and | |
3652 | // user- cert last, so we nee d to inver t the chai n before w e store | |
3653 | // it | |
3654 | int j=0; | |
3655 | for (int i=chain.s ize()-1; i >=0; i--) { | |
3656 | newC hain[j] = chain.elem entAt(i).s nd; | |
3657 | j++; | |
3658 | } | |
3659 | return n ewChain; | |
3660 | } else { | |
3661 | throw ne w Exceptio n | |
3662 | (rb. getString( "Failed.to .establish .chain.fro m.reply")) ; | |
3663 | } | |
3664 | } | |
3665 | ||
3666 | /** | |
3667 | * Rec ursively t ries to es tablish ch ain from p ool of cer ts startin g from | |
3668 | * cer tToVerify until a se lf-signed cert is fo und, and f ill the ce rts found | |
3669 | * int o chain. E ach cert i n the chai n signs th e next one . | |
3670 | * | |
3671 | * Thi s method i s able to recover fr om an erro r, say, if certToVer ify | |
3672 | * is signed by certA but certA has no issuer in certs a nd itself is not | |
3673 | * sel f-signed, the method can try a nother cer tB that al so signs | |
3674 | * cer tToVerify and look f or signer of certB, etc, etc. | |
3675 | * | |
3676 | * Eac h cert in chain come s with a l abel showi ng its ori gin. The l abel is | |
3677 | * use d in the w arning mes sage when the cert i s consider ed a risk. | |
3678 | * | |
3679 | * @pa ram certTo Verify the cert that needs to be verifie d. | |
3680 | * @pa ram chain the chain that's bei ng built. | |
3681 | * @pa ram certs the pool o f trusted certs | |
3682 | * | |
3683 | * @re turn true if success ful, false otherwise . | |
3684 | */ | |
3685 | privat e boolean buildChain (Pair<Stri ng,X509Cer tificate> certToVeri fy, | |
3686 | Vector<P air<String ,X509Certi ficate>> c hain, | |
3687 | Hashtabl e<Principa l, Vector< Pair<Strin g,X509Cert ificate>>> certs) { | |
3688 | if (isSelfSi gned(certT oVerify.sn d)) { | |
3689 | // reach ed self-si gned root cert; | |
3690 | // no ve rification needed be cause it's trusted. | |
3691 | chain.ad dElement(c ertToVerif y); | |
3692 | return t rue; | |
3693 | } | |
3694 | ||
3695 | Pr incipal is suer = cer tToVerify. snd.getIss uerDN(); | |
3696 | ||
3697 | // Get the i ssuer's ce rtificate( s) | |
3698 | Ve ctor<Pair< String,X50 9Certifica te>> vec = certs.get (issuer); | |
3699 | if (vec == n ull) { | |
3700 | return f alse; | |
3701 | } | |
3702 | ||
3703 | // Try out e ach certif icate in t he vector, until we find one | |
3704 | // whose pub lic key ve rifies the signature of the ce rtificate | |
3705 | // in questi on. | |
3706 | fo r (Enumera tion<Pair< String,X50 9Certifica te>> issue rCerts = v ec.element s(); | |
3707 | issuerC erts.hasMo reElements (); ) { | |
3708 | Pair<Str ing,X509Ce rtificate> issuerCer t = issuer Certs.next Element(); | |
3709 | PublicKe y issuerPu bKey = iss uerCert.sn d.getPubli cKey(); | |
3710 | try { | |
3711 | cert ToVerify.s nd.verify( issuerPubK ey); | |
3712 | } catch (Exception e) { | |
3713 | cont inue; | |
3714 | } | |
3715 | if (buil dChain(iss uerCert, c hain, cert s)) { | |
3716 | chai n.addEleme nt(certToV erify); | |
3717 | retu rn true; | |
3718 | } | |
3719 | } | |
3720 | re turn false ; | |
3721 | } | |
3722 | ||
3723 | /** | |
3724 | * Pro mpts user for yes/no decision. | |
3725 | * | |
3726 | * @re turn the u ser's deci sion, can only be "Y ES" or "NO " | |
3727 | */ | |
3728 | privat e String g etYesNoRep ly(String prompt) | |
3729 | th rows IOExc eption | |
3730 | { | |
3731 | St ring reply = null; | |
3732 | in t maxRetry = 20; | |
3733 | do { | |
3734 | if (maxR etry-- < 0 ) { | |
3735 | thro w new Runt imeExcepti on(rb.getS tring( | |
3736 | "Too.m any.retrie s.program. terminated ")); | |
3737 | } | |
3738 | System.e rr.print(p rompt); | |
3739 | System.e rr.flush() ; | |
3740 | reply = (new Buffe redReader( new InputS treamReade r | |
3741 | (System.in ))).readLi ne(); | |
3742 | if (coll ator.compa re(reply, "") == 0 | | | |
3743 | coll ator.compa re(reply, rb.getStri ng("n")) = = 0 || | |
3744 | coll ator.compa re(reply, rb.getStri ng("no")) == 0) { | |
3745 | repl y = "NO"; | |
3746 | } else i f (collato r.compare( reply, rb. getString( "y")) == 0 || | |
3747 | collato r.compare( reply, rb. getString( "yes")) == 0) { | |
3748 | repl y = "YES"; | |
3749 | } else { | |
3750 | Syst em.err.pri ntln(rb.ge tString("W rong.answe r.try.agai n")); | |
3751 | repl y = null; | |
3752 | } | |
3753 | } while (rep ly == null ); | |
3754 | re turn reply ; | |
3755 | } | |
3756 | ||
3757 | /** | |
3758 | * Sto res the (l eaf) certi ficates of a keystor e in a has htable. | |
3759 | * All certs bel onging to the same C A are stor ed in a ve ctor that | |
3760 | * in turn is st ored in th e hashtabl e, keyed b y the CA's subject D N. | |
3761 | * Eac h cert com es with a string lab el that sh ows its or igin and a lias. | |
3762 | */ | |
3763 | privat e void key storecerts 2Hashtable (KeyStore ks, | |
3764 | Hash table<Prin cipal, Vec tor<Pair<S tring,X509 Certificat e>>> hash) | |
3765 | th rows Excep tion { | |
3766 | ||
3767 | fo r (Enumera tion<Strin g> aliases = ks.alia ses(); | |
3768 | aliases.ha sMoreEleme nts(); ) { | |
3769 | String a lias = ali ases.nextE lement(); | |
3770 | Certific ate cert = ks.getCer tificate(a lias); | |
3771 | if (cert != null) { | |
3772 | Prin cipal subj ectDN = (( X509Certif icate)cert ).getSubje ctDN(); | |
3773 | Pair <String,X5 09Certific ate> pair = new Pair <>( | |
3774 | String .format( | |
3775 | rb.getSt ring(ks == caks ? | |
3776 | "alias.in. cacerts" : | |
3777 | "alias.in. keystore") , | |
3778 | alias), | |
3779 | (X509C ertificate )cert); | |
3780 | Vect or<Pair<St ring,X509C ertificate >> vec = h ash.get(su bjectDN); | |
3781 | if ( vec == nul l) { | |
3782 | vec = new Vector<>() ; | |
3783 | vec.addEle ment(pair) ; | |
3784 | } el se { | |
3785 | if (!vec.c ontains(pa ir)) { | |
3786 | vec.ad dElement(p air); | |
3787 | } | |
3788 | } | |
3789 | hash .put(subje ctDN, vec) ; | |
3790 | } | |
3791 | } | |
3792 | } | |
3793 | ||
3794 | /** | |
3795 | * Ret urns the i ssue time that's spe cified the -startdat e option | |
3796 | * @pa ram s the value of - startdate option | |
3797 | */ | |
3798 | privat e static D ate getSta rtDate(Str ing s) thr ows IOExce ption { | |
3799 | Ca lendar c = new Grego rianCalend ar(); | |
3800 | if (s != nul l) { | |
3801 | IOExcept ion ioe = new IOExce ption( | |
3802 | rb.getStri ng("Illega l.startdat e.value")) ; | |
3803 | int len = s.length (); | |
3804 | if (len == 0) { | |
3805 | thro w ioe; | |
3806 | } | |
3807 | if (s.ch arAt(0) == '-' || s. charAt(0) == '+') { | |
3808 | // F orm 1: ([+ -]nnn[ymdH MS])+ | |
3809 | int start = 0; | |
3810 | whil e (start < len) { | |
3811 | int sign = 0; | |
3812 | switch (s. charAt(sta rt)) { | |
3813 | case ' +': sign = 1; break; | |
3814 | case ' -': sign = -1; break ; | |
3815 | defaul t: throw i oe; | |
3816 | } | |
3817 | int i = st art+1; | |
3818 | for (; i<l en; i++) { | |
3819 | char c h = s.char At(i); | |
3820 | if (ch < '0' || ch > '9') break; | |
3821 | } | |
3822 | if (i == s tart+1) th row ioe; | |
3823 | int number = Integer .parseInt( s.substrin g(start+1, i)); | |
3824 | if (i >= l en) throw ioe; | |
3825 | int unit = 0; | |
3826 | switch (s. charAt(i)) { | |
3827 | case ' y': unit = Calendar. YEAR; brea k; | |
3828 | case ' m': unit = Calendar. MONTH; bre ak; | |
3829 | case ' d': unit = Calendar. DATE; brea k; | |
3830 | case ' H': unit = Calendar. HOUR; brea k; | |
3831 | case ' M': unit = Calendar. MINUTE; br eak; | |
3832 | case ' S': unit = Calendar. SECOND; br eak; | |
3833 | defaul t: throw i oe; | |
3834 | } | |
3835 | c.add(unit , sign * n umber); | |
3836 | start = i + 1; | |
3837 | } | |
3838 | } else { | |
3839 | // F orm 2: [yy yy/mm/dd] [HH:MM:SS] | |
3840 | Stri ng date = null, time = null; | |
3841 | if ( len == 19) { | |
3842 | date = s.s ubstring(0 , 10); | |
3843 | time = s.s ubstring(1 1); | |
3844 | if (s.char At(10) != ' ') | |
3845 | throw ioe; | |
3846 | } el se if (len == 10) { | |
3847 | date = s; | |
3848 | } el se if (len == 8) { | |
3849 | time = s; | |
3850 | } el se { | |
3851 | throw ioe; | |
3852 | } | |
3853 | if ( date != nu ll) { | |
3854 | if (date.m atches("\\ d\\d\\d\\d \\/\\d\\d\ \/\\d\\d") ) { | |
3855 | c.set( Integer.va lueOf(date .substring (0, 4)), | |
3856 | Integer. valueOf(da te.substri ng(5, 7))- 1, | |
3857 | Integer. valueOf(da te.substri ng(8, 10)) ); | |
3858 | } else { | |
3859 | throw ioe; | |
3860 | } | |
3861 | } | |
3862 | if ( time != nu ll) { | |
3863 | if (time.m atches("\\ d\\d:\\d\\ d:\\d\\d") ) { | |
3864 | c.set( Calendar.H OUR_OF_DAY , Integer. valueOf(ti me.substri ng(0, 2))) ; | |
3865 | c.set( Calendar.M INUTE, Int eger.value Of(time.su bstring(0, 2))); | |
3866 | c.set( Calendar.S ECOND, Int eger.value Of(time.su bstring(0, 2))); | |
3867 | c.set( Calendar.M ILLISECOND , 0); | |
3868 | } else { | |
3869 | throw ioe; | |
3870 | } | |
3871 | } | |
3872 | } | |
3873 | } | |
3874 | re turn c.get Time(); | |
3875 | } | |
3876 | ||
3877 | /** | |
3878 | * Mat ch a comma nd (may be abbreviat ed) with a command s et. | |
3879 | * @pa ram s the command pr ovided | |
3880 | * @pa ram list t he legal c ommand set . If there is a null , commands after it | |
3881 | * are regarded experiment al, which means they are suppo rted but t heir | |
3882 | * exi stence sho uld not be revealed to user. | |
3883 | * @re turn the p osition of a single match, or -1 if none matched | |
3884 | * @th rows Excep tion if s is ambiguo us | |
3885 | */ | |
3886 | privat e static i nt oneOf(S tring s, S tring... l ist) throw s Exceptio n { | |
3887 | in t[] match = new int[ list.lengt h]; | |
3888 | in t nmatch = 0; | |
3889 | in t experime nt = Integ er.MAX_VAL UE; | |
3890 | fo r (int i = 0; i<list .length; i ++) { | |
3891 | String o ne = list[ i]; | |
3892 | if (one == null) { | |
3893 | expe riment = i ; | |
3894 | cont inue; | |
3895 | } | |
3896 | if (one. toLowerCas e(Locale.E NGLISH) | |
3897 | .startsWit h(s.toLowe rCase(Loca le.ENGLISH ))) { | |
3898 | matc h[nmatch++ ] = i; | |
3899 | } else { | |
3900 | Stri ngBuffer s b = new St ringBuffer (); | |
3901 | bool ean first = true; | |
3902 | for (char c: o ne.toCharA rray()) { | |
3903 | if (first) { | |
3904 | sb.app end(c); | |
3905 | first = false; | |
3906 | } else { | |
3907 | if (!C haracter.i sLowerCase (c)) { | |
3908 | sb .append(c) ; | |
3909 | } | |
3910 | } | |
3911 | } | |
3912 | if ( sb.toStrin g().equals IgnoreCase (s)) { | |
3913 | match[nmat ch++] = i; | |
3914 | } | |
3915 | } | |
3916 | } | |
3917 | if (nmatch = = 0) { | |
3918 | return - 1; | |
3919 | } else if (n match == 1 ) { | |
3920 | return m atch[0]; | |
3921 | } else { | |
3922 | // If mu ltiple mat ches is in experimen tal comman ds, ignore them | |
3923 | if (matc h[1] > exp eriment) { | |
3924 | retu rn match[0 ]; | |
3925 | } | |
3926 | StringBu ffer sb = new String Buffer(); | |
3927 | MessageF ormat form = new Mes sageFormat (rb.getStr ing | |
3928 | ("co mmand.{0}. is.ambiguo us.")); | |
3929 | Object[] source = {s}; | |
3930 | sb.appen d(form.for mat(source )); | |
3931 | sb.appen d("\n " ); | |
3932 | for (int i=0; i<nm atch && ma tch[i]<exp eriment; i ++) { | |
3933 | sb.a ppend(' ') ; | |
3934 | sb.a ppend(list [match[i]] ); | |
3935 | } | |
3936 | throw ne w Exceptio n(sb.toStr ing()); | |
3937 | } | |
3938 | } | |
3939 | ||
3940 | /** | |
3941 | * Cre ate a Gene ralName ob ject from known type s | |
3942 | * @pa ram t one of 5 known types | |
3943 | * @pa ram v valu e | |
3944 | * @re turn which one | |
3945 | */ | |
3946 | privat e GeneralN ame create GeneralNam e(String t , String v ) | |
3947 | throws E xception { | |
3948 | Ge neralNameI nterface g n; | |
3949 | in t p = oneO f(t, "EMAI L", "URI", "DNS", "I P", "OID") ; | |
3950 | if (p < 0) { | |
3951 | throw ne w Exceptio n(rb.getSt ring( | |
3952 | "Unrecogni zed.Genera lName.type .") + t); | |
3953 | } | |
3954 | sw itch (p) { | |
3955 | case 0: gn = new R FC822Name( v); break; | |
3956 | case 1: gn = new U RIName(v); break; | |
3957 | case 2: gn = new D NSName(v); break; | |
3958 | case 3: gn = new I PAddressNa me(v); bre ak; | |
3959 | default: gn = new OIDName(v) ; break; / /4 | |
3960 | } | |
3961 | re turn new G eneralName (gn); | |
3962 | } | |
3963 | ||
3964 | privat e static f inal Strin g[] extSup ported = { | |
3965 | "Basic Constraint s", | |
3966 | "KeyUs age", | |
3967 | "Exten dedKeyUsag e", | |
3968 | "Subje ctAlternat iveName", | |
3969 | "Issue rAlternati veName", | |
3970 | "Subje ctInfoAcce ss", | |
3971 | "Autho rityInfoAc cess", | |
3972 | null, | |
3973 | "CRLDi stribution Points", | |
3974 | }; | |
3975 | ||
3976 | privat e ObjectId entifier f indOidForE xtName(Str ing type) | |
3977 | throws E xception { | |
3978 | sw itch (oneO f(type, ex tSupported )) { | |
3979 | case 0: return PKI XExtension s.BasicCon straints_I d; | |
3980 | case 1: return PKI XExtension s.KeyUsage _Id; | |
3981 | case 2: return PKI XExtension s.Extended KeyUsage_I d; | |
3982 | case 3: return PKI XExtension s.SubjectA lternative Name_Id; | |
3983 | case 4: return PKI XExtension s.IssuerAl ternativeN ame_Id; | |
3984 | case 5: return PKI XExtension s.SubjectI nfoAccess_ Id; | |
3985 | case 6: return PKI XExtension s.AuthInfo Access_Id; | |
3986 | case 8: return PKI XExtension s.CRLDistr ibutionPoi nts_Id; | |
3987 | default: return ne w ObjectId entifier(t ype); | |
3988 | } | |
3989 | } | |
3990 | ||
3991 | /** | |
3992 | * Cre ate X509v3 extension s from a s tring repr esentation . Note tha t the | |
3993 | * Sub jectKeyIde ntifierExt ension wil l always b e created non-critic al besides | |
3994 | * the extension requested in the <c ode>extstr </code> ar gument. | |
3995 | * | |
3996 | * @pa ram reqex the reques ted extens ions, can be null, u sed for -g encert | |
3997 | * @pa ram ext th e original extension s, can be null, used for -self cert | |
3998 | * @pa ram extstr s -ext val ues, Read keytool do c | |
3999 | * @pa ram pkey t he public key for th e certific ate | |
4000 | * @pa ram akey t he public key for th e authorit y (issuer) | |
4001 | * @re turn the c reated Cer tificateEx tensions | |
4002 | */ | |
4003 | privat e Certific ateExtensi ons create V3Extensio ns( | |
4004 | Certific ateExtensi ons reqex, | |
4005 | Certific ateExtensi ons ext, | |
4006 | List <St ring> exts trs, | |
4007 | PublicKe y pkey, | |
4008 | PublicKe y akey) th rows Excep tion { | |
4009 | ||
4010 | if (ext != n ull && req ex != null ) { | |
4011 | // This should not happen | |
4012 | throw ne w Exceptio n("One of request an d original should be null."); | |
4013 | } | |
4014 | if (ext == n ull) ext = new Certi ficateExte nsions(); | |
4015 | tr y { | |
4016 | // name{ :critical} {=value} | |
4017 | // Honor ing reques ted extens ions | |
4018 | if (reqe x != null) { | |
4019 | for( String ext str: extst rs) { | |
4020 | if (extstr .toLowerCa se(Locale. ENGLISH).s tartsWith( "honored=" )) { | |
4021 | List<S tring> lis t = Arrays .asList( | |
4022 | extstr.t oLowerCase (Locale.EN GLISH).sub string(8). split(",") ); | |
4023 | // Fir st check e xistence o f "all" | |
4024 | if (li st.contain s("all")) { | |
4025 | ex t = reqex; // we know ext w as null | |
4026 | } | |
4027 | // one by one fo r others | |
4028 | for (S tring item : list) { | |
4029 | if (item.equ als("all") ) continue ; | |
4030 | ||
4031 | // add or re move | |
4032 | bo olean add = true; | |
4033 | // -1, uncha nged, 0 cr tical, 1 n on-critica l | |
4034 | in t action = -1; | |
4035 | St ring type = null; | |
4036 | if (item.sta rtsWith("- ")) { | |
4037 | add = fa lse; | |
4038 | type = i tem.substr ing(1); | |
4039 | } else { | |
4040 | int colo npos = ite m.indexOf( ':'); | |
4041 | if (colo npos >= 0) { | |
4042 | type = item.su bstring(0, colonpos) ; | |
4043 | acti on = oneOf (item.subs tring(colo npos+1), | |
4044 | "criti cal", "non -critical" ); | |
4045 | if ( action == -1) { | |
4046 | throw new Exception( rb.getStri ng | |
4047 | ("Ille gal.value. ") + item) ; | |
4048 | } | |
4049 | } | |
4050 | } | |
4051 | St ring n = r eqex.getNa meByOid(fi ndOidForEx tName(type )); | |
4052 | if (add) { | |
4053 | Extensio n e = reqe x.get(n); | |
4054 | if (!e.i sCritical( ) && actio n == 0 | |
4055 | || e.isCri tical() && action == 1) { | |
4056 | e = Extension. newExtensi on( | |
4057 | e.getE xtensionId (), | |
4058 | !e.isC ritical(), | |
4059 | e.getE xtensionVa lue()); | |
4060 | ext. set(n, e); | |
4061 | } | |
4062 | } else { | |
4063 | ext.dele te(n); | |
4064 | } | |
4065 | } | |
4066 | break; | |
4067 | } | |
4068 | } | |
4069 | } | |
4070 | for(Stri ng extstr: extstrs) { | |
4071 | Stri ng name, v alue; | |
4072 | bool ean isCrit ical = fal se; | |
4073 | ||
4074 | int eqpos = ex tstr.index Of('='); | |
4075 | if ( eqpos >= 0 ) { | |
4076 | name = ext str.substr ing(0, eqp os); | |
4077 | value = ex tstr.subst ring(eqpos +1); | |
4078 | } el se { | |
4079 | name = ext str; | |
4080 | value = nu ll; | |
4081 | } | |
4082 | ||
4083 | int colonpos = name.inde xOf(':'); | |
4084 | if ( colonpos > = 0) { | |
4085 | if (oneOf( name.subst ring(colon pos+1), "c ritical") == 0) { | |
4086 | isCrit ical = tru e; | |
4087 | } | |
4088 | name = nam e.substrin g(0, colon pos); | |
4089 | } | |
4090 | ||
4091 | if ( name.equal sIgnoreCas e("honored ")) { | |
4092 | continue; | |
4093 | } | |
4094 | int exttype = oneOf(name , extSuppo rted); | |
4095 | swit ch (exttyp e) { | |
4096 | case 0: // BC | |
4097 | int pa thLen = -1 ; | |
4098 | boolea n isCA = f alse; | |
4099 | if (va lue == nul l) { | |
4100 | is CA = true; | |
4101 | } else { | |
4102 | tr y { // t he abbr fo rmat | |
4103 | pathLen = Integer. parseInt(v alue); | |
4104 | isCA = t rue; | |
4105 | } catch (Num berFormatE xception u fe) { | |
4106 | // ca:tr ue,pathlen :1 | |
4107 | for (Str ing part: value.spli t(",")) { | |
4108 | Stri ng[] nv = part.split (":"); | |
4109 | if ( nv.length != 2) { | |
4110 | throw new Exception( rb.getStri ng | |
4111 | (" Illegal.va lue.") + e xtstr); | |
4112 | } el se { | |
4113 | if (nv[0]. equalsIgno reCase("ca ")) { | |
4114 | isCA = Boolean.p arseBoolea n(nv[1]); | |
4115 | } else if (nv[0].equ alsIgnoreC ase("pathl en")) { | |
4116 | pathLe n = Intege r.parseInt (nv[1]); | |
4117 | } else { | |
4118 | throw new Except ion(rb.get String | |
4119 | (" Illegal.va lue.") + e xtstr); | |
4120 | } | |
4121 | } | |
4122 | } | |
4123 | } | |
4124 | } | |
4125 | ext.se t(BasicCon straintsEx tension.NA ME, | |
4126 | new Basi cConstrain tsExtensio n(isCritic al, isCA, | |
4127 | pathLen) ); | |
4128 | break; | |
4129 | case 1: // KU | |
4130 | if(val ue != null ) { | |
4131 | bo olean[] ok = new boo lean[9]; | |
4132 | fo r (String s: value.s plit(",")) { | |
4133 | int p = oneOf(s, | |
4134 | " digitalSig nature", // (0), | |
4135 | " nonRepudia tion", // (1) | |
4136 | " keyEnciphe rment", // (2), | |
4137 | " dataEnciph erment", // (3), | |
4138 | " keyAgreeme nt", // (4), | |
4139 | " keyCertSig n", // (5), | |
4140 | " cRLSign", // (6), | |
4141 | " encipherOn ly", // (7), | |
4142 | " decipherOn ly", // (8) | |
4143 | " contentCom mitment" // also (1 ) | |
4144 | ) ; | |
4145 | if (p < 0) { | |
4146 | thro w new Exce ption(rb.g etString(" Unknown.ke yUsage.typ e.") + s); | |
4147 | } | |
4148 | if (p == 9) p = 1; | |
4149 | ok[p] = true; | |
4150 | } | |
4151 | Ke yUsageExte nsion kue = new KeyU sageExtens ion(ok); | |
4152 | // The above KeyUsageE xtension c onstructor does not | |
4153 | // allow isC ritical va lue, so... | |
4154 | ex t.set(KeyU sageExtens ion.NAME, Extension. newExtensi on( | |
4155 | kue. getExtensi onId(), | |
4156 | isCr itical, | |
4157 | kue. getExtensi onValue()) ); | |
4158 | } else { | |
4159 | th row new Ex ception(rb .getString | |
4160 | ("Il legal.valu e.") + ext str); | |
4161 | } | |
4162 | break; | |
4163 | case 2: // EKU | |
4164 | if(val ue != null ) { | |
4165 | Ve ctor<Objec tIdentifie r> v = new Vector<>( ); | |
4166 | fo r (String s: value.s plit(",")) { | |
4167 | int p = oneOf(s, | |
4168 | "anyExtend edKeyUsage ", | |
4169 | "serverAut h", //1 | |
4170 | "clientAut h", //2 | |
4171 | "codeSigni ng", //3 | |
4172 | "emailProt ection", //4 | |
4173 | "", //5 | |
4174 | "", //6 | |
4175 | "", //7 | |
4176 | "timeStamp ing", //8 | |
4177 | "OCSPSigni ng" //9 | |
4178 | ) ; | |
4179 | if (p < 0) { | |
4180 | try { | |
4181 | v.add(new ObjectIden tifier(s)) ; | |
4182 | } ca tch (Excep tion e) { | |
4183 | throw new Exception( rb.getStri ng( | |
4184 | "U nknown.ext endedkeyUs age.type." ) + s); | |
4185 | } | |
4186 | } else i f (p == 0) { | |
4187 | v.ad d(new Obje ctIdentifi er("2.5.29 .37.0")); | |
4188 | } else { | |
4189 | v.ad d(new Obje ctIdentifi er("1.3.6. 1.5.5.7.3. " + p)); | |
4190 | } | |
4191 | } | |
4192 | ex t.set(Exte ndedKeyUsa geExtensio n.NAME, | |
4193 | new ExtendedKe yUsageExte nsion(isCr itical, v) ); | |
4194 | } else { | |
4195 | th row new Ex ception(rb .getString | |
4196 | ("Il legal.valu e.") + ext str); | |
4197 | } | |
4198 | break; | |
4199 | case 3: // SAN | |
4200 | case 4: // IAN | |
4201 | if(val ue != null ) { | |
4202 | St ring[] ps = value.sp lit(","); | |
4203 | Ge neralNames gnames = new Genera lNames(); | |
4204 | fo r(String i tem: ps) { | |
4205 | colonpos = item.in dexOf(':') ; | |
4206 | if (colo npos < 0) { | |
4207 | thro w new Exce ption("Ill egal item " + item + " in " + extstr); | |
4208 | } | |
4209 | String t = item.su bstring(0, colonpos) ; | |
4210 | String v = item.su bstring(co lonpos+1); | |
4211 | gnames.a dd(createG eneralName (t, v)); | |
4212 | } | |
4213 | if (exttype == 3) { | |
4214 | ext.set( SubjectAlt ernativeNa meExtensio n.NAME, | |
4215 | new Subjec tAlternati veNameExte nsion( | |
4216 | isCrit ical, gnam es)); | |
4217 | } else { | |
4218 | ext.set( IssuerAlte rnativeNam eExtension .NAME, | |
4219 | new Issuer Alternativ eNameExten sion( | |
4220 | isCrit ical, gnam es)); | |
4221 | } | |
4222 | } else { | |
4223 | th row new Ex ception(rb .getString | |
4224 | ("Il legal.valu e.") + ext str); | |
4225 | } | |
4226 | break; | |
4227 | case 5: // SIA, always non -critical | |
4228 | case 6: // AIA, always non -critical | |
4229 | if (is Critical) { | |
4230 | th row new Ex ception(rb .getString ( | |
4231 | "Thi s.extensio n.cannot.b e.marked.a s.critical .") + exts tr); | |
4232 | } | |
4233 | if(val ue != null ) { | |
4234 | Li st<AccessD escription > accessDe scriptions = | |
4235 | new ArrayList< >(); | |
4236 | St ring[] ps = value.sp lit(","); | |
4237 | fo r(String i tem: ps) { | |
4238 | colonpos = item.in dexOf(':') ; | |
4239 | int colo npos2 = it em.indexOf (':', colo npos+1); | |
4240 | if (colo npos < 0 | | colonpos 2 < 0) { | |
4241 | thro w new Exce ption(rb.g etString | |
4242 | ("Ille gal.value. ") + extst r); | |
4243 | } | |
4244 | String m = item.su bstring(0, colonpos) ; | |
4245 | String t = item.su bstring(co lonpos+1, colonpos2) ; | |
4246 | String v = item.su bstring(co lonpos2+1) ; | |
4247 | int p = oneOf(m, | |
4248 | "", | |
4249 | "ocsp", //1 | |
4250 | "caIssuers ", //2 | |
4251 | "timeStamp ing", //3 | |
4252 | "", | |
4253 | "caReposit ory" //5 | |
4254 | ); | |
4255 | ObjectId entifier o id; | |
4256 | if (p < 0) { | |
4257 | try { | |
4258 | oid = new ObjectIden tifier(m); | |
4259 | } ca tch (Excep tion e) { | |
4260 | throw new Exception( rb.getStri ng( | |
4261 | "U nknown.Acc essDescrip tion.type. ") + m); | |
4262 | } | |
4263 | } else { | |
4264 | oid = new Obje ctIdentifi er("1.3.6. 1.5.5.7.48 ." + p); | |
4265 | } | |
4266 | accessDe scriptions .add(new A ccessDescr iption( | |
4267 | oid, creat eGeneralNa me(t, v))) ; | |
4268 | } | |
4269 | if (exttype == 5) { | |
4270 | ext.set( SubjectInf oAccessExt ension.NAM E, | |
4271 | new Subjec tInfoAcces sExtension (accessDes criptions) ); | |
4272 | } else { | |
4273 | ext.set( AuthorityI nfoAccessE xtension.N AME, | |
4274 | new Author ityInfoAcc essExtensi on(accessD escription s)); | |
4275 | } | |
4276 | } else { | |
4277 | th row new Ex ception(rb .getString | |
4278 | ("Il legal.valu e.") + ext str); | |
4279 | } | |
4280 | break; | |
4281 | case 8: // CRL, expe rimental, only suppo rt 1 distr ibutionpoi nt | |
4282 | if(val ue != null ) { | |
4283 | St ring[] ps = value.sp lit(","); | |
4284 | Ge neralNames gnames = new Genera lNames(); | |
4285 | fo r(String i tem: ps) { | |
4286 | colonpos = item.in dexOf(':') ; | |
4287 | if (colo npos < 0) { | |
4288 | thro w new Exce ption("Ill egal item " + item + " in " + extstr); | |
4289 | } | |
4290 | String t = item.su bstring(0, colonpos) ; | |
4291 | String v = item.su bstring(co lonpos+1); | |
4292 | gnames.a dd(createG eneralName (t, v)); | |
4293 | } | |
4294 | ex t.set(CRLD istributio nPointsExt ension.NAM E, | |
4295 | new CRLDistrib utionPoint sExtension ( | |
4296 | isCritical , Collecti ons.single tonList( | |
4297 | new Distri butionPoin t(gnames, null, null )))); | |
4298 | } else { | |
4299 | th row new Ex ception(rb .getString | |
4300 | ("Il legal.valu e.") + ext str); | |
4301 | } | |
4302 | break; | |
4303 | case -1: | |
4304 | Object Identifier oid = new ObjectIde ntifier(na me); | |
4305 | byte[] data = nu ll; | |
4306 | if (va lue != nul l) { | |
4307 | da ta = new b yte[value. length() / 2 + 1]; | |
4308 | in t pos = 0; | |
4309 | fo r (char c: value.toC harArray() ) { | |
4310 | int hex; | |
4311 | if (c >= '0' && c <= '9') { | |
4312 | hex = c - '0' ; | |
4313 | } else i f (c >= 'A ' && c <= 'F') { | |
4314 | hex = c - 'A' + 10; | |
4315 | } else i f (c >= 'a ' && c <= 'f') { | |
4316 | hex = c - 'a' + 10; | |
4317 | } else { | |
4318 | cont inue; | |
4319 | } | |
4320 | if (pos % 2 == 0) { | |
4321 | data [pos/2] = (byte)(hex << 4); | |
4322 | } else { | |
4323 | data [pos/2] += hex; | |
4324 | } | |
4325 | pos++; | |
4326 | } | |
4327 | if (pos % 2 != 0) { | |
4328 | throw ne w Exceptio n(rb.getSt ring( | |
4329 | "Odd.numbe r.of.hex.d igits.foun d.") + ext str); | |
4330 | } | |
4331 | da ta = Array s.copyOf(d ata, pos/2 ); | |
4332 | } else { | |
4333 | da ta = new b yte[0]; | |
4334 | } | |
4335 | ext.se t(oid.toSt ring(), ne w Extensio n(oid, isC ritical, | |
4336 | new DerV alue(DerVa lue.tag_Oc tetString, data) | |
4337 | .toByteArr ay())); | |
4338 | break; | |
4339 | default: | |
4340 | throw new Except ion(rb.get String( | |
4341 | "Unknown .extension .type.") + extstr); | |
4342 | } | |
4343 | } | |
4344 | // alway s non-crit ical | |
4345 | ext.set( SubjectKey Identifier Extension. NAME, | |
4346 | new Subjec tKeyIdenti fierExtens ion( | |
4347 | new Ke yIdentifie r(pkey).ge tIdentifie r())); | |
4348 | if (akey != null & & !pkey.eq uals(akey) ) { | |
4349 | ext. set(Author ityKeyIden tifierExte nsion.NAME , | |
4350 | new Au thorityKey Identifier Extension( | |
4351 | new Ke yIdentifie r(akey), n ull, null) ); | |
4352 | } | |
4353 | } catch(IOEx ception e) { | |
4354 | throw ne w RuntimeE xception(e ); | |
4355 | } | |
4356 | re turn ext; | |
4357 | } | |
4358 | ||
4359 | privat e boolean isTrustedC ert(Certif icate cert ) throws K eyStoreExc eption { | |
4360 | if (caks != null && ca ks.getCert ificateAli as(cert) ! = null) { | |
4361 | return t rue; | |
4362 | } else { | |
4363 | String i nKS = keyS tore.getCe rtificateA lias(cert) ; | |
4364 | return i nKS != nul l && keySt ore.isCert ificateEnt ry(inKS); | |
4365 | } | |
4366 | } | |
4367 | ||
4368 | privat e void che ckWeak(Str ing label, String si gAlg, Key key) { | |
4369 | ||
4370 | if (sigAlg ! = null && !DISABLED_ CHECK.perm its( | |
4371 | SIG_ PRIMITIVE_ SET, sigAl g, null)) { | |
4372 | weakWarn ings.add(S tring.form at( | |
4373 | rb.getStri ng("whose. sigalg.ris k"), label , sigAlg)) ; | |
4374 | } | |
4375 | if (key != n ull && !DI SABLED_CHE CK.permits (SIG_PRIMI TIVE_SET, key)) { | |
4376 | weakWarn ings.add(S tring.form at( | |
4377 | rb.getStri ng("whose. key.risk") , | |
4378 | label, | |
4379 | String.for mat(rb.get String("ke y.bit"), | |
4380 | Ke yUtil.getK eySize(key ), key.get Algorithm( )))); | |
4381 | } | |
4382 | } | |
4383 | ||
4384 | privat e void che ckWeak(Str ing label, Certifica te[] certs ) | |
4385 | throws K eyStoreExc eption { | |
4386 | fo r (int i = 0; i < ce rts.length ; i++) { | |
4387 | Certific ate cert = certs[i]; | |
4388 | if (cert instanceo f X509Cert ificate) { | |
4389 | X509 Certificat e xc = (X5 09Certific ate)cert; | |
4390 | Stri ng fullLab el = label ; | |
4391 | if ( certs.leng th > 1) { | |
4392 | fullLabel = oneInMan y(label, i , certs.le ngth); | |
4393 | } | |
4394 | chec kWeak(full Label, xc) ; | |
4395 | } | |
4396 | } | |
4397 | } | |
4398 | ||
4399 | privat e void che ckWeak(Str ing label, Certifica te cert) | |
4400 | throws K eyStoreExc eption { | |
4401 | if (cert ins tanceof X5 09Certific ate) { | |
4402 | X509Cert ificate xc = (X509Ce rtificate) cert; | |
4403 | // No ne ed to chec k the siga lg of a tr ust anchor | |
4404 | String s igAlg = is TrustedCer t(cert) ? null : xc. getSigAlgN ame(); | |
4405 | checkWea k(label, s igAlg, xc. getPublicK ey()); | |
4406 | } | |
4407 | } | |
4408 | ||
4409 | privat e void che ckWeak(Str ing label, PKCS10 p1 0) { | |
4410 | ch eckWeak(la bel, p10.g etSigAlg() , p10.getS ubjectPubl icKeyInfo( )); | |
4411 | } | |
4412 | ||
4413 | privat e void che ckWeak(Str ing label, CRL crl, Key key) { | |
4414 | if (crl inst anceof X50 9CRLImpl) { | |
4415 | X509CRLI mpl impl = (X509CRLI mpl)crl; | |
4416 | checkWea k(label, i mpl.getSig AlgName(), key); | |
4417 | } | |
4418 | } | |
4419 | ||
4420 | privat e void pri ntWeakWarn ings(boole an newLine ) { | |
4421 | if (!weakWar nings.isEm pty() && ! nowarn) { | |
4422 | System.e rr.println ("\nWarnin g:"); | |
4423 | for (Str ing warnin g : weakWa rnings) { | |
4424 | Syst em.err.pri ntln(warni ng); | |
4425 | } | |
4426 | if (newL ine) { | |
4427 | // W hen callin g before a yes/no pr ompt, add a new line | |
4428 | Syst em.err.pri ntln(); | |
4429 | } | |
4430 | } | |
4431 | we akWarnings .clear(); | |
4432 | } | |
4433 | ||
4434 | /** | |
4435 | * Pri nts the us age of thi s tool. | |
4436 | */ | |
4437 | privat e void usa ge() { | |
4438 | if (command != null) { | |
4439 | System.e rr.println ("keytool " + comman d + | |
4440 | rb.getStri ng(".OPTIO N.")); | |
4441 | System.e rr.println (); | |
4442 | System.e rr.println (rb.getStr ing(comman d.descript ion)); | |
4443 | System.e rr.println (); | |
4444 | System.e rr.println (rb.getStr ing("Optio ns.")); | |
4445 | System.e rr.println (); | |
4446 | ||
4447 | // Left and right sides of t he options list | |
4448 | String[] left = ne w String[c ommand.opt ions.lengt h]; | |
4449 | String[] right = n ew String[ command.op tions.leng th]; | |
4450 | ||
4451 | // Check if there' s an unkno wn option | |
4452 | boolean found = fa lse; | |
4453 | ||
4454 | // Lengt h of left side of op tions list | |
4455 | int lenL eft = 0; | |
4456 | for (int j=0; j<le ft.length; j++) { | |
4457 | Opti on opt = c ommand.opt ions[j]; | |
4458 | left [j] = opt. toString() ; | |
4459 | if ( opt.arg != null) lef t[j] += " " + opt.ar g; | |
4460 | if ( left[j].le ngth() > l enLeft) { | |
4461 | lenLeft = left[j].le ngth(); | |
4462 | } | |
4463 | righ t[j] = rb. getString( opt.descri ption); | |
4464 | } | |
4465 | for (int j=0; j<le ft.length; j++) { | |
4466 | Syst em.err.pri ntf(" %-" + lenLeft + "s %s\n ", | |
4467 | left[j ], right[j ]); | |
4468 | } | |
4469 | System.e rr.println (); | |
4470 | System.e rr.println (rb.getStr ing( | |
4471 | "Use.keyto ol.help.fo r.all.avai lable.comm ands")); | |
4472 | } else { | |
4473 | System.e rr.println (rb.getStr ing( | |
4474 | "Key.and.C ertificate .Managemen t.Tool")); | |
4475 | System.e rr.println (); | |
4476 | System.e rr.println (rb.getStr ing("Comma nds.")); | |
4477 | System.e rr.println (); | |
4478 | for (Com mand c: Co mmand.valu es()) { | |
4479 | if ( c == KEYCL ONE) break ; | |
4480 | Syst em.err.pri ntf(" %-20 s%s\n", c, rb.getStr ing(c.desc ription)); | |
4481 | } | |
4482 | System.e rr.println (); | |
4483 | System.e rr.println (rb.getStr ing( | |
4484 | "Use.keyto ol.command .name.help .for.usage .of.comman d.name")); | |
4485 | } | |
4486 | } | |
4487 | ||
4488 | privat e void tin yHelp() { | |
4489 | us age(); | |
4490 | if (debug) { | |
4491 | throw ne w RuntimeE xception(" NO BIG ERR OR, SORRY" ); | |
4492 | } else { | |
4493 | System.e xit(1); | |
4494 | } | |
4495 | } | |
4496 | ||
4497 | privat e void err orNeedArgu ment(Strin g flag) { | |
4498 | Ob ject[] sou rce = {fla g}; | |
4499 | Sy stem.err.p rintln(new MessageFo rmat( | |
4500 | rb.g etString(" Command.op tion.flag. needs.an.a rgument.") ).format(s ource)); | |
4501 | ti nyHelp(); | |
4502 | } | |
4503 | ||
4504 | privat e char[] g etPass(Str ing modifi er, String arg) { | |
4505 | ch ar[] outpu t = KeySto reUtil.get PassWithMo difier(mod ifier, arg , rb); | |
4506 | if (output ! = null) re turn outpu t; | |
4507 | ti nyHelp(); | |
4508 | re turn null; // Use less, tiny Help() alr eady exits . | |
4509 | } | |
4510 | } | |
4511 | ||
4512 | // This cl ass is exa ctly the s ame as com .sun.tools .javac.uti l.Pair, | |
4513 | // it's co pied here since the original o ne is not included i n JRE. | |
4514 | class Pair <A, B> { | |
4515 | ||
4516 | public final A f st; | |
4517 | public final B s nd; | |
4518 | ||
4519 | public Pair(A fs t, B snd) { | |
4520 | th is.fst = f st; | |
4521 | th is.snd = s nd; | |
4522 | } | |
4523 | ||
4524 | public String to String() { | |
4525 | re turn "Pair [" + fst + "," + snd + "]"; | |
4526 | } | |
4527 | ||
4528 | public boolean e quals(Obje ct other) { | |
4529 | re turn | |
4530 | other in stanceof P air && | |
4531 | Objects. equals(fst , ((Pair)o ther).fst) && | |
4532 | Objects. equals(snd , ((Pair)o ther).snd) ; | |
4533 | } | |
4534 | ||
4535 | public int hashC ode() { | |
4536 | if (fst == n ull) retur n (snd == null) ? 0 : snd.hash Code() + 1 ; | |
4537 | el se if (snd == null) return fst .hashCode( ) + 2; | |
4538 | el se return fst.hashCo de() * 17 + snd.hash Code(); | |
4539 | } | |
4540 | ||
4541 | public static <A ,B> Pair<A ,B> of(A a , B b) { | |
4542 | re turn new P air<>(a,b) ; | |
4543 | } | |
4544 | } |
Araxis Merge (but not the data content of this report) is Copyright © 1993-2016 Araxis Ltd (www.araxis.com). All rights reserved.