|
1 /* |
|
2 * Copyright (c) 2016, 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 /* @test |
|
25 * @bug 8051408 |
|
26 * @modules java.base/sun.security.provider |
|
27 * @summary check the AbstractDrbg API etc |
|
28 */ |
|
29 |
|
30 import java.security.*; |
|
31 import sun.security.provider.AbstractDrbg; |
|
32 import static java.security.DrbgParameters.Capability.*; |
|
33 |
|
34 /** |
|
35 * This test makes sure the AbstractDrbg API works as specified. It also |
|
36 * checks the SecureRandom API. |
|
37 */ |
|
38 public class AbstractDrbgSpec { |
|
39 |
|
40 public static void main(String args[]) throws Exception { |
|
41 |
|
42 // getInstance from a provider. |
|
43 |
|
44 Provider p = new All("A", 0, ""); |
|
45 byte[] bytes = new byte[100]; |
|
46 |
|
47 // A non-DRBG |
|
48 iae(() -> SecureRandom.getInstance("S1", null, p)); |
|
49 nsae(() -> SecureRandom.getInstance("S1", |
|
50 new SecureRandomParameters() {}, p)); |
|
51 |
|
52 SecureRandom s1 = SecureRandom.getInstance("S1", p); |
|
53 if (s1.getParameters() != null) { |
|
54 throw new Exception(); |
|
55 } |
|
56 |
|
57 iae(() -> s1.nextBytes(bytes, null)); |
|
58 uoe(() -> s1.nextBytes(bytes, new SecureRandomParameters() {})); |
|
59 uoe(() -> s1.reseed()); |
|
60 iae(() -> s1.reseed(null)); |
|
61 uoe(() -> s1.reseed(new SecureRandomParameters() {})); |
|
62 |
|
63 // A weak DRBG |
|
64 iae(() -> SecureRandom.getInstance("S2", null, p)); |
|
65 nsae(() -> SecureRandom.getInstance("S2", |
|
66 new SecureRandomParameters() {}, p)); |
|
67 nsae(() -> SecureRandom.getInstance("S2", |
|
68 DrbgParameters.instantiation(256, NONE, null), p)); |
|
69 nsae(() -> SecureRandom.getInstance("S2", |
|
70 DrbgParameters.instantiation(-1, PR_AND_RESEED, null), p)); |
|
71 nsae(() -> SecureRandom.getInstance("S2", |
|
72 DrbgParameters.instantiation(-1, RESEED_ONLY, null), p)); |
|
73 |
|
74 SecureRandom s2 = SecureRandom.getInstance("S2", |
|
75 DrbgParameters.instantiation(-1, NONE, null), p); |
|
76 equals(s2, "S2,SQUEEZE,128,none"); |
|
77 equals(s2.getParameters(), "128,none,null"); |
|
78 |
|
79 npe(() -> s2.nextBytes(null)); |
|
80 iae(() -> s2.nextBytes(bytes, null)); |
|
81 iae(() -> s2.nextBytes(bytes, new SecureRandomParameters() {})); |
|
82 uoe(() -> s2.reseed()); |
|
83 iae(() -> s2.reseed(null)); |
|
84 |
|
85 iae(() -> s2.nextBytes(bytes, |
|
86 DrbgParameters.nextBytes(-1, false, new byte[101]))); |
|
87 s2.nextBytes(new byte[101], |
|
88 DrbgParameters.nextBytes(-1, false, new byte[100])); |
|
89 s2.nextBytes(bytes, |
|
90 DrbgParameters.nextBytes(-1, false, new byte[100])); |
|
91 |
|
92 // A strong DRBG |
|
93 iae(() -> SecureRandom.getInstance("S3", null, p)); |
|
94 nsae(() -> SecureRandom.getInstance("S3", |
|
95 new SecureRandomParameters() {}, p)); |
|
96 SecureRandom.getInstance("S3", |
|
97 DrbgParameters.instantiation(192, PR_AND_RESEED, null), p); |
|
98 |
|
99 SecureRandom s3 = SecureRandom.getInstance("S3", p); |
|
100 equals(s3, "S3,SQUEEZE,128,reseed_only"); |
|
101 equals(s3.getParameters(), "128,reseed_only,null"); |
|
102 |
|
103 iae(() -> s3.nextBytes(bytes, |
|
104 DrbgParameters.nextBytes(192, false, null))); |
|
105 iae(() -> s3.nextBytes(bytes, |
|
106 DrbgParameters.nextBytes(112, true, null))); |
|
107 iae(() -> s3.reseed(new SecureRandomParameters() {})); |
|
108 |
|
109 SecureRandom s32 = SecureRandom.getInstance( |
|
110 "S3", DrbgParameters.instantiation(192, PR_AND_RESEED, null), p); |
|
111 equals(s32, "S3,SQUEEZE,192,pr_and_reseed"); |
|
112 equals(s32.getParameters(), "192,pr_and_reseed,null"); |
|
113 |
|
114 s32.nextBytes(bytes, DrbgParameters.nextBytes(192, false, null)); |
|
115 s32.nextBytes(bytes, DrbgParameters.nextBytes(112, true, null)); |
|
116 s32.reseed(); |
|
117 s32.reseed(DrbgParameters.reseed(true, new byte[100])); |
|
118 |
|
119 // getInstance from competitive providers. |
|
120 |
|
121 Provider l = new Legacy("L", 0, ""); |
|
122 Provider w = new Weak("W", 0, ""); |
|
123 Provider s = new Strong("S", 0, ""); |
|
124 |
|
125 Security.addProvider(l); |
|
126 Security.addProvider(w); |
|
127 Security.addProvider(s); |
|
128 |
|
129 SecureRandom s4; |
|
130 |
|
131 try { |
|
132 s4 = SecureRandom.getInstance("S"); |
|
133 if (s4.getProvider() != l) { |
|
134 throw new Exception(); |
|
135 } |
|
136 |
|
137 nsae(() -> SecureRandom.getInstance( |
|
138 "S", DrbgParameters.instantiation(256, NONE, null))); |
|
139 |
|
140 s4 = SecureRandom.getInstance( |
|
141 "S", DrbgParameters.instantiation(192, NONE, null)); |
|
142 if (s4.getProvider() != s) { |
|
143 throw new Exception(); |
|
144 } |
|
145 |
|
146 s4 = SecureRandom.getInstance( |
|
147 "S", DrbgParameters.instantiation(128, PR_AND_RESEED, null)); |
|
148 if (s4.getProvider() != s) { |
|
149 throw new Exception(); |
|
150 } |
|
151 |
|
152 s4 = SecureRandom.getInstance( |
|
153 "S", DrbgParameters.instantiation(128, RESEED_ONLY, null)); |
|
154 if (s4.getProvider() != s) { |
|
155 throw new Exception(); |
|
156 } |
|
157 |
|
158 s4 = SecureRandom.getInstance( |
|
159 "S", DrbgParameters.instantiation(128, NONE, null)); |
|
160 if (s4.getProvider() != w) { |
|
161 throw new Exception(); |
|
162 } |
|
163 } finally { |
|
164 Security.removeProvider("L"); |
|
165 Security.removeProvider("W"); |
|
166 Security.removeProvider("S"); |
|
167 } |
|
168 } |
|
169 |
|
170 public static class All extends Provider { |
|
171 protected All(String name, double version, String info) { |
|
172 super(name, version, info); |
|
173 put("SecureRandom.S1", S1.class.getName()); |
|
174 put("SecureRandom.S2", S2.class.getName()); |
|
175 put("SecureRandom.S3", S3.class.getName()); |
|
176 } |
|
177 } |
|
178 |
|
179 // Providing S with no params support |
|
180 public static class Legacy extends Provider { |
|
181 protected Legacy(String name, double version, String info) { |
|
182 super(name, version, info); |
|
183 put("SecureRandom.S", S1.class.getName()); |
|
184 } |
|
185 } |
|
186 |
|
187 public static class Weak extends Provider { |
|
188 protected Weak(String name, double version, String info) { |
|
189 super(name, version, info); |
|
190 put("SecureRandom.S", S2.class.getName()); |
|
191 } |
|
192 } |
|
193 |
|
194 public static class Strong extends Provider { |
|
195 protected Strong(String name, double version, String info) { |
|
196 super(name, version, info); |
|
197 put("SecureRandom.S", S3.class.getName()); |
|
198 } |
|
199 } |
|
200 |
|
201 // This is not a DRBG. |
|
202 public static class S1 extends SecureRandomSpi { |
|
203 @Override |
|
204 protected void engineSetSeed(byte[] seed) { |
|
205 } |
|
206 |
|
207 @Override |
|
208 protected void engineNextBytes(byte[] bytes) { |
|
209 } |
|
210 |
|
211 @Override |
|
212 protected byte[] engineGenerateSeed(int numBytes) { |
|
213 return new byte[numBytes]; |
|
214 } |
|
215 } |
|
216 |
|
217 // This is a strong DRBG. |
|
218 public static class S3 extends AbstractDrbg { |
|
219 |
|
220 public S3(SecureRandomParameters params) { |
|
221 supportPredictionResistance = true; |
|
222 supportReseeding = true; |
|
223 highestSupportedSecurityStrength = 192; |
|
224 mechName = "S3"; |
|
225 algorithm = "SQUEEZE"; |
|
226 configure(params); |
|
227 } |
|
228 protected void chooseAlgorithmAndStrength() { |
|
229 if (requestedInstantiationSecurityStrength < 0) { |
|
230 securityStrength = DEFAULT_STRENGTH; |
|
231 } else { |
|
232 securityStrength = requestedInstantiationSecurityStrength; |
|
233 } |
|
234 minLength = securityStrength / 8; |
|
235 maxAdditionalInputLength = maxPersonalizationStringLength = 100; |
|
236 } |
|
237 |
|
238 @Override |
|
239 protected void initEngine() { |
|
240 |
|
241 } |
|
242 |
|
243 @Override |
|
244 protected void instantiateAlgorithm(byte[] ei) { |
|
245 |
|
246 } |
|
247 |
|
248 @Override |
|
249 protected void generateAlgorithm(byte[] result, byte[] additionalInput) { |
|
250 |
|
251 } |
|
252 |
|
253 @Override |
|
254 protected void reseedAlgorithm(byte[] ei, byte[] additionalInput) { |
|
255 |
|
256 } |
|
257 } |
|
258 |
|
259 // This is a weak DRBG. maximum strength is 128 and does |
|
260 // not support prediction resistance or reseed. |
|
261 public static class S2 extends S3 { |
|
262 public S2(SecureRandomParameters params) { |
|
263 super(null); |
|
264 mechName = "S2"; |
|
265 highestSupportedSecurityStrength = 128; |
|
266 supportPredictionResistance = false; |
|
267 supportReseeding = false; |
|
268 configure(params); |
|
269 } |
|
270 } |
|
271 |
|
272 static void nsae(RunnableWithException r) throws Exception { |
|
273 checkException(r, NoSuchAlgorithmException.class); |
|
274 } |
|
275 |
|
276 static void iae(RunnableWithException r) throws Exception { |
|
277 checkException(r, IllegalArgumentException.class); |
|
278 } |
|
279 |
|
280 static void uoe(RunnableWithException r) throws Exception { |
|
281 checkException(r, UnsupportedOperationException.class); |
|
282 } |
|
283 |
|
284 static void npe(RunnableWithException r) throws Exception { |
|
285 checkException(r, NullPointerException.class); |
|
286 } |
|
287 |
|
288 interface RunnableWithException { |
|
289 void run() throws Exception; |
|
290 } |
|
291 |
|
292 static void checkException(RunnableWithException r, Class ex) |
|
293 throws Exception { |
|
294 try { |
|
295 r.run(); |
|
296 } catch (Exception e) { |
|
297 if (ex.isAssignableFrom(e.getClass())) { |
|
298 return; |
|
299 } |
|
300 throw e; |
|
301 } |
|
302 throw new Exception("No exception thrown"); |
|
303 } |
|
304 |
|
305 static void equals(Object o, String s) throws Exception { |
|
306 if (!o.toString().equals(s)) { |
|
307 throw new Exception(o.toString() + " is not " + s); |
|
308 } |
|
309 } |
|
310 } |