287. EPMO Open Source Coordination Office Redaction File Detail Report

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.

287.1 Files compared

# 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

287.2 Comparison summary

Description Between
Files 1 and 2
Text Blocks Lines
Unchanged 7 9076
Changed 6 12
Inserted 0 0
Removed 0 0

287.3 Comparison options

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

287.4 Active regular expressions

No regular expressions were active.

287.5 Comparison detail

  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   }