1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
//
// SunJSSE does not support dynamic system properties, no way to re-use
// system properties in samevm/agentvm mode.
//
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.KeyManagerFactorySpi;
import javax.net.ssl.ManagerFactoryParameters;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.X509KeyManager;
import java.net.Socket;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.Security;
import java.security.UnrecoverableKeyException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
/*
* @test
* @bug 8262186
* @summary Callback semantics of the method X509KeyManager.chooseClientAlias(...)
* @library /javax/net/ssl/templates
* @modules java.base/sun.security.ssl:+open
* java.base/javax.net.ssl:+open
* @run main/othervm MultipleChooseAlias PKIX
* @run main/othervm MultipleChooseAlias SunX509
*/
public class MultipleChooseAlias extends SSLSocketTemplate {
static volatile int numOfCalls = 0;
static String kmfAlgorithm = null;
@Override
protected void configureServerSocket(SSLServerSocket socket) {
socket.setNeedClientAuth(true);
}
@Override
protected ContextParameters getClientContextParameters() {
return new ContextParameters("TLS", "PKIX", "Mine");
}
public static void main(String[] args) throws Exception {
kmfAlgorithm = args[0];
Security.addProvider(new MyProvider());
try {
new MultipleChooseAlias().run();
} catch (Exception e) {
// expected
}
if (numOfCalls != 1) {
throw new RuntimeException("Too many times " + numOfCalls);
}
}
static class MyProvider extends Provider {
public MyProvider() {
super("Mine", "1", "many many things");
put("KeyManagerFactory.Mine", "MultipleChooseAlias$MyKMF");
}
}
// This KeyManagerFactory impl returns key managers
// wrapped in MyKM
public static class MyKMF extends KeyManagerFactorySpi {
KeyManagerFactory fac;
public MyKMF() {
try {
fac = KeyManagerFactory.getInstance(kmfAlgorithm);
} catch (Exception e) {
throw new AssertionError(e);
}
}
@Override
protected void engineInit(KeyStore ks, char[] password)
throws KeyStoreException, NoSuchAlgorithmException,
UnrecoverableKeyException {
fac.init(ks, password);
}
@Override
protected void engineInit(ManagerFactoryParameters spec)
throws InvalidAlgorithmParameterException {
fac.init(spec);
}
@Override
protected KeyManager[] engineGetKeyManagers() {
KeyManager[] result = fac.getKeyManagers();
for (int i = 0; i < result.length; i++) {
result[i] = new MyKM((X509KeyManager)result[i]);
}
return result;
}
}
// This KeyManager remembers how many times chooseClientAlias is called.
static class MyKM implements X509KeyManager {
X509KeyManager km;
MyKM(X509KeyManager km) {
this.km = km;
}
public String[] getClientAliases(String keyType, Principal[] issuers) {
return km.getClientAliases(keyType, issuers);
}
public String chooseClientAlias(String[] keyType, Principal[] issuers,
Socket socket) {
System.out.println("chooseClientAlias called on "
+ Arrays.toString(keyType));
numOfCalls++;
return null; // so it will try all key types and finally fails
}
public String[] getServerAliases(String keyType, Principal[] issuers) {
return getServerAliases(keyType, issuers);
}
public String chooseServerAlias(String keyType, Principal[] issuers,
Socket socket) {
return km.chooseServerAlias(keyType, issuers, socket);
}
public X509Certificate[] getCertificateChain(String alias) {
return km.getCertificateChain(alias);
}
public PrivateKey getPrivateKey(String alias) {
return km.getPrivateKey(alias);
}
}
}
|