1 /* 2 * Copyright (c) 2002, 2018, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.security.ssl; 27 28 import java.security.*; 29 30 /** 31 * The "KeyManager" for ephemeral RSA keys. Ephemeral DH and ECDH keys 32 * are handled by the DHCrypt and ECDHCrypt classes, respectively. 33 * 34 * @author Andreas Sterbenz 35 */ 36 final class EphemeralKeyManager { 37 38 // indices for the keys array below 39 private static final int INDEX_RSA512 = 0; 40 private static final int INDEX_RSA1024 = 1; 41 42 /* 43 * Current cached RSA KeyPairs. Elements are never null. 44 * Indexed via the constants above. 45 */ 46 private final EphemeralKeyPair[] keys = new EphemeralKeyPair[] { 47 new EphemeralKeyPair(null), 48 new EphemeralKeyPair(null), 49 }; 50 EphemeralKeyManager()51 EphemeralKeyManager() { 52 // empty 53 } 54 55 /* 56 * Get a temporary RSA KeyPair. 57 */ getRSAKeyPair(boolean export, SecureRandom random)58 KeyPair getRSAKeyPair(boolean export, SecureRandom random) { 59 int length, index; 60 if (export) { 61 length = 512; 62 index = INDEX_RSA512; 63 } else { 64 length = 1024; 65 index = INDEX_RSA1024; 66 } 67 68 synchronized (keys) { 69 KeyPair kp = keys[index].getKeyPair(); 70 if (kp == null) { 71 try { 72 KeyPairGenerator kgen = JsseJce.getKeyPairGenerator("RSA"); 73 kgen.initialize(length, random); 74 keys[index] = new EphemeralKeyPair(kgen.genKeyPair()); 75 kp = keys[index].getKeyPair(); 76 } catch (Exception e) { 77 // ignore 78 } 79 } 80 return kp; 81 } 82 } 83 84 /** 85 * Inner class to handle storage of ephemeral KeyPairs. 86 */ 87 private static class EphemeralKeyPair { 88 89 // maximum number of times a KeyPair is used 90 private static final int MAX_USE = 200; 91 92 // maximum time interval in which the keypair is used (1 hour in ms) 93 private static final long USE_INTERVAL = 3600*1000; 94 95 private KeyPair keyPair; 96 private int uses; 97 private long expirationTime; 98 EphemeralKeyPair(KeyPair keyPair)99 private EphemeralKeyPair(KeyPair keyPair) { 100 this.keyPair = keyPair; 101 expirationTime = System.currentTimeMillis() + USE_INTERVAL; 102 } 103 104 /* 105 * Check if the KeyPair can still be used. 106 */ isValid()107 private boolean isValid() { 108 return (keyPair != null) && (uses < MAX_USE) 109 && (System.currentTimeMillis() < expirationTime); 110 } 111 112 /* 113 * Return the KeyPair or null if it is invalid. 114 */ getKeyPair()115 private KeyPair getKeyPair() { 116 if (isValid() == false) { 117 keyPair = null; 118 return null; 119 } 120 uses++; 121 return keyPair; 122 } 123 } 124 } 125