95. EPMO Open Source Coordination Office Redaction File Detail Report

Produced by Araxis Merge on 9/25/2018 2:13:02 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.

95.1 Files compared

# Location File Last Modified
1 build 3.zip\build 3\MHLTH_YS_137_Source\JavaScript\resources\javaJDF-1.8.0\src\com\sun\crypto\provider JceKeyStore.java Mon Jan 22 14:46:50 2018 UTC
2 build 3.zip\build 3\MHLTH_YS_137_Source\JavaScript\resources\javaJDF-1.8.0\src\com\sun\crypto\provider JceKeyStore.java Wed Sep 12 16:22:33 2018 UTC

95.2 Comparison summary

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

95.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

95.4 Active regular expressions

No regular expressions were active.

95.5 Comparison detail

  1   /*
  2    * Copyrig ht (c) 199 8, 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 co m.sun.cryp to.provide r;
  27  
  28   import jav a.io.*;
  29   import jav a.util.*;
  30   import jav a.security .AccessCon troller;
  31   import jav a.security .DigestInp utStream;
  32   import jav a.security .DigestOut putStream;
  33   import jav a.security .MessageDi gest;
  34   import jav a.security .NoSuchAlg orithmExce ption;
  35   import jav a.security .Key;
  36   import jav a.security .PrivateKe y;
  37   import jav a.security .Privilege dAction;
  38   import jav a.security .KeyStoreS pi;
  39   import jav a.security .KeyStoreE xception;
  40   import jav a.security .Unrecover ableKeyExc eption;
  41   import jav a.security .cert.Cert ificate;
  42   import jav a.security .cert.Cert ificateFac tory;
  43   import jav a.security .cert.Cert ificateExc eption;
  44   import jav ax.crypto. SealedObje ct;
  45  
  46   import sun .misc.Obje ctInputFil ter;
  47  
  48   /**
  49    * This cl ass provid es the key store impl ementation  referred  to as "jce ks".
  50    * This im plementati on strongl y protects  the keyst ore privat e keys usi ng
  51    * triple- DES, where  the tripl e-DES encr yption/dec ryption ke y is deriv ed from
  52    * the use r's passwo rd.
  53    * The enc rypted pri vate keys  are stored  in the ke ystore in  a standard  format,
  54    * namely  the <code> EncryptedP rivateKeyI nfo</code>  format de fined in P KCS #8.
  55    *
  56    * @author  Jan Luehe
  57    *
  58    *
  59    * @see ja va.securit y.KeyStore Spi
  60    */
  61  
  62   public fin al class J ceKeyStore  extends K eyStoreSpi  {
  63  
  64       privat e static f inal int J CEKS_MAGIC  = 0xcecec ece;
  65       privat e static f inal int J KS_MAGIC =  0xfeedfee d;
  66       privat e static f inal int V ERSION_1 =  0x01;
  67       privat e static f inal int V ERSION_2 =  0x02;
  68  
  69       // Pri vate key a nd support ing certif icate chai n
  70       privat e static f inal class  PrivateKe yEntry {
  71           Da te date; / / the crea tion date  of this en try
  72           by te[] prote ctedKey;
  73           Ce rtificate  chain[];
  74       };
  75  
  76       // Sec ret key
  77       privat e static f inal class  SecretKey Entry {
  78           Da te date; / / the crea tion date  of this en try
  79           Se aledObject  sealedKey ;
  80       }
  81  
  82       // Tru sted certi ficate
  83       privat e static f inal class  TrustedCe rtEntry {
  84           Da te date; / / the crea tion date  of this en try
  85           Ce rtificate  cert;
  86       };
  87  
  88       /**
  89        * Pri vate keys  and certif icates are  stored in  a hashtab le.
  90        * Has h entries  are keyed  by alias n ames.
  91        */
  92       privat e Hashtabl e<String,  Object> en tries = ne w Hashtabl e<String,  Object>();
  93  
  94       /**
  95        * Ret urns the k ey associa ted with t he given a lias, usin g the give n
  96        * pas sword to r ecover it.
  97        *
  98        * @pa ram alias  the alias  name
  99        * @pa ram passwo rd the pas sword for  recovering  the key
  100        *
  101        * @re turn the r equested k ey, or nul l if the g iven alias  does not  exist
  102        * or  does not i dentify a  <i>key ent ry</i>.
  103        *
  104        * @ex ception No SuchAlgori thmExcepti on if the  algorithm  for recove ring the
  105        * key  cannot be  found
  106        * @ex ception Un recoverabl eKeyExcept ion if the  key canno t be recov ered
  107        * (e. g., the gi ven passwo rd is wron g).
  108        */
  109       public  Key engin eGetKey(St ring alias , char[] p assword)
  110           th rows NoSuc hAlgorithm Exception,  Unrecover ableKeyExc eption
  111       {
  112           Ke y key = nu ll;
  113  
  114           Ob ject entry  = entries .get(alias .toLowerCa se(Locale. ENGLISH));
  115  
  116           if  (!((entry  instanceo f PrivateK eyEntry) | |
  117                  (entry  instanceo f SecretKe yEntry)))  {
  118                return n ull;
  119           }
  120  
  121           Ke yProtector  keyProtec tor = new  KeyProtect or(passwor d);
  122  
  123           if  (entry in stanceof P rivateKeyE ntry) {
  124                byte[] e ncrBytes =  ((Private KeyEntry)e ntry).prot ectedKey;
  125                Encrypte dPrivateKe yInfo encr Info;
  126                try {
  127                    encr Info = new  Encrypted PrivateKey Info(encrB ytes);
  128                } catch  (IOExcepti on ioe) {
  129                    thro w new Unre coverableK eyExceptio n("Private  key not s tored "
  130                                                            + "as PK CS #8 " +
  131                                                            "Encrypt edPrivateK eyInfo");
  132                }
  133                key = ke yProtector .recover(e ncrInfo);
  134           }  else {
  135                key =
  136                    keyP rotector.u nseal(((Se cretKeyEnt ry)entry). sealedKey) ;
  137           }
  138  
  139           re turn key;
  140       }
  141  
  142       /**
  143        * Ret urns the c ertificate  chain ass ociated wi th the giv en alias.
  144        *
  145        * @pa ram alias  the alias  name
  146        *
  147        * @re turn the c ertificate  chain (or dered with  the user' s certific ate first
  148        * and  the root  certificat e authorit y last), o r null if  the given  alias
  149        * doe s not exis t or does  not contai n a certif icate chai n (i.e., t he given
  150        * ali as identif ies either  a <i>trus ted certif icate entr y</i> or a
  151        * <i> key entry< /i> withou t a certif icate chai n).
  152        */
  153       public  Certifica te[] engin eGetCertif icateChain (String al ias)
  154       {
  155           Ce rtificate[ ] chain =  null;
  156  
  157           Ob ject entry  = entries .get(alias .toLowerCa se(Locale. ENGLISH));
  158  
  159           if  ((entry i nstanceof  PrivateKey Entry)
  160                && (((Pr ivateKeyEn try)entry) .chain !=  null)) {
  161                chain =  ((PrivateK eyEntry)en try).chain .clone();
  162           }
  163  
  164           re turn chain ;
  165       }
  166  
  167       /**
  168        * Ret urns the c ertificate  associate d with the  given ali as.
  169        *
  170        * <p> If the giv en alias n ame identi fies a
  171        * <i> trusted ce rtificate  entry</i>,  the certi ficate ass ociated wi th that
  172        * ent ry is retu rned. If t he given a lias name  identifies  a
  173        * <i> key entry< /i>, the f irst eleme nt of the  certificat e chain of  that
  174        * ent ry is retu rned, or n ull if tha t entry do es not hav e a certif icate
  175        * cha in.
  176        *
  177        * @pa ram alias  the alias  name
  178        *
  179        * @re turn the c ertificate , or null  if the giv en alias d oes not ex ist or
  180        * doe s not cont ain a cert ificate.
  181        */
  182       public  Certifica te engineG etCertific ate(String  alias) {
  183           Ce rtificate  cert = nul l;
  184  
  185           Ob ject entry  = entries .get(alias .toLowerCa se(Locale. ENGLISH));
  186  
  187           if  (entry !=  null) {
  188                if (entr y instance of Trusted CertEntry)  {
  189                    cert  = ((Trust edCertEntr y)entry).c ert;
  190                } else i f ((entry  instanceof  PrivateKe yEntry) &&
  191                            (((Priv ateKeyEntr y)entry).c hain != nu ll)) {
  192                    cert  = ((Priva teKeyEntry )entry).ch ain[0];
  193                }
  194           }
  195  
  196           re turn cert;
  197       }
  198  
  199       /**
  200        * Ret urns the c reation da te of the  entry iden tified by  the given  alias.
  201        *
  202        * @pa ram alias  the alias  name
  203        *
  204        * @re turn the c reation da te of this  entry, or  null if t he given a lias does
  205        * not  exist
  206        */
  207       public  Date engi neGetCreat ionDate(St ring alias ) {
  208           Da te date =  null;
  209  
  210           Ob ject entry  = entries .get(alias .toLowerCa se(Locale. ENGLISH));
  211  
  212           if  (entry !=  null) {
  213                // We ha ve to crea te a new i nstance of  java.util .Date beca use
  214                // dates  are not i mmutable
  215                if (entr y instance of Trusted CertEntry)  {
  216                    date  = new Dat e(((Truste dCertEntry )entry).da te.getTime ());
  217                } else i f (entry i nstanceof  PrivateKey Entry) {
  218                    date  = new Dat e(((Privat eKeyEntry) entry).dat e.getTime( ));
  219                } else {
  220                    date  = new Dat e(((Secret KeyEntry)e ntry).date .getTime() );
  221                }
  222           }
  223  
  224           re turn date;
  225       }
  226  
  227       /**
  228        * Ass igns the g iven key t o the give n alias, p rotecting  it with th e given
  229        * pas sword.
  230        *
  231        * <p> If the giv en key is  of type <c ode>java.s ecurity.Pr ivateKey</ code>,
  232        * it  must be ac companied  by a certi ficate cha in certify ing the
  233        * cor responding  public ke y.
  234        *
  235        * <p> If the giv en alias a lready exi sts, the k eystore in formation
  236        * ass ociated wi th it is o verridden  by the giv en key (an d possibly
  237        * cer tificate c hain).
  238        *
  239        * @pa ram alias  the alias  name
  240        * @pa ram key th e key to b e associat ed with th e alias
  241        * @pa ram passwo rd the pas sword to p rotect the  key
  242        * @pa ram chain  the certif icate chai n for the  correspond ing public
  243        * key  (only req uired if t he given k ey is of t ype
  244        * <co de>java.se curity.Pri vateKey</c ode>).
  245        *
  246        * @ex ception Ke yStoreExce ption if t he given k ey cannot  be protect ed, or
  247        * thi s operatio n fails fo r some oth er reason
  248        */
  249       public  void engi neSetKeyEn try(String  alias, Ke y key, cha r[] passwo rd,
  250                                        Certif icate[] ch ain)
  251           th rows KeySt oreExcepti on
  252       {
  253           sy nchronized (entries)  {
  254                try {
  255                    KeyP rotector k eyProtecto r = new Ke yProtector (password) ;
  256  
  257                    if ( key instan ceof Priva teKey) {
  258                         PrivateKey Entry entr y = new Pr ivateKeyEn try();
  259                         entry.date  = new Dat e();
  260  
  261                         // protect  the priva te key
  262                         entry.prot ectedKey =  keyProtec tor.protec t((Private Key)key);
  263  
  264                         // clone t he chain
  265                         if ((chain  != null)  &&
  266                             (chain .length != 0)) {
  267                             entry. chain = ch ain.clone( );
  268                         } else {
  269                             entry. chain = nu ll;
  270                         }
  271  
  272                         // store t he entry
  273                         entries.pu t(alias.to LowerCase( Locale.ENG LISH), ent ry);
  274  
  275                    } el se {
  276                         SecretKeyE ntry entry  = new Sec retKeyEntr y();
  277                         entry.date  = new Dat e();
  278  
  279                         // seal an d store th e key
  280                         entry.seal edKey = ke yProtector .seal(key) ;
  281                         entries.pu t(alias.to LowerCase( Locale.ENG LISH), ent ry);
  282                    }
  283  
  284                } catch  (Exception  e) {
  285                    thro w new KeyS toreExcept ion(e.getM essage());
  286                }
  287           }
  288       }
  289  
  290       /**
  291        * Ass igns the g iven key ( that has a lready bee n protecte d) to the  given
  292        * ali as.
  293        *
  294        * <p> If the pro tected key  is of typ e
  295        * <co de>java.se curity.Pri vateKey</c ode>,
  296        * it  must be ac companied  by a certi ficate cha in certify ing the
  297        * cor responding  public ke y.
  298        *
  299        * <p> If the giv en alias a lready exi sts, the k eystore in formation
  300        * ass ociated wi th it is o verridden  by the giv en key (an d possibly
  301        * cer tificate c hain).
  302        *
  303        * @pa ram alias  the alias  name
  304        * @pa ram key th e key (in  protected  format) to  be associ ated with  the alias
  305        * @pa ram chain  the certif icate chai n for the  correspond ing public
  306        * key  (only use ful if the  protected  key is of  type
  307        * <co de>java.se curity.Pri vateKey</c ode>).
  308        *
  309        * @ex ception Ke yStoreExce ption if t his operat ion fails.
  310        */
  311       public  void engi neSetKeyEn try(String  alias, by te[] key,
  312                                        Certif icate[] ch ain)
  313           th rows KeySt oreExcepti on
  314       {
  315           sy nchronized (entries)  {
  316                // We as sume it's  a private  key, becau se there i s no stand ard
  317                  // (ASN.1)  encoding  format for  wrapped  PW        keys
  318                PrivateK eyEntry en try = new  PrivateKey Entry();
  319                entry.da te = new D ate();
  320  
  321                entry.pr otectedKey  = key.clo ne();
  322                if ((cha in != null ) &&
  323                    (cha in.length  != 0)) {
  324                    entr y.chain =  chain.clon e();
  325                } else {
  326                    entr y.chain =  null;
  327                }
  328  
  329                entries. put(alias. toLowerCas e(Locale.E NGLISH), e ntry);
  330           }
  331       }
  332  
  333       /**
  334        * Ass igns the g iven certi ficate to  the given  alias.
  335        *
  336        * <p> If the giv en alias a lready exi sts in thi s keystore  and ident ifies a
  337        * <i> trusted ce rtificate  entry</i>,  the certi ficate ass ociated wi th it is
  338        * ove rridden by  the given  certifica te.
  339        *
  340        * @pa ram alias  the alias  name
  341        * @pa ram cert t he certifi cate
  342        *
  343        * @ex ception Ke yStoreExce ption if t he given a lias alrea dy exists  and does
  344        * not  identify  a <i>trust ed certifi cate entry </i>, or t his operat ion
  345        * fai ls for som e other re ason.
  346        */
  347       public  void engi neSetCerti ficateEntr y(String a lias, Cert ificate ce rt)
  348           th rows KeySt oreExcepti on
  349       {
  350           sy nchronized (entries)  {
  351  
  352                Object e ntry = ent ries.get(a lias.toLow erCase(Loc ale.ENGLIS H));
  353                if (entr y != null)  {
  354                    if ( entry inst anceof Pri vateKeyEnt ry) {
  355                         throw new  KeyStoreEx ception("C annot over write own  "
  356                                                       +  "certifica te");
  357                    } el se if (ent ry instanc eof Secret KeyEntry)  {
  358                          throw new  KeyStoreEx ception("C annot over write  PW        key");
  359                    }
  360                }
  361  
  362                TrustedC ertEntry t rustedCert Entry = ne w TrustedC ertEntry() ;
  363                trustedC ertEntry.c ert = cert ;
  364                trustedC ertEntry.d ate = new  Date();
  365                entries. put(alias. toLowerCas e(Locale.E NGLISH), t rustedCert Entry);
  366           }
  367       }
  368  
  369       /**
  370        * Del etes the e ntry ident ified by t he given a lias from  this keyst ore.
  371        *
  372        * @pa ram alias  the alias  name
  373        *
  374        * @ex ception Ke yStoreExce ption if t he entry c annot be r emoved.
  375        */
  376       public  void engi neDeleteEn try(String  alias)
  377           th rows KeySt oreExcepti on
  378       {
  379           sy nchronized (entries)  {
  380                entries. remove(ali as.toLower Case(Local e.ENGLISH) );
  381           }
  382       }
  383  
  384       /**
  385        * Lis ts all the  alias nam es of this  keystore.
  386        *
  387        * @re turn enume ration of  the alias  names
  388        */
  389       public  Enumerati on<String>  engineAli ases() {
  390           re turn entri es.keys();
  391       }
  392  
  393       /**
  394        * Che cks if the  given ali as exists  in this ke ystore.
  395        *
  396        * @pa ram alias  the alias  name
  397        *
  398        * @re turn true  if the ali as exists,  false oth erwise
  399        */
  400       public  boolean e ngineConta insAlias(S tring alia s) {
  401           re turn entri es.contain sKey(alias .toLowerCa se(Locale. ENGLISH));
  402       }
  403  
  404       /**
  405        * Ret rieves the  number of  entries i n this key store.
  406        *
  407        * @re turn the n umber of e ntries in  this keyst ore
  408        */
  409       public  int engin eSize() {
  410           re turn entri es.size();
  411       }
  412  
  413       /**
  414        * Ret urns true  if the ent ry identif ied by the  given ali as is a
  415        * <i> key entry< /i>, and f alse other wise.
  416        *
  417        * @re turn true  if the ent ry identif ied by the  given ali as is a
  418        * <i> key entry< /i>, false  otherwise .
  419        */
  420       public  boolean e ngineIsKey Entry(Stri ng alias)  {
  421           bo olean isKe y = false;
  422  
  423           Ob ject entry  = entries .get(alias .toLowerCa se(Locale. ENGLISH));
  424           if  ((entry i nstanceof  PrivateKey Entry)
  425                || (entr y instance of SecretK eyEntry))  {
  426                isKey =  true;
  427           }
  428  
  429           re turn isKey ;
  430       }
  431  
  432       /**
  433        * Ret urns true  if the ent ry identif ied by the  given ali as is a
  434        * <i> trusted ce rtificate  entry</i>,  and false  otherwise .
  435        *
  436        * @re turn true  if the ent ry identif ied by the  given ali as is a
  437        * <i> trusted ce rtificate  entry</i>,  false oth erwise.
  438        */
  439       public  boolean e ngineIsCer tificateEn try(String  alias) {
  440           bo olean isCe rt = false ;
  441           Ob ject entry  = entries .get(alias .toLowerCa se(Locale. ENGLISH));
  442           if  (entry in stanceof T rustedCert Entry) {
  443                isCert =  true;
  444           }
  445           re turn isCer t;
  446       }
  447  
  448       /**
  449        * Ret urns the ( alias) nam e of the f irst keyst ore entry  whose cert ificate
  450        * mat ches the g iven certi ficate.
  451        *
  452        * <p> This metho d attempts  to match  the given  certificat e with eac h
  453        * key store entr y. If the  entry bein g consider ed
  454        * is  a <i>trust ed certifi cate entry </i>, the  given cert ificate is
  455        * com pared to t hat entry' s certific ate. If th e entry be ing consid ered is
  456        * a < i>key entr y</i>, the  given cer tificate i s compared  to the fi rst
  457        * ele ment of th at entry's  certifica te chain ( if a chain  exists).
  458        *
  459        * @pa ram cert t he certifi cate to ma tch with.
  460        *
  461        * @re turn the ( alias) nam e of the f irst entry  with matc hing certi ficate,
  462        * or  null if no  such entr y exists i n this key store.
  463        */
  464       public  String en gineGetCer tificateAl ias(Certif icate cert ) {
  465           Ce rtificate  certElem;
  466  
  467           En umeration< String> e  = entries. keys();
  468           wh ile (e.has MoreElemen ts()) {
  469                String a lias = e.n extElement ();
  470                Object e ntry = ent ries.get(a lias);
  471                if (entr y instance of Trusted CertEntry)  {
  472                    cert Elem = ((T rustedCert Entry)entr y).cert;
  473                } else i f ((entry  instanceof  PrivateKe yEntry) &&
  474                            (((Priv ateKeyEntr y)entry).c hain != nu ll)) {
  475                    cert Elem = ((P rivateKeyE ntry)entry ).chain[0] ;
  476                } else {
  477                    cont inue;
  478                }
  479                if (cert Elem.equal s(cert)) {
  480                    retu rn alias;
  481                }
  482           }
  483           re turn null;
  484       }
  485  
  486       /**
  487        * Sto res this k eystore to  the given  output st ream, and  protects i ts
  488        * int egrity wit h the give n password .
  489        *
  490        * @pa ram stream  the outpu t stream t o which th is keystor e is writt en.
  491        * @pa ram passwo rd the pas sword to g enerate th e keystore  integrity  check
  492        *
  493        * @ex ception IO Exception  if there w as an I/O  problem wi th data
  494        * @ex ception No SuchAlgori thmExcepti on if the  appropriat e data int egrity
  495        * alg orithm cou ld not be  found
  496        * @ex ception Ce rtificateE xception i f any of t he certifi cates incl uded in
  497        * the  keystore  data could  not be st ored
  498        */
  499       public  void engi neStore(Ou tputStream  stream, c har[] pass word)
  500           th rows IOExc eption, No SuchAlgori thmExcepti on, Certif icateExcep tion
  501       {
  502           sy nchronized (entries)  {
  503                /*
  504                 * KEYST ORE FORMAT :
  505                 *
  506                 * Magic  number (b ig-endian  integer),
  507                 * Versi on of this  file form at (big-en dian integ er),
  508                 *
  509                 * Count  (big-endi an integer ),
  510                 * follo wed by "co unt" insta nces of ei ther:
  511                 *
  512                 *     {
  513                 *       tag=1 (big -endian in teger)
  514                 *       alias (UTF  string)
  515                 *       timestamp
  516                 *       encrypted  private-ke y info acc ording to  PKCS #8
  517                 *           (integ er length  followed b y encoding )
  518                 *       cert chain  (integer  count foll owed by ce rts;
  519                 *           for ea ch cert: t ype UTF st ring, foll owed by in teger
  520                 *               le ngth, foll owed by en coding)
  521                 *     }
  522                 *
  523                 * or:
  524                 *
  525                 *     {
  526                 *       tag=2 (big -endian in teger)
  527                 *       alias (UTF  string)
  528                 *       timestamp
  529                 *       cert (type  UTF strin g, followe d by integ er length,
  530                 *           follow ed by enco ding)
  531                 *     }
  532                 *
  533                 * or:
  534                 *
  535                 *     {
  536                 *       tag=3 (big -endian in teger)
  537                 *       alias (UTF  string)
  538                 *       timestamp
  539                         sealed  PW        key (in se rialized f orm)
  540                 *     }
  541                 *
  542                 * ended  by a keye d SHA1 has h (bytes o nly) of
  543                 *     {  password  + whitener  + precedi ng body }
  544                 */
  545  
  546                // passw ord is man datory whe n storing
  547                if (pass word == nu ll) {
  548                    thro w new Ille galArgumen tException ("password  can't be  null");
  549                }
  550  
  551                byte[] e ncoded; //  the certi ficate enc oding
  552  
  553                MessageD igest md =  getPreKey edHash(pas sword);
  554                DataOutp utStream d os
  555                    = ne w DataOutp utStream(n ew DigestO utputStrea m(stream,  md));
  556                // NOTE:  don't pas s dos to o os at this  point or  it'll corr upt
  557                // the k eystore!!!
  558                ObjectOu tputStream  oos = nul l;
  559                try {
  560                    dos. writeInt(J CEKS_MAGIC );
  561                    dos. writeInt(V ERSION_2);  // always  write the  latest ve rsion
  562  
  563                    dos. writeInt(e ntries.siz e());
  564  
  565                    Enum eration<St ring> e =  entries.ke ys();
  566                    whil e (e.hasMo reElements ()) {
  567  
  568                         String ali as = e.nex tElement() ;
  569                         Object ent ry = entri es.get(ali as);
  570  
  571                         if (entry  instanceof  PrivateKe yEntry) {
  572  
  573                             Privat eKeyEntry  pentry = ( PrivateKey Entry)entr y;
  574  
  575                             // wri te Private KeyEntry t ag
  576                             dos.wr iteInt(1);
  577  
  578                             // wri te the ali as
  579                             dos.wr iteUTF(ali as);
  580  
  581                             // wri te the (en try creati on) date
  582                             dos.wr iteLong(pe ntry.date. getTime()) ;
  583  
  584                             // wri te the pro tected pri vate key
  585                             dos.wr iteInt(pen try.protec tedKey.len gth);
  586                             dos.wr ite(pentry .protected Key);
  587  
  588                             // wri te the cer tificate c hain
  589                             int ch ainLen;
  590                             if (pe ntry.chain  == null)  {
  591                                 ch ainLen = 0 ;
  592                             } else  {
  593                                 ch ainLen = p entry.chai n.length;
  594                             }
  595                             dos.wr iteInt(cha inLen);
  596                             for (i nt i = 0;  i < chainL en; i++) {
  597                                 en coded = pe ntry.chain [i].getEnc oded();
  598                                 do s.writeUTF (pentry.ch ain[i].get Type());
  599                                 do s.writeInt (encoded.l ength);
  600                                 do s.write(en coded);
  601                             }
  602  
  603                         } else if  (entry ins tanceof Tr ustedCertE ntry) {
  604  
  605                             // wri te Trusted CertEntry  tag
  606                             dos.wr iteInt(2);
  607  
  608                             // wri te the ali as
  609                             dos.wr iteUTF(ali as);
  610  
  611                             // wri te the (en try creati on) date
  612                             dos.wr iteLong((( TrustedCer tEntry)ent ry).date.g etTime());
  613  
  614                             // wri te the tru sted certi ficate
  615                             encode d = ((Trus tedCertEnt ry)entry). cert.getEn coded();
  616                             dos.wr iteUTF(((T rustedCert Entry)entr y).cert.ge tType());
  617                             dos.wr iteInt(enc oded.lengt h);
  618                             dos.wr ite(encode d);
  619  
  620                         } else {
  621  
  622                             // wri te SecretK eyEntry ta g
  623                             dos.wr iteInt(3);
  624  
  625                             // wri te the ali as
  626                             dos.wr iteUTF(ali as);
  627  
  628                             // wri te the (en try creati on) date
  629                             dos.wr iteLong((( SecretKeyE ntry)entry ).date.get Time());
  630  
  631                             // wri te the sea led key
  632                             oos =  new Object OutputStre am(dos);
  633                             oos.wr iteObject( ((SecretKe yEntry)ent ry).sealed Key);
  634                             // NOT E: don't c lose oos h ere since  we are sti ll
  635                             // usi ng dos!!!
  636                         }
  637                    }
  638  
  639                    /*
  640                     * W rite the k eyed hash  which is u sed to det ect tamper ing with
  641                     * t he keystor e (such as  deleting  or modifyi ng key or
  642                     * c ertificate  entries).
  643                     */
  644                    byte  digest[]  = md.diges t();
  645  
  646                    dos. write(dige st);
  647                    dos. flush();
  648                } finall y {
  649                    if ( oos != nul l) {
  650                         oos.close( );
  651                    } el se {
  652                         dos.close( );
  653                    }
  654                }
  655           }
  656       }
  657  
  658       /**
  659        * Loa ds the key store from  the given  input str eam.
  660        *
  661        * <p> If a passw ord is giv en, it is  used to ch eck the in tegrity of  the
  662        * key store data . Otherwis e, the int egrity of  the keysto re is not  checked.
  663        *
  664        * @pa ram stream  the input  stream fr om which t he keystor e is loade d
  665        * @pa ram passwo rd the (op tional) pa ssword use d to check  the integ rity of
  666        * the  keystore.
  667        *
  668        * @ex ception IO Exception  if there i s an I/O o r format p roblem wit h the
  669        * key store data
  670        * @ex ception No SuchAlgori thmExcepti on if the  algorithm  used to ch eck
  671        * the  integrity  of the ke ystore can not be fou nd
  672        * @ex ception Ce rtificateE xception i f any of t he certifi cates in t he
  673        * key store coul d not be l oaded
  674        */
  675       public  void engi neLoad(Inp utStream s tream, cha r[] passwo rd)
  676           th rows IOExc eption, No SuchAlgori thmExcepti on, Certif icateExcep tion
  677       {
  678           sy nchronized (entries)  {
  679                DataInpu tStream di s;
  680                MessageD igest md =  null;
  681                Certific ateFactory  cf = null ;
  682                Hashtabl e<String,  Certificat eFactory>  cfs = null ;
  683                ByteArra yInputStre am bais =  null;
  684                byte[] e ncoded = n ull;
  685  
  686                if (stre am == null )
  687                    retu rn;
  688  
  689                if (pass word != nu ll) {
  690                    md =  getPreKey edHash(pas sword);
  691                    dis  = new Data InputStrea m(new Dige stInputStr eam(stream , md));
  692                } else {
  693                    dis  = new Data InputStrea m(stream);
  694                }
  695                // NOTE:  don't pas s dis to o is at this  point or  it'll fail  to load
  696                // the k eystore!!!
  697                ObjectIn putStream  ois = null ;
  698  
  699                try {
  700                    // B ody format : see stor e method
  701  
  702                    int  xMagic = d is.readInt ();
  703                    int  xVersion =  dis.readI nt();
  704  
  705                    // A ccept the  following  keystore i mplementat ions:
  706                    // -  JCEKS (th is impleme ntation),  versions 1  and 2
  707                    // -  JKS (Sun' s keystore  implement ation in J DK 1.2),
  708                    //    versions  1 and 2
  709                    if ( ((xMagic ! = JCEKS_MA GIC) && (x Magic != J KS_MAGIC))  ||
  710                         ((xVersion  != VERSIO N_1) && (x Version !=  VERSION_2 ))) {
  711                         throw new  IOExceptio n("Invalid  keystore  format");
  712                    }
  713  
  714                    if ( xVersion = = VERSION_ 1) {
  715                         cf = Certi ficateFact ory.getIns tance("X50 9");
  716                    } el se {
  717                         // version  2
  718                         cfs = new  Hashtable< String, Ce rtificateF actory>(3) ;
  719                    }
  720  
  721                    entr ies.clear( );
  722                    int  count = di s.readInt( );
  723  
  724                    for  (int i = 0 ; i < coun t; i++) {
  725                         int tag;
  726                         String ali as;
  727  
  728                         tag = dis. readInt();
  729  
  730                         if (tag ==  1) { // p rivate-key  entry
  731  
  732                             Privat eKeyEntry  entry = ne w PrivateK eyEntry();
  733  
  734                             // rea d the alia s
  735                             alias  = dis.read UTF();
  736  
  737                             // rea d the (ent ry creatio n) date
  738                             entry. date = new  Date(dis. readLong() );
  739  
  740                             // rea d the priv ate key
  741                             try {
  742                                 en try.protec tedKey = n ew byte[di s.readInt( )];
  743                             } catc h (OutOfMe moryError  e) {
  744                                 th row new IO Exception( "Keysize t oo big");
  745                             }
  746                             dis.re adFully(en try.protec tedKey);
  747  
  748                             // rea d the cert ificate ch ain
  749                             int nu mOfCerts =  dis.readI nt();
  750                             try {
  751                                 if  (numOfCer ts > 0) {
  752                                      entry.ch ain = new  Certificat e[numOfCer ts];
  753                                 }
  754                             } catc h (OutOfMe moryError  e) {
  755                                 th row new IO Exception( "Too many  certificat es in "
  756                                                          + "chain") ;
  757                             }
  758                             for (i nt j = 0;  j < numOfC erts; j++)  {
  759                                 if  (xVersion  == 2) {
  760                                      // read  the certif icate type , and inst antiate a
  761                                      // certi ficate fac tory of th at type (r euse
  762                                      // exist ing factor y if possi ble)
  763                                      String c ertType =  dis.readUT F();
  764                                      if (cfs. containsKe y(certType )) {
  765                                      // reuse  certifica te factory
  766                                          cf =  cfs.get(c ertType);
  767                                      } else {
  768                                      // creat e new cert ificate fa ctory
  769                                          cf =  Certifica teFactory. getInstanc e(
  770                                               certType);
  771                                      // store  the certi ficate fac tory so we  can
  772                                      // reuse  it later
  773                                          cfs. put(certTy pe, cf);
  774                                      }
  775                                 }
  776                                 //  instantia te the cer tificate
  777                                 tr y {
  778                                      encoded  = new byte [dis.readI nt()];
  779                                 }  catch (Out OfMemoryEr ror e) {
  780                                      throw ne w IOExcept ion("Certi ficate too  big");
  781                                 }
  782                                 di s.readFull y(encoded) ;
  783                                 ba is = new B yteArrayIn putStream( encoded);
  784                                 en try.chain[ j] = cf.ge nerateCert ificate(ba is);
  785                             }
  786  
  787                             // Add  the entry  to the li st
  788                             entrie s.put(alia s, entry);
  789  
  790                         } else if  (tag == 2)  { // trus ted certif icate entr y
  791  
  792                             Truste dCertEntry  entry = n ew Trusted CertEntry( );
  793  
  794                             // rea d the alia s
  795                             alias  = dis.read UTF();
  796  
  797                             // rea d the (ent ry creatio n) date
  798                             entry. date = new  Date(dis. readLong() );
  799  
  800                             // rea d the trus ted certif icate
  801                             if (xV ersion ==  2) {
  802                                 //  read the  certificat e type, an d instanti ate a
  803                                 //  certifica te factory  of that t ype (reuse
  804                                 //  existing  factory if  possible)
  805                                 St ring certT ype = dis. readUTF();
  806                                 if  (cfs.cont ainsKey(ce rtType)) {
  807                                      // reuse  certifica te factory
  808                                      cf = cfs .get(certT ype);
  809                                 }  else {
  810                                      // creat e new cert ificate fa ctory
  811                                      cf = Cer tificateFa ctory.getI nstance(ce rtType);
  812                                      // store  the certi ficate fac tory so we  can
  813                                      // reuse  it later
  814                                      cfs.put( certType,  cf);
  815                                 }
  816                             }
  817                             try {
  818                                 en coded = ne w byte[dis .readInt() ];
  819                             } catc h (OutOfMe moryError  e) {
  820                                 th row new IO Exception( "Certifica te too big ");
  821                             }
  822                             dis.re adFully(en coded);
  823                             bais =  new ByteA rrayInputS tream(enco ded);
  824                             entry. cert = cf. generateCe rtificate( bais);
  825  
  826                             // Add  the entry  to the li st
  827                             entrie s.put(alia s, entry);
  828  
  829                          } else if  (tag == 3)  { //  PW      -key entry
  830  
  831                             Secret KeyEntry e ntry = new  SecretKey Entry();
  832  
  833                             // rea d the alia s
  834                             alias  = dis.read UTF();
  835  
  836                             // rea d the (ent ry creatio n) date
  837                             entry. date = new  Date(dis. readLong() );
  838  
  839                             // rea d the seal ed key
  840                             try {
  841                                 oi s = new Ob jectInputS tream(dis) ;
  842                                 fi nal Object InputStrea m ois2 = o is;
  843                                 //  Set a des erializati on checker
  844                                 Ac cessContro ller.doPri vileged(
  845                                      (Privile gedAction< Void>)() - > {
  846                                          Obje ctInputFil ter.Config .setObject InputFilte r(
  847                                               ois2, new  Deserializ ationCheck er());
  848                                          retu rn null;
  849                                 }) ;
  850                                 en try.sealed Key = (Sea ledObject) ois.readOb ject();
  851                                 //  NOTE: don 't close o is here si nce we are  still
  852                                 //  using dis !!!
  853                             } catc h (ClassNo tFoundExce ption cnfe ) {
  854                                 th row new IO Exception( cnfe.getMe ssage());
  855                             } catc h (Invalid ClassExcep tion ice)  {
  856                                   throw new  IOExceptio n("Invalid   PW        key format ");
  857                             }
  858  
  859                             // Add  the entry  to the li st
  860                             entrie s.put(alia s, entry);
  861  
  862                         } else {
  863                             throw  new IOExce ption("Unr ecognized  keystore e ntry");
  864                         }
  865                    }
  866  
  867                    /*
  868                     * I f a passwo rd has bee n provided , we check  the keyed  digest
  869                     * a t the end.  If this c heck fails , the stor e has been  tampered
  870                     * w ith
  871                     */
  872                    if ( password ! = null) {
  873                         byte compu ted[], act ual[];
  874                         computed =  md.digest ();
  875                         actual = n ew byte[co mputed.len gth];
  876                         dis.readFu lly(actual );
  877                         for (int i  = 0; i <  computed.l ength; i++ ) {
  878                             if (co mputed[i]  != actual[ i]) {
  879                                 th row new IO Exception(
  880                                      "Keystor e was tamp ered with,  or "
  881                                      + "passw ord was in correct",
  882                                          new  Unrecovera bleKeyExce ption(
  883                                                   "Passw ord verifi cation fai led"));
  884                             }
  885                         }
  886                    }
  887                }  final ly {
  888                    if ( ois != nul l) {
  889                         ois.close( );
  890                    } el se {
  891                         dis.close( );
  892                    }
  893                }
  894           }
  895       }
  896  
  897       /**
  898        * To  guard agai nst tamper ing with t he keystor e, we appe nd a keyed
  899        * has h with a b it of whit ener.
  900        */
  901       privat e MessageD igest getP reKeyedHas h(char[] p assword)
  902       throws  NoSuchAlg orithmExce ption, Uns upportedEn codingExce ption {
  903           in t i, j;
  904  
  905           Me ssageDiges t md = Mes sageDigest .getInstan ce("SHA");
  906           by te[] passw dBytes = n ew byte[pa ssword.len gth * 2];
  907           fo r (i=0, j= 0; i<passw ord.length ; i++) {
  908                passwdBy tes[j++] =  (byte)(pa ssword[i]  >> 8);
  909                passwdBy tes[j++] =  (byte)pas sword[i];
  910           }
  911           md .update(pa sswdBytes) ;
  912           fo r (i=0; i< passwdByte s.length;  i++)
  913                passwdBy tes[i] = 0 ;
  914           md .update("M ighty Aphr odite".get Bytes("UTF 8"));
  915           re turn md;
  916       }
  917  
  918       /*
  919          * An Objec tInputFilt er that ch ecks the f ormat of t he  PW        key being
  920        * des erialized.
  921        */
  922       privat e static c lass Deser ialization Checker im plements O bjectInput Filter {
  923           pr ivate stat ic final i nt MAX_NES TED_DEPTH  = 2;
  924  
  925           @O verride
  926           pu blic Objec tInputFilt er.Status
  927                checkInp ut(ObjectI nputFilter .FilterInf o info) {
  928  
  929                // First  run a cus tom filter
  930                long nes tedDepth =  info.dept h();
  931                if ((nes tedDepth = = 1 &&
  932                    info .serialCla ss() != Se aledObject ForKeyProt ector.clas s) ||
  933                    nest edDepth >  MAX_NESTED _DEPTH) {
  934                    retu rn Status. REJECTED;
  935                }
  936  
  937                // Next  run the de fault filt er, if ava ilable
  938                ObjectIn putFilter  defaultFil ter =
  939                    Obje ctInputFil ter.Config .getSerial Filter();
  940                if (defa ultFilter  != null) {
  941                    retu rn default Filter.che ckInput(in fo);
  942                }
  943  
  944                return S tatus.UNDE CIDED;
  945           }
  946       }
  947   }