blob: 8222ca14821e8ec2fd4f92bdc71c7d0ea9fd6dc5 [file] [log] [blame]
Benedict Wong56420432019-11-01 16:45:08 -07001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.net;
18
Chiachang Wang69aa9882022-03-31 14:45:59 +080019import static android.net.cts.util.IkeSessionTestUtils.CHILD_PARAMS;
20import static android.net.cts.util.IkeSessionTestUtils.IKE_PARAMS;
21
Chiachang Wang137bbed2022-02-11 15:32:30 +080022import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
23
Benedict Wong56420432019-11-01 16:45:08 -070024import static org.junit.Assert.assertArrayEquals;
25import static org.junit.Assert.assertEquals;
26import static org.junit.Assert.assertNotNull;
27import static org.junit.Assert.assertNull;
28import static org.junit.Assert.assertTrue;
29import static org.junit.Assert.fail;
Benedict Wong56420432019-11-01 16:45:08 -070030
Chiachang Wang69aa9882022-03-31 14:45:59 +080031import android.net.ipsec.ike.IkeTunnelConnectionParams;
Remi NGUYEN VAN154cf1d2021-06-29 17:16:28 +090032import android.os.Build;
Benedict Wong56420432019-11-01 16:45:08 -070033import android.test.mock.MockContext;
34
35import androidx.test.filters.SmallTest;
Benedict Wong56420432019-11-01 16:45:08 -070036
37import com.android.internal.net.VpnProfile;
Daulet Zhanguzin9a357a92021-01-25 19:43:53 +000038import com.android.internal.org.bouncycastle.x509.X509V1CertificateGenerator;
Yan Yan86783c32021-04-28 15:16:22 -070039import com.android.net.module.util.ProxyUtils;
Remi NGUYEN VAN154cf1d2021-06-29 17:16:28 +090040import com.android.testutils.DevSdkIgnoreRule;
41import com.android.testutils.DevSdkIgnoreRunner;
Benedict Wong56420432019-11-01 16:45:08 -070042
43import org.junit.Before;
Chiachang Wangaf7c44c2022-01-18 19:19:25 +080044import org.junit.Rule;
Benedict Wong56420432019-11-01 16:45:08 -070045import org.junit.Test;
46import org.junit.runner.RunWith;
47
48import java.math.BigInteger;
49import java.security.KeyPair;
50import java.security.KeyPairGenerator;
51import java.security.PrivateKey;
52import java.security.cert.X509Certificate;
Benedict Wong8e3914c2020-04-09 21:49:05 -070053import java.util.ArrayList;
54import java.util.Arrays;
Benedict Wong56420432019-11-01 16:45:08 -070055import java.util.Date;
Benedict Wong8e3914c2020-04-09 21:49:05 -070056import java.util.List;
Benedict Wong56420432019-11-01 16:45:08 -070057import java.util.concurrent.TimeUnit;
58
59import javax.security.auth.x500.X500Principal;
60
61/** Unit tests for {@link Ikev2VpnProfile.Builder}. */
62@SmallTest
Remi NGUYEN VAN154cf1d2021-06-29 17:16:28 +090063@RunWith(DevSdkIgnoreRunner.class)
64@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
Benedict Wong56420432019-11-01 16:45:08 -070065public class Ikev2VpnProfileTest {
66 private static final String SERVER_ADDR_STRING = "1.2.3.4";
67 private static final String IDENTITY_STRING = "Identity";
68 private static final String USERNAME_STRING = "username";
69 private static final String PASSWORD_STRING = "pa55w0rd";
70 private static final String EXCL_LIST = "exclList";
71 private static final byte[] PSK_BYTES = "preSharedKey".getBytes();
72 private static final int TEST_MTU = 1300;
73
Chiachang Wangaf7c44c2022-01-18 19:19:25 +080074 @Rule
75 public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
76
Benedict Wong56420432019-11-01 16:45:08 -070077 private final MockContext mMockContext =
78 new MockContext() {
79 @Override
80 public String getOpPackageName() {
81 return "fooPackage";
82 }
83 };
Serik Beketayeva9dc6772020-12-06 23:08:08 -080084 private final ProxyInfo mProxy = ProxyInfo.buildDirectProxy(
85 SERVER_ADDR_STRING, -1, ProxyUtils.exclusionStringAsList(EXCL_LIST));
Benedict Wong56420432019-11-01 16:45:08 -070086
87 private X509Certificate mUserCert;
88 private X509Certificate mServerRootCa;
89 private PrivateKey mPrivateKey;
90
91 @Before
92 public void setUp() throws Exception {
93 mServerRootCa = generateRandomCertAndKeyPair().cert;
94
95 final CertificateAndKey userCertKey = generateRandomCertAndKeyPair();
96 mUserCert = userCertKey.cert;
97 mPrivateKey = userCertKey.key;
98 }
99
100 private Ikev2VpnProfile.Builder getBuilderWithDefaultOptions() {
101 final Ikev2VpnProfile.Builder builder =
102 new Ikev2VpnProfile.Builder(SERVER_ADDR_STRING, IDENTITY_STRING);
103
104 builder.setBypassable(true);
105 builder.setProxy(mProxy);
106 builder.setMaxMtu(TEST_MTU);
107 builder.setMetered(true);
108
109 return builder;
110 }
111
112 @Test
113 public void testBuildValidProfileWithOptions() throws Exception {
114 final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
115
116 builder.setAuthUsernamePassword(USERNAME_STRING, PASSWORD_STRING, mServerRootCa);
117 final Ikev2VpnProfile profile = builder.build();
118 assertNotNull(profile);
119
120 // Check non-auth parameters correctly stored
121 assertEquals(SERVER_ADDR_STRING, profile.getServerAddr());
122 assertEquals(IDENTITY_STRING, profile.getUserIdentity());
123 assertEquals(mProxy, profile.getProxyInfo());
124 assertTrue(profile.isBypassable());
125 assertTrue(profile.isMetered());
126 assertEquals(TEST_MTU, profile.getMaxMtu());
Benedict Wong8e3914c2020-04-09 21:49:05 -0700127 assertEquals(Ikev2VpnProfile.DEFAULT_ALGORITHMS, profile.getAllowedAlgorithms());
Benedict Wong56420432019-11-01 16:45:08 -0700128 }
129
130 @Test
131 public void testBuildUsernamePasswordProfile() throws Exception {
132 final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
133
134 builder.setAuthUsernamePassword(USERNAME_STRING, PASSWORD_STRING, mServerRootCa);
135 final Ikev2VpnProfile profile = builder.build();
136 assertNotNull(profile);
137
138 assertEquals(USERNAME_STRING, profile.getUsername());
139 assertEquals(PASSWORD_STRING, profile.getPassword());
140 assertEquals(mServerRootCa, profile.getServerRootCaCert());
141
142 assertNull(profile.getPresharedKey());
143 assertNull(profile.getRsaPrivateKey());
144 assertNull(profile.getUserCert());
145 }
146
147 @Test
148 public void testBuildDigitalSignatureProfile() throws Exception {
149 final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
150
151 builder.setAuthDigitalSignature(mUserCert, mPrivateKey, mServerRootCa);
152 final Ikev2VpnProfile profile = builder.build();
153 assertNotNull(profile);
154
155 assertEquals(profile.getUserCert(), mUserCert);
156 assertEquals(mPrivateKey, profile.getRsaPrivateKey());
157 assertEquals(profile.getServerRootCaCert(), mServerRootCa);
158
159 assertNull(profile.getPresharedKey());
160 assertNull(profile.getUsername());
161 assertNull(profile.getPassword());
162 }
163
164 @Test
165 public void testBuildPresharedKeyProfile() throws Exception {
166 final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
167
168 builder.setAuthPsk(PSK_BYTES);
169 final Ikev2VpnProfile profile = builder.build();
170 assertNotNull(profile);
171
172 assertArrayEquals(PSK_BYTES, profile.getPresharedKey());
173
174 assertNull(profile.getServerRootCaCert());
175 assertNull(profile.getUsername());
176 assertNull(profile.getPassword());
177 assertNull(profile.getRsaPrivateKey());
178 assertNull(profile.getUserCert());
179 }
180
181 @Test
Benedict Wong8e3914c2020-04-09 21:49:05 -0700182 public void testBuildWithAllowedAlgorithmsAead() throws Exception {
183 final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
184 builder.setAuthPsk(PSK_BYTES);
185
Yan Yan86783c32021-04-28 15:16:22 -0700186 List<String> allowedAlgorithms =
187 Arrays.asList(
188 IpSecAlgorithm.AUTH_CRYPT_AES_GCM,
189 IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305);
Benedict Wong8e3914c2020-04-09 21:49:05 -0700190 builder.setAllowedAlgorithms(allowedAlgorithms);
191
192 final Ikev2VpnProfile profile = builder.build();
193 assertEquals(allowedAlgorithms, profile.getAllowedAlgorithms());
194 }
195
196 @Test
197 public void testBuildWithAllowedAlgorithmsNormal() throws Exception {
198 final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
199 builder.setAuthPsk(PSK_BYTES);
200
201 List<String> allowedAlgorithms =
Yan Yan86783c32021-04-28 15:16:22 -0700202 Arrays.asList(
203 IpSecAlgorithm.AUTH_HMAC_SHA512,
204 IpSecAlgorithm.AUTH_AES_XCBC,
205 IpSecAlgorithm.AUTH_AES_CMAC,
206 IpSecAlgorithm.CRYPT_AES_CBC,
207 IpSecAlgorithm.CRYPT_AES_CTR);
Benedict Wong8e3914c2020-04-09 21:49:05 -0700208 builder.setAllowedAlgorithms(allowedAlgorithms);
209
210 final Ikev2VpnProfile profile = builder.build();
211 assertEquals(allowedAlgorithms, profile.getAllowedAlgorithms());
212 }
213
214 @Test
215 public void testSetAllowedAlgorithmsEmptyList() throws Exception {
216 final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
217
218 try {
219 builder.setAllowedAlgorithms(new ArrayList<>());
220 fail("Expected exception due to no valid algorithm set");
221 } catch (IllegalArgumentException expected) {
222 }
223 }
224
225 @Test
226 public void testSetAllowedAlgorithmsInvalidList() throws Exception {
227 final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
228 List<String> allowedAlgorithms = new ArrayList<>();
229
230 try {
231 builder.setAllowedAlgorithms(Arrays.asList(IpSecAlgorithm.AUTH_HMAC_SHA256));
232 fail("Expected exception due to missing encryption");
233 } catch (IllegalArgumentException expected) {
234 }
235
236 try {
237 builder.setAllowedAlgorithms(Arrays.asList(IpSecAlgorithm.CRYPT_AES_CBC));
238 fail("Expected exception due to missing authentication");
239 } catch (IllegalArgumentException expected) {
240 }
241 }
242
243 @Test
244 public void testSetAllowedAlgorithmsInsecureAlgorithm() throws Exception {
245 final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
246 List<String> allowedAlgorithms = new ArrayList<>();
247
248 try {
249 builder.setAllowedAlgorithms(Arrays.asList(IpSecAlgorithm.AUTH_HMAC_MD5));
250 fail("Expected exception due to insecure algorithm");
251 } catch (IllegalArgumentException expected) {
252 }
253
254 try {
255 builder.setAllowedAlgorithms(Arrays.asList(IpSecAlgorithm.AUTH_HMAC_SHA1));
256 fail("Expected exception due to insecure algorithm");
257 } catch (IllegalArgumentException expected) {
258 }
259 }
260
261 @Test
Benedict Wong56420432019-11-01 16:45:08 -0700262 public void testBuildNoAuthMethodSet() throws Exception {
263 final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
264
265 try {
266 builder.build();
267 fail("Expected exception due to lack of auth method");
268 } catch (IllegalArgumentException expected) {
269 }
270 }
271
Chiachang Wangb4a319b2022-01-06 16:55:41 +0800272
Chiachang Wang137bbed2022-02-11 15:32:30 +0800273 // TODO: Refer to Build.VERSION_CODES.SC_V2 when it's available in AOSP and mainline branch
274 @DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
Chiachang Wangb4a319b2022-01-06 16:55:41 +0800275 @Test
276 public void testBuildExcludeLocalRoutesSet() throws Exception {
277 final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
278 builder.setAuthPsk(PSK_BYTES);
Chiachang Wangf8908742022-02-08 15:45:11 +0800279 builder.setLocalRoutesExcluded(true);
Chiachang Wangb4a319b2022-01-06 16:55:41 +0800280
281 final Ikev2VpnProfile profile = builder.build();
282 assertNotNull(profile);
Chiachang Wangf8908742022-02-08 15:45:11 +0800283 assertTrue(profile.areLocalRoutesExcluded());
Chiachang Wangb4a319b2022-01-06 16:55:41 +0800284
285 builder.setBypassable(false);
286 try {
287 builder.build();
288 fail("Expected exception because excludeLocalRoutes should be set only"
289 + " on the bypassable VPN");
290 } catch (IllegalArgumentException expected) {
291 }
292 }
293
Benedict Wong56420432019-11-01 16:45:08 -0700294 @Test
295 public void testBuildInvalidMtu() throws Exception {
296 final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
297
298 try {
299 builder.setMaxMtu(500);
300 fail("Expected exception due to too-small MTU");
301 } catch (IllegalArgumentException expected) {
302 }
303 }
304
305 private void verifyVpnProfileCommon(VpnProfile profile) {
306 assertEquals(SERVER_ADDR_STRING, profile.server);
307 assertEquals(IDENTITY_STRING, profile.ipsecIdentifier);
308 assertEquals(mProxy, profile.proxy);
309 assertTrue(profile.isBypassable);
310 assertTrue(profile.isMetered);
311 assertEquals(TEST_MTU, profile.maxMtu);
312 }
313
314 @Test
315 public void testPskConvertToVpnProfile() throws Exception {
316 final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
317
318 builder.setAuthPsk(PSK_BYTES);
319 final VpnProfile profile = builder.build().toVpnProfile();
320
321 verifyVpnProfileCommon(profile);
322 assertEquals(Ikev2VpnProfile.encodeForIpsecSecret(PSK_BYTES), profile.ipsecSecret);
323
324 // Check nothing else is set
325 assertEquals("", profile.username);
326 assertEquals("", profile.password);
327 assertEquals("", profile.ipsecUserCert);
328 assertEquals("", profile.ipsecCaCert);
329 }
330
331 @Test
332 public void testUsernamePasswordConvertToVpnProfile() throws Exception {
333 final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
334
335 builder.setAuthUsernamePassword(USERNAME_STRING, PASSWORD_STRING, mServerRootCa);
336 final VpnProfile profile = builder.build().toVpnProfile();
337
338 verifyVpnProfileCommon(profile);
339 assertEquals(USERNAME_STRING, profile.username);
340 assertEquals(PASSWORD_STRING, profile.password);
341 assertEquals(Ikev2VpnProfile.certificateToPemString(mServerRootCa), profile.ipsecCaCert);
342
343 // Check nothing else is set
344 assertEquals("", profile.ipsecUserCert);
345 assertEquals("", profile.ipsecSecret);
346 }
347
348 @Test
349 public void testRsaConvertToVpnProfile() throws Exception {
350 final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
351
352 builder.setAuthDigitalSignature(mUserCert, mPrivateKey, mServerRootCa);
353 final VpnProfile profile = builder.build().toVpnProfile();
354
Benedict Wong94d31ad2020-01-17 19:41:38 -0800355 final String expectedSecret = Ikev2VpnProfile.PREFIX_INLINE
356 + Ikev2VpnProfile.encodeForIpsecSecret(mPrivateKey.getEncoded());
Benedict Wong56420432019-11-01 16:45:08 -0700357 verifyVpnProfileCommon(profile);
358 assertEquals(Ikev2VpnProfile.certificateToPemString(mUserCert), profile.ipsecUserCert);
359 assertEquals(
Benedict Wong94d31ad2020-01-17 19:41:38 -0800360 expectedSecret,
Benedict Wong56420432019-11-01 16:45:08 -0700361 profile.ipsecSecret);
362 assertEquals(Ikev2VpnProfile.certificateToPemString(mServerRootCa), profile.ipsecCaCert);
363
364 // Check nothing else is set
365 assertEquals("", profile.username);
366 assertEquals("", profile.password);
367 }
368
369 @Test
370 public void testPskFromVpnProfileDiscardsIrrelevantValues() throws Exception {
371 final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
372
373 builder.setAuthPsk(PSK_BYTES);
374 final VpnProfile profile = builder.build().toVpnProfile();
375 profile.username = USERNAME_STRING;
376 profile.password = PASSWORD_STRING;
377 profile.ipsecCaCert = Ikev2VpnProfile.certificateToPemString(mServerRootCa);
378 profile.ipsecUserCert = Ikev2VpnProfile.certificateToPemString(mUserCert);
379
380 final Ikev2VpnProfile result = Ikev2VpnProfile.fromVpnProfile(profile);
381 assertNull(result.getUsername());
382 assertNull(result.getPassword());
383 assertNull(result.getUserCert());
384 assertNull(result.getRsaPrivateKey());
385 assertNull(result.getServerRootCaCert());
386 }
387
388 @Test
389 public void testUsernamePasswordFromVpnProfileDiscardsIrrelevantValues() throws Exception {
390 final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
391
392 builder.setAuthUsernamePassword(USERNAME_STRING, PASSWORD_STRING, mServerRootCa);
393 final VpnProfile profile = builder.build().toVpnProfile();
394 profile.ipsecSecret = new String(PSK_BYTES);
395 profile.ipsecUserCert = Ikev2VpnProfile.certificateToPemString(mUserCert);
396
397 final Ikev2VpnProfile result = Ikev2VpnProfile.fromVpnProfile(profile);
398 assertNull(result.getPresharedKey());
399 assertNull(result.getUserCert());
400 assertNull(result.getRsaPrivateKey());
401 }
402
403 @Test
404 public void testRsaFromVpnProfileDiscardsIrrelevantValues() throws Exception {
405 final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
406
407 builder.setAuthDigitalSignature(mUserCert, mPrivateKey, mServerRootCa);
408 final VpnProfile profile = builder.build().toVpnProfile();
409 profile.username = USERNAME_STRING;
410 profile.password = PASSWORD_STRING;
411
412 final Ikev2VpnProfile result = Ikev2VpnProfile.fromVpnProfile(profile);
413 assertNull(result.getUsername());
414 assertNull(result.getPassword());
415 assertNull(result.getPresharedKey());
416 }
417
418 @Test
419 public void testPskConversionIsLossless() throws Exception {
420 final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
421
422 builder.setAuthPsk(PSK_BYTES);
423 final Ikev2VpnProfile ikeProfile = builder.build();
424
425 assertEquals(ikeProfile, Ikev2VpnProfile.fromVpnProfile(ikeProfile.toVpnProfile()));
426 }
427
428 @Test
429 public void testUsernamePasswordConversionIsLossless() throws Exception {
430 final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
431
432 builder.setAuthUsernamePassword(USERNAME_STRING, PASSWORD_STRING, mServerRootCa);
433 final Ikev2VpnProfile ikeProfile = builder.build();
434
435 assertEquals(ikeProfile, Ikev2VpnProfile.fromVpnProfile(ikeProfile.toVpnProfile()));
436 }
437
438 @Test
439 public void testRsaConversionIsLossless() throws Exception {
440 final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
441
442 builder.setAuthDigitalSignature(mUserCert, mPrivateKey, mServerRootCa);
443 final Ikev2VpnProfile ikeProfile = builder.build();
444
445 assertEquals(ikeProfile, Ikev2VpnProfile.fromVpnProfile(ikeProfile.toVpnProfile()));
446 }
447
Chiachang Wang69aa9882022-03-31 14:45:59 +0800448 @Test
449 public void testConversionIsLosslessWithIkeTunConnParams() throws Exception {
450 final IkeTunnelConnectionParams tunnelParams =
451 new IkeTunnelConnectionParams(IKE_PARAMS, CHILD_PARAMS);
452 // Config authentication related fields is not required while building with
453 // IkeTunnelConnectionParams.
454 final Ikev2VpnProfile ikeProfile = new Ikev2VpnProfile.Builder(tunnelParams).build();
455 assertEquals(ikeProfile, Ikev2VpnProfile.fromVpnProfile(ikeProfile.toVpnProfile()));
456 }
457
458 @Test
459 public void testEquals() throws Exception {
460 // Verify building without IkeTunnelConnectionParams
461 final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
462 builder.setAuthDigitalSignature(mUserCert, mPrivateKey, mServerRootCa);
463 assertEquals(builder.build(), builder.build());
464
465 // Verify building with IkeTunnelConnectionParams
466 final IkeTunnelConnectionParams tunnelParams =
467 new IkeTunnelConnectionParams(IKE_PARAMS, CHILD_PARAMS);
468 final IkeTunnelConnectionParams tunnelParams2 =
469 new IkeTunnelConnectionParams(IKE_PARAMS, CHILD_PARAMS);
470 assertEquals(new Ikev2VpnProfile.Builder(tunnelParams).build(),
471 new Ikev2VpnProfile.Builder(tunnelParams2).build());
472 }
473
474
Benedict Wong56420432019-11-01 16:45:08 -0700475 private static class CertificateAndKey {
476 public final X509Certificate cert;
477 public final PrivateKey key;
478
479 CertificateAndKey(X509Certificate cert, PrivateKey key) {
480 this.cert = cert;
481 this.key = key;
482 }
483 }
484
485 private static CertificateAndKey generateRandomCertAndKeyPair() throws Exception {
486 final Date validityBeginDate =
487 new Date(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1L));
488 final Date validityEndDate =
489 new Date(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1L));
490
491 // Generate a keypair
492 final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
493 keyPairGenerator.initialize(512);
494 final KeyPair keyPair = keyPairGenerator.generateKeyPair();
495
496 final X500Principal dnName = new X500Principal("CN=test.android.com");
497 final X509V1CertificateGenerator certGen = new X509V1CertificateGenerator();
498 certGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
499 certGen.setSubjectDN(dnName);
500 certGen.setIssuerDN(dnName);
501 certGen.setNotBefore(validityBeginDate);
502 certGen.setNotAfter(validityEndDate);
503 certGen.setPublicKey(keyPair.getPublic());
504 certGen.setSignatureAlgorithm("SHA256WithRSAEncryption");
505
506 final X509Certificate cert = certGen.generate(keyPair.getPrivate(), "AndroidOpenSSL");
507 return new CertificateAndKey(cert, keyPair.getPrivate());
508 }
509}