equal
deleted
inserted
replaced
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. |