Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/security/pkcs11/fips/TestTLS12.java
38855 views
/*1* Copyright (c) 2018, Red Hat, Inc. and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 802966126* @summary Test TLS 1.227* @library ..28* @run main/othervm/timeout=120 TestTLS1229*/3031import java.io.File;32import java.io.FileInputStream;33import java.io.InputStream;34import java.nio.ByteBuffer;3536import java.security.interfaces.RSAPrivateKey;37import java.security.interfaces.RSAPublicKey;38import java.security.KeyStore;39import java.security.NoSuchAlgorithmException;40import java.security.Provider;41import java.security.SecureRandom;42import java.security.Security;4344import java.util.Arrays;4546import javax.crypto.Cipher;47import javax.crypto.KeyGenerator;48import javax.crypto.SecretKey;49import javax.crypto.spec.SecretKeySpec;5051import javax.net.ssl.KeyManagerFactory;52import javax.net.ssl.SSLContext;53import javax.net.ssl.SSLEngine;54import javax.net.ssl.SSLEngineResult;55import javax.net.ssl.SSLEngineResult.HandshakeStatus;56import javax.net.ssl.SSLParameters;57import javax.net.ssl.SSLSession;58import javax.net.ssl.TrustManagerFactory;5960import sun.security.internal.spec.TlsMasterSecretParameterSpec;61import sun.security.internal.spec.TlsPrfParameterSpec;62import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;6364public final class TestTLS12 extends SecmodTest {6566private static final boolean enableDebug = true;6768private static Provider sunPKCS11NSSProvider;69private static Provider sunJCEProvider;70private static com.sun.net.ssl.internal.ssl.Provider jsseProvider;71private static KeyStore ks;72private static KeyStore ts;73private static char[] passphrase = "JAHshj131@@".toCharArray();74private static RSAPrivateKey privateKey;75private static RSAPublicKey publicKey;7677public static void main(String[] args) throws Exception {78try {79initialize();80} catch (Exception e) {81System.out.println("Test skipped: failure during" +82" initialization");83return;84}8586if (shouldRun()) {87// Test against JCE88testTlsAuthenticationCodeGeneration();8990// Self-integrity test (complete TLS 1.2 communication)91new testTLS12SunPKCS11Communication().run();9293System.out.println("Test PASS - OK");94} else {95System.out.println("Test skipped: TLS 1.2 mechanisms" +96" not supported by current SunPKCS11 back-end");97}98}99100private static boolean shouldRun() {101if (sunPKCS11NSSProvider == null) {102return false;103}104try {105KeyGenerator.getInstance("SunTls12MasterSecret",106sunPKCS11NSSProvider);107KeyGenerator.getInstance(108"SunTls12RsaPremasterSecret", sunPKCS11NSSProvider);109KeyGenerator.getInstance("SunTls12Prf", sunPKCS11NSSProvider);110} catch (NoSuchAlgorithmException e) {111return false;112}113return true;114}115116private static void testTlsAuthenticationCodeGeneration()117throws Exception {118// Generate RSA Pre-Master Secret in SunPKCS11 provider119SecretKey rsaPreMasterSecret = null;120@SuppressWarnings("deprecation")121TlsRsaPremasterSecretParameterSpec rsaPreMasterSecretSpec =122new TlsRsaPremasterSecretParameterSpec(0x0303, 0x0303);123{124KeyGenerator rsaPreMasterSecretKG = KeyGenerator.getInstance(125"SunTls12RsaPremasterSecret", sunPKCS11NSSProvider);126rsaPreMasterSecretKG.init(rsaPreMasterSecretSpec, null);127rsaPreMasterSecret = rsaPreMasterSecretKG.generateKey();128}129130// Get RSA Pre-Master Secret in plain (from SunPKCS11 provider)131byte[] rsaPlainPreMasterSecret = null;132{133Cipher rsaPreMasterSecretWrapperCipher =134Cipher.getInstance("RSA/ECB/PKCS1Padding",135sunPKCS11NSSProvider);136rsaPreMasterSecretWrapperCipher.init(Cipher.WRAP_MODE, publicKey,137new SecureRandom());138byte[] rsaEncryptedPreMasterSecret =139rsaPreMasterSecretWrapperCipher.wrap(rsaPreMasterSecret);140Cipher rsaPreMasterSecretUnwrapperCipher =141Cipher.getInstance("RSA/ECB/PKCS1Padding", sunJCEProvider);142rsaPreMasterSecretUnwrapperCipher.init(Cipher.UNWRAP_MODE,143privateKey, rsaPreMasterSecretSpec);144rsaPlainPreMasterSecret = rsaPreMasterSecretUnwrapperCipher.unwrap(145rsaEncryptedPreMasterSecret, "TlsRsaPremasterSecret",146Cipher.SECRET_KEY).getEncoded();147148if (enableDebug) {149System.out.println("rsaPlainPreMasterSecret:");150for (byte b : rsaPlainPreMasterSecret) {151System.out.printf("%02X, ", b);152}153System.out.println("");154}155}156157// Generate Master Secret158SecretKey sunPKCS11MasterSecret = null;159SecretKey jceMasterSecret = null;160{161KeyGenerator sunPKCS11MasterSecretGenerator =162KeyGenerator.getInstance("SunTls12MasterSecret",163sunPKCS11NSSProvider);164KeyGenerator jceMasterSecretGenerator = KeyGenerator.getInstance(165"SunTls12MasterSecret", sunJCEProvider);166@SuppressWarnings("deprecation")167TlsMasterSecretParameterSpec sunPKCS11MasterSecretSpec =168new TlsMasterSecretParameterSpec(rsaPreMasterSecret, 3, 3,169new byte[32], new byte[32], "SHA-256", 32, 64);170@SuppressWarnings("deprecation")171TlsMasterSecretParameterSpec jceMasterSecretSpec =172new TlsMasterSecretParameterSpec(173new SecretKeySpec(rsaPlainPreMasterSecret,174"Generic"), 3, 3, new byte[32],175new byte[32], "SHA-256", 32, 64);176sunPKCS11MasterSecretGenerator.init(sunPKCS11MasterSecretSpec,177null);178jceMasterSecretGenerator.init(jceMasterSecretSpec, null);179sunPKCS11MasterSecret =180sunPKCS11MasterSecretGenerator.generateKey();181jceMasterSecret = jceMasterSecretGenerator.generateKey();182if (enableDebug) {183System.out.println("Master Secret (SunJCE):");184if (jceMasterSecret != null) {185for (byte b : jceMasterSecret.getEncoded()) {186System.out.printf("%02X, ", b);187}188System.out.println("");189}190}191}192193// Generate authentication codes194byte[] sunPKCS11AuthenticationCode = null;195byte[] jceAuthenticationCode = null;196{197// Generate SunPKCS11 authentication code198{199@SuppressWarnings("deprecation")200TlsPrfParameterSpec sunPKCS11AuthenticationCodeSpec =201new TlsPrfParameterSpec(sunPKCS11MasterSecret,202"client finished", "a".getBytes(), 12,203"SHA-256", 32, 64);204KeyGenerator sunPKCS11AuthCodeGenerator =205KeyGenerator.getInstance("SunTls12Prf",206sunPKCS11NSSProvider);207sunPKCS11AuthCodeGenerator.init(208sunPKCS11AuthenticationCodeSpec);209sunPKCS11AuthenticationCode =210sunPKCS11AuthCodeGenerator.generateKey().getEncoded();211}212213// Generate SunJCE authentication code214{215@SuppressWarnings("deprecation")216TlsPrfParameterSpec jceAuthenticationCodeSpec =217new TlsPrfParameterSpec(jceMasterSecret,218"client finished", "a".getBytes(), 12,219"SHA-256", 32, 64);220KeyGenerator jceAuthCodeGenerator =221KeyGenerator.getInstance("SunTls12Prf",222sunJCEProvider);223jceAuthCodeGenerator.init(jceAuthenticationCodeSpec);224jceAuthenticationCode =225jceAuthCodeGenerator.generateKey().getEncoded();226}227228if (enableDebug) {229System.out.println("SunPKCS11 Authentication Code: ");230for (byte b : sunPKCS11AuthenticationCode) {231System.out.printf("%02X, ", b);232}233System.out.println("");234System.out.println("SunJCE Authentication Code: ");235for (byte b : jceAuthenticationCode) {236System.out.printf("%02X, ", b);237}238System.out.println("");239}240}241242if (sunPKCS11AuthenticationCode == null ||243jceAuthenticationCode == null ||244sunPKCS11AuthenticationCode.length == 0 ||245jceAuthenticationCode.length == 0 ||246!Arrays.equals(sunPKCS11AuthenticationCode,247jceAuthenticationCode)) {248throw new Exception("Authentication codes from JCE" +249" and SunPKCS11 differ.");250}251}252253private static class testTLS12SunPKCS11Communication {254public static void run() throws Exception {255SSLEngine[][] enginesToTest = getSSLEnginesToTest();256257for (SSLEngine[] engineToTest : enginesToTest) {258259SSLEngine clientSSLEngine = engineToTest[0];260SSLEngine serverSSLEngine = engineToTest[1];261262// SSLEngine code based on RedhandshakeFinished.java263264boolean dataDone = false;265266ByteBuffer clientOut = null;267ByteBuffer clientIn = null;268ByteBuffer serverOut = null;269ByteBuffer serverIn = null;270ByteBuffer cTOs;271ByteBuffer sTOc;272273SSLSession session = clientSSLEngine.getSession();274int appBufferMax = session.getApplicationBufferSize();275int netBufferMax = session.getPacketBufferSize();276277clientIn = ByteBuffer.allocate(appBufferMax + 50);278serverIn = ByteBuffer.allocate(appBufferMax + 50);279280cTOs = ByteBuffer.allocateDirect(netBufferMax);281sTOc = ByteBuffer.allocateDirect(netBufferMax);282283clientOut = ByteBuffer.wrap(284"Hi Server, I'm Client".getBytes());285serverOut = ByteBuffer.wrap(286"Hello Client, I'm Server".getBytes());287288SSLEngineResult clientResult;289SSLEngineResult serverResult;290291while (!dataDone) {292clientResult = clientSSLEngine.wrap(clientOut, cTOs);293runDelegatedTasks(clientResult, clientSSLEngine);294serverResult = serverSSLEngine.wrap(serverOut, sTOc);295runDelegatedTasks(serverResult, serverSSLEngine);296cTOs.flip();297sTOc.flip();298299if (enableDebug) {300System.out.println("Client -> Network");301printTlsNetworkPacket("", cTOs);302System.out.println("");303System.out.println("Server -> Network");304printTlsNetworkPacket("", sTOc);305System.out.println("");306}307308clientResult = clientSSLEngine.unwrap(sTOc, clientIn);309runDelegatedTasks(clientResult, clientSSLEngine);310serverResult = serverSSLEngine.unwrap(cTOs, serverIn);311runDelegatedTasks(serverResult, serverSSLEngine);312313cTOs.compact();314sTOc.compact();315316if (!dataDone &&317(clientOut.limit() == serverIn.position()) &&318(serverOut.limit() == clientIn.position())) {319checkTransfer(serverOut, clientIn);320checkTransfer(clientOut, serverIn);321dataDone = true;322}323}324}325}326327static void printTlsNetworkPacket(String prefix, ByteBuffer bb) {328ByteBuffer slice = bb.slice();329byte[] buffer = new byte[slice.remaining()];330slice.get(buffer);331for (int i = 0; i < buffer.length; i++) {332System.out.printf("%02X, ", (byte)(buffer[i] & (byte)0xFF));333if (i % 8 == 0 && i % 16 != 0) {334System.out.print(" ");335}336if (i % 16 == 0) {337System.out.println("");338}339}340System.out.flush();341}342343private static void checkTransfer(ByteBuffer a, ByteBuffer b)344throws Exception {345a.flip();346b.flip();347if (!a.equals(b)) {348throw new Exception("Data didn't transfer cleanly");349}350a.position(a.limit());351b.position(b.limit());352a.limit(a.capacity());353b.limit(b.capacity());354}355356private static void runDelegatedTasks(SSLEngineResult result,357SSLEngine engine) throws Exception {358359if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {360Runnable runnable;361while ((runnable = engine.getDelegatedTask()) != null) {362runnable.run();363}364HandshakeStatus hsStatus = engine.getHandshakeStatus();365if (hsStatus == HandshakeStatus.NEED_TASK) {366throw new Exception(367"handshake shouldn't need additional tasks");368}369}370}371372private static SSLEngine[][] getSSLEnginesToTest() throws Exception {373SSLEngine[][] enginesToTest = new SSLEngine[2][2];374String[][] preferredSuites = new String[][]{ new String[] {375"TLS_RSA_WITH_AES_128_CBC_SHA256"376}, new String[] {377"TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"378}};379for (int i = 0; i < enginesToTest.length; i++) {380enginesToTest[i][0] = createSSLEngine(true);381enginesToTest[i][1] = createSSLEngine(false);382enginesToTest[i][0].setEnabledCipherSuites(preferredSuites[i]);383enginesToTest[i][1].setEnabledCipherSuites(preferredSuites[i]);384}385return enginesToTest;386}387388static private SSLEngine createSSLEngine(boolean client)389throws Exception {390SSLEngine ssle;391KeyManagerFactory kmf = KeyManagerFactory.getInstance("PKIX",392jsseProvider);393kmf.init(ks, passphrase);394395TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX",396jsseProvider);397tmf.init(ts);398399SSLContext sslCtx = SSLContext.getInstance("TLSv1.2",400jsseProvider);401sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);402ssle = sslCtx.createSSLEngine("localhost", 443);403ssle.setUseClientMode(client);404SSLParameters sslParameters = ssle.getSSLParameters();405ssle.setSSLParameters(sslParameters);406407return ssle;408}409}410411private static void initialize() throws Exception {412if (initSecmod() == false) {413return;414}415String configName = BASE + SEP + "fips.cfg";416sunPKCS11NSSProvider = getSunPKCS11(configName);417System.out.println("SunPKCS11 provider: " + sunPKCS11NSSProvider);418Security.addProvider(sunPKCS11NSSProvider);419420sunJCEProvider = new com.sun.crypto.provider.SunJCE();421Security.addProvider(sunJCEProvider);422423Security.removeProvider("SunJSSE");424jsseProvider =new com.sun.net.ssl.internal.ssl.Provider(425sunPKCS11NSSProvider);426Security.addProvider(jsseProvider);427System.out.println(jsseProvider.getInfo());428429ks = KeyStore.getInstance("PKCS11", sunPKCS11NSSProvider);430ks.load(null, "test12".toCharArray());431ts = ks;432433KeyStore ksPlain = readTestKeyStore();434privateKey = (RSAPrivateKey)ksPlain.getKey("rh_rsa_sha256",435passphrase);436publicKey = (RSAPublicKey)ksPlain.getCertificate(437"rh_rsa_sha256").getPublicKey();438}439440private static KeyStore readTestKeyStore() throws Exception {441File file = new File(System.getProperty("test.src", "."), "keystore");442InputStream in = new FileInputStream(file);443KeyStore ks = KeyStore.getInstance("JKS");444ks.load(in, "passphrase".toCharArray());445in.close();446return ks;447}448}449450