Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/javax/security/auth/Destroyable/KeyDestructionTest.java
41153 views
1
/*
2
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
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
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
/*
25
* @test
26
* @bug 6263419
27
* @summary No way to clean the memory for a java.security.Key
28
*/
29
30
import java.security.*;
31
import java.util.*;
32
import javax.crypto.*;
33
import javax.security.auth.Destroyable;
34
import javax.security.auth.DestroyFailedException;
35
36
public class KeyDestructionTest {
37
public static void main(String[] args) throws Exception {
38
KeyPair keypair = generateKeyPair("RSA", 1024);
39
40
// Check keys that support and have implemented key destruction
41
testKeyDestruction(new MyDestroyableSecretKey());
42
testKeyDestruction(new MyDestroyablePrivateKey());
43
44
// Check keys that support but have not implemented key destruction
45
testNoKeyDestruction(generateSecretKey("AES", 128));
46
testNoKeyDestruction(keypair.getPrivate());
47
48
// Check keys that do not support key destruction
49
try {
50
testKeyDestruction(keypair.getPublic());
51
} catch (UnsupportedOperationException uoe) {
52
// not an error
53
System.out.println(keypair.getPublic().getClass().getName() +
54
" keys do not support key destruction");
55
}
56
57
System.out.println("PASSED.");
58
}
59
60
// Check the behaviour of a key that implements key destruction
61
private static void testKeyDestruction(Key key) throws Exception {
62
String klass = key.getClass().getName();
63
boolean hasUsable = key instanceof Usable;
64
65
try {
66
key.getAlgorithm();
67
key.getFormat();
68
if (allZero(key.getEncoded())) {
69
throw new Exception("error: key destroyed prematurely");
70
}
71
} catch (IllegalStateException ise) {
72
throw new Exception("error: unexpected ISE", ise);
73
}
74
75
if (hasUsable) {
76
((Usable) key).useKey();
77
}
78
79
destroyKey(key);
80
81
try {
82
if (hasUsable) {
83
((Usable) key).useKey();
84
}
85
} catch (IllegalStateException ise) {
86
// not an error
87
}
88
89
try {
90
key.getAlgorithm();
91
key.getFormat();
92
if (!allZero(key.getEncoded())) {
93
throw new Exception("error: key destroyed incorrectly");
94
}
95
} catch (IllegalStateException ise) {
96
// not an error
97
}
98
99
System.out.println("A " + klass +
100
" key has been successfully destroyed");
101
}
102
103
// Check the behaviour of a key that does not implement key destruction
104
private static void testNoKeyDestruction(Destroyable key)
105
throws Exception {
106
String klass = key.getClass().getName();
107
108
if (key.isDestroyed()) {
109
throw new Exception("error: a " + klass +
110
" key has been unexpectedly destroyed");
111
}
112
try {
113
key.destroy();
114
} catch (DestroyFailedException dfe) {
115
// not an error
116
117
if (key.isDestroyed()) {
118
throw new Exception("error: a " + klass +
119
" key has been unexpectedly destroyed");
120
}
121
System.out.println(klass + " keys are not destroyable");
122
return;
123
}
124
throw new Exception("error: key may been unexpectedly destroyed");
125
}
126
127
private static KeyPair generateKeyPair(String algorithm, int size)
128
throws NoSuchAlgorithmException {
129
KeyPairGenerator generator = KeyPairGenerator.getInstance(algorithm);
130
generator.initialize(size);
131
return generator.genKeyPair();
132
}
133
134
private static SecretKey generateSecretKey(String algorithm, int size)
135
throws NoSuchAlgorithmException {
136
KeyGenerator generator = KeyGenerator.getInstance(algorithm);
137
generator.init(size);
138
return generator.generateKey();
139
}
140
141
private static void destroyKey(Key key) throws Exception {
142
String klass = key.getClass().getName();
143
144
if (!(key instanceof Destroyable)) {
145
throw new UnsupportedOperationException();
146
}
147
148
Destroyable dKey = (Destroyable) key;
149
if (dKey.isDestroyed()) {
150
throw new Exception("error: a " + klass +
151
" key has already been destroyed");
152
}
153
dKey.destroy();
154
if (!dKey.isDestroyed()) {
155
throw new Exception("error: a " + klass +
156
" key has NOT been destroyed");
157
}
158
}
159
160
private static boolean allZero(byte[] bytes) {
161
int count = 0;
162
for (byte b : bytes) {
163
if (b == 0x00) {
164
count++;
165
}
166
}
167
return (bytes.length == count);
168
}
169
}
170
171
interface Usable {
172
public void useKey();
173
}
174
175
class MyDestroyableSecretKey implements SecretKey, Usable {
176
private byte[] encoded = new byte[]{0x0F, 0x1F, 0x2F, 0x3F}; // non-zero
177
private boolean isDestroyed = false;
178
179
@Override
180
public void useKey() {
181
if (isDestroyed) {
182
throw new IllegalStateException();
183
}
184
}
185
186
@Override
187
public String getAlgorithm() {
188
return "MyDestroyableSecretKey algorithm";
189
}
190
191
@Override
192
public String getFormat() {
193
return "MyDestroyableSecretKey format";
194
}
195
196
@Override
197
public byte[] getEncoded() {
198
return this.encoded;
199
}
200
201
@Override
202
public void destroy() throws DestroyFailedException {
203
if (!this.isDestroyed) {
204
Arrays.fill(encoded, (byte) 0);
205
this.isDestroyed = true;
206
}
207
}
208
209
@Override
210
public boolean isDestroyed() {
211
return this.isDestroyed;
212
}
213
}
214
215
class MyDestroyablePrivateKey implements PrivateKey, Usable {
216
private byte[] encoded = new byte[]{0x4F, 0x5F, 0x6F, 0x7F}; // non-zero
217
private boolean isDestroyed = false;
218
219
@Override
220
public void useKey() {
221
if (isDestroyed) {
222
throw new IllegalStateException();
223
}
224
}
225
226
@Override
227
public String getAlgorithm() {
228
return "MyDestroyablePrivateKey algorithm";
229
}
230
231
@Override
232
public String getFormat() {
233
return "MyDestroyablePrivateKey format";
234
}
235
236
@Override
237
public byte[] getEncoded() {
238
return this.encoded;
239
}
240
241
@Override
242
public void destroy() throws DestroyFailedException {
243
if (!this.isDestroyed) {
244
Arrays.fill(encoded, (byte) 0);
245
this.isDestroyed = true;
246
}
247
}
248
249
@Override
250
public boolean isDestroyed() {
251
return this.isDestroyed;
252
}
253
}
254
255