src/java.base/share/classes/com/sun/crypto/provider/PBEKey.java
changeset 51293 53c3b460503c
parent 48560 46e99460e8c9
child 51504 c9a3e3cac9c7
equal deleted inserted replaced
51292:0538a5cdb474 51293:53c3b460503c
     1 /*
     1 /*
     2  * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    27 
    27 
    28 import java.lang.ref.Reference;
    28 import java.lang.ref.Reference;
    29 import java.security.MessageDigest;
    29 import java.security.MessageDigest;
    30 import java.security.KeyRep;
    30 import java.security.KeyRep;
    31 import java.security.spec.InvalidKeySpecException;
    31 import java.security.spec.InvalidKeySpecException;
       
    32 import java.util.Arrays;
    32 import java.util.Locale;
    33 import java.util.Locale;
    33 import javax.crypto.SecretKey;
    34 import javax.crypto.SecretKey;
    34 import javax.crypto.spec.PBEKeySpec;
    35 import javax.crypto.spec.PBEKeySpec;
    35 
    36 
    36 import jdk.internal.ref.CleanerFactory;
    37 import jdk.internal.ref.CleanerFactory;
    52     /**
    53     /**
    53      * Creates a PBE key from a given PBE key specification.
    54      * Creates a PBE key from a given PBE key specification.
    54      *
    55      *
    55      * @param keytype the given PBE key specification
    56      * @param keytype the given PBE key specification
    56      */
    57      */
    57     PBEKey(PBEKeySpec keySpec, String keytype) throws InvalidKeySpecException {
    58     PBEKey(PBEKeySpec keySpec, String keytype, boolean useCleaner)
       
    59             throws InvalidKeySpecException {
    58         char[] passwd = keySpec.getPassword();
    60         char[] passwd = keySpec.getPassword();
    59         if (passwd == null) {
    61         if (passwd == null) {
    60             // Should allow an empty password.
    62             // Should allow an empty password.
    61             passwd = new char[0];
    63             passwd = new char[0];
    62         }
    64         }
    69             }
    71             }
    70         }
    72         }
    71         this.key = new byte[passwd.length];
    73         this.key = new byte[passwd.length];
    72         for (int i=0; i<passwd.length; i++)
    74         for (int i=0; i<passwd.length; i++)
    73             this.key[i] = (byte) (passwd[i] & 0x7f);
    75             this.key[i] = (byte) (passwd[i] & 0x7f);
    74         java.util.Arrays.fill(passwd, ' ');
    76         Arrays.fill(passwd, ' ');
    75         type = keytype;
    77         type = keytype;
    76 
    78 
    77         // Use the cleaner to zero the key when no longer referenced
    79         // Use the cleaner to zero the key when no longer referenced
    78         final byte[] k = this.key;
    80         if (useCleaner) {
    79         CleanerFactory.cleaner().register(this,
    81             final byte[] k = this.key;
    80                 () -> java.util.Arrays.fill(k, (byte)0x00));
    82             CleanerFactory.cleaner().register(this,
       
    83                 () -> Arrays.fill(k, (byte) 0x00));
       
    84         }
    81     }
    85     }
    82 
    86 
    83     public byte[] getEncoded() {
    87     public byte[] getEncoded() {
    84         // The key is zeroized by finalize()
    88         // The key is zeroized by finalize()
    85         // The reachability fence ensures finalize() isn't called early
    89         // The reachability fence ensures finalize() isn't called early
   120         if (!(that.getAlgorithm().equalsIgnoreCase(type)))
   124         if (!(that.getAlgorithm().equalsIgnoreCase(type)))
   121             return false;
   125             return false;
   122 
   126 
   123         byte[] thatEncoded = that.getEncoded();
   127         byte[] thatEncoded = that.getEncoded();
   124         boolean ret = MessageDigest.isEqual(this.key, thatEncoded);
   128         boolean ret = MessageDigest.isEqual(this.key, thatEncoded);
   125         java.util.Arrays.fill(thatEncoded, (byte)0x00);
   129         Arrays.fill(thatEncoded, (byte)0x00);
   126         return ret;
   130         return ret;
       
   131     }
       
   132 
       
   133     /**
       
   134      * Clears the internal copy of the key.
       
   135      *
       
   136      */
       
   137     @Override
       
   138     public void destroy() {
       
   139         if (key != null) {
       
   140             Arrays.fill(key, (byte) 0x00);
       
   141             key = null;
       
   142         }
   127     }
   143     }
   128 
   144 
   129     /**
   145     /**
   130      * readObject is called to restore the state of this key from
   146      * readObject is called to restore the state of this key from
   131      * a stream.
   147      * a stream.