1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.conscrypt; 19 20 import java.security.Principal; 21 import java.security.cert.Certificate; 22 import java.util.HashMap; 23 import javax.net.ssl.*; 24 25 /** 26 * This is returned in the place of a {@link SSLSession} when no TLS connection could be negotiated, 27 * but one was requested from a method that can't throw an exception such as {@link 28 * SSLSocket#getSession()} before {@link SSLSocket#startHandshake()} is called. 29 */ 30 final class SSLNullSession implements SSLSession, Cloneable { 31 static final String INVALID_CIPHER = "SSL_NULL_WITH_NULL_NULL"; 32 33 /* 34 * Holds default instances so class preloading doesn't create an instance of 35 * it. 36 */ 37 private static class DefaultHolder { 38 static final SSLNullSession NULL_SESSION = new SSLNullSession(); 39 } 40 41 private final HashMap<String, Object> values = new HashMap<String, Object>(); 42 43 private long creationTime; 44 private long lastAccessedTime; 45 getNullSession()46 static SSLSession getNullSession() { 47 return DefaultHolder.NULL_SESSION; 48 } 49 isNullSession(SSLSession session)50 static boolean isNullSession(SSLSession session) { 51 return session == DefaultHolder.NULL_SESSION; 52 } 53 SSLNullSession()54 private SSLNullSession() { 55 creationTime = System.currentTimeMillis(); 56 lastAccessedTime = creationTime; 57 } 58 59 @Override getApplicationBufferSize()60 public int getApplicationBufferSize() { 61 return NativeConstants.SSL3_RT_MAX_PLAIN_LENGTH; 62 } 63 64 @Override getCipherSuite()65 public String getCipherSuite() { 66 return INVALID_CIPHER; 67 } 68 69 @Override getCreationTime()70 public long getCreationTime() { 71 return creationTime; 72 } 73 74 @Override getId()75 public byte[] getId() { 76 return EmptyArray.BYTE; 77 } 78 79 @Override getLastAccessedTime()80 public long getLastAccessedTime() { 81 return lastAccessedTime; 82 } 83 84 @Override getLocalCertificates()85 public Certificate[] getLocalCertificates() { 86 return null; 87 } 88 89 @Override getLocalPrincipal()90 public Principal getLocalPrincipal() { 91 return null; 92 } 93 94 @Override getPacketBufferSize()95 public int getPacketBufferSize() { 96 return NativeConstants.SSL3_RT_MAX_PACKET_SIZE; 97 } 98 99 @Override getPeerCertificateChain()100 public javax.security.cert.X509Certificate[] getPeerCertificateChain() 101 throws SSLPeerUnverifiedException { 102 throw new SSLPeerUnverifiedException("No peer certificate"); 103 } 104 105 @Override getPeerCertificates()106 public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException { 107 throw new SSLPeerUnverifiedException("No peer certificate"); 108 } 109 110 @Override getPeerHost()111 public String getPeerHost() { 112 return null; 113 } 114 115 @Override getPeerPort()116 public int getPeerPort() { 117 return -1; 118 } 119 120 @Override getPeerPrincipal()121 public Principal getPeerPrincipal() throws SSLPeerUnverifiedException { 122 throw new SSLPeerUnverifiedException("No peer certificate"); 123 } 124 125 @Override getProtocol()126 public String getProtocol() { 127 return "NONE"; 128 } 129 130 @Override getSessionContext()131 public SSLSessionContext getSessionContext() { 132 return null; 133 } 134 135 @Override getValue(String name)136 public Object getValue(String name) { 137 if (name == null) { 138 throw new IllegalArgumentException("name == null"); 139 } 140 return values.get(name); 141 } 142 143 @Override getValueNames()144 public String[] getValueNames() { 145 return values.keySet().toArray(new String[values.size()]); 146 } 147 148 @Override invalidate()149 public void invalidate() { 150 } 151 152 @Override isValid()153 public boolean isValid() { 154 return false; 155 } 156 157 @Override putValue(String name, Object value)158 public void putValue(String name, Object value) { 159 if (name == null || value == null) { 160 throw new IllegalArgumentException("name == null || value == null"); 161 } 162 Object old = values.put(name, value); 163 if (value instanceof SSLSessionBindingListener) { 164 ((SSLSessionBindingListener) value).valueBound(new SSLSessionBindingEvent(this, name)); 165 } 166 if (old instanceof SSLSessionBindingListener) { 167 ((SSLSessionBindingListener) old).valueUnbound(new SSLSessionBindingEvent(this, name)); 168 } 169 170 } 171 172 @Override removeValue(String name)173 public void removeValue(String name) { 174 if (name == null) { 175 throw new IllegalArgumentException("name == null"); 176 } 177 Object old = values.remove(name); 178 if (old instanceof SSLSessionBindingListener) { 179 SSLSessionBindingListener listener = (SSLSessionBindingListener) old; 180 listener.valueUnbound(new SSLSessionBindingEvent(this, name)); 181 } 182 } 183 } 184