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.security.cert.X509Certificate; 23 import java.util.Collections; 24 import java.util.List; 25 import javax.net.ssl.SSLPeerUnverifiedException; 26 import javax.net.ssl.SSLSession; 27 import javax.net.ssl.SSLSessionContext; 28 29 /** 30 * This is returned in the place of a {@link SSLSession} when no TLS connection could be negotiated, 31 * but one was requested from a method that can't throw an exception such as {@link 32 * javax.net.ssl.SSLSocket#getSession()} before {@link javax.net.ssl.SSLSocket#startHandshake()} is 33 * called. 34 */ 35 final class SSLNullSession implements ConscryptSession, Cloneable { 36 static final String INVALID_CIPHER = "SSL_NULL_WITH_NULL_NULL"; 37 38 /* 39 * Holds default instances so class preloading doesn't create an instance of 40 * it. 41 */ 42 private static class DefaultHolder { 43 static final SSLNullSession NULL_SESSION = new SSLNullSession(); 44 } 45 46 private long creationTime; 47 private long lastAccessedTime; 48 49 static ConscryptSession getNullSession() { 50 return DefaultHolder.NULL_SESSION; 51 } 52 53 static boolean isNullSession(SSLSession session) { 54 return SSLUtils.unwrapSession(session) == DefaultHolder.NULL_SESSION; 55 } 56 57 private SSLNullSession() { 58 creationTime = System.currentTimeMillis(); 59 lastAccessedTime = creationTime; 60 } 61 62 @Override 63 public String getRequestedServerName() { 64 return null; 65 } 66 67 @Override 68 public List<byte[]> getStatusResponses() { 69 return Collections.emptyList(); 70 } 71 72 @Override 73 public byte[] getPeerSignedCertificateTimestamp() { 74 return EmptyArray.BYTE; 75 } 76 77 @Override 78 public int getApplicationBufferSize() { 79 return NativeConstants.SSL3_RT_MAX_PLAIN_LENGTH; 80 } 81 82 @Override 83 public String getCipherSuite() { 84 return INVALID_CIPHER; 85 } 86 87 @Override 88 public long getCreationTime() { 89 return creationTime; 90 } 91 92 @Override 93 public byte[] getId() { 94 return EmptyArray.BYTE; 95 } 96 97 @Override 98 public long getLastAccessedTime() { 99 return lastAccessedTime; 100 } 101 102 @Override 103 public Certificate[] getLocalCertificates() { 104 return null; 105 } 106 107 @Override 108 public Principal getLocalPrincipal() { 109 return null; 110 } 111 112 @Override 113 public int getPacketBufferSize() { 114 return NativeConstants.SSL3_RT_MAX_PACKET_SIZE; 115 } 116 117 @Override 118 public javax.security.cert.X509Certificate[] getPeerCertificateChain() 119 throws SSLPeerUnverifiedException { 120 throw new SSLPeerUnverifiedException("No peer certificate"); 121 } 122 123 @Override 124 public X509Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException { 125 throw new SSLPeerUnverifiedException("No peer certificate"); 126 } 127 128 @Override 129 public String getPeerHost() { 130 return null; 131 } 132 133 @Override 134 public int getPeerPort() { 135 return -1; 136 } 137 138 @Override 139 public Principal getPeerPrincipal() throws SSLPeerUnverifiedException { 140 throw new SSLPeerUnverifiedException("No peer certificate"); 141 } 142 143 @Override 144 public String getProtocol() { 145 return "NONE"; 146 } 147 148 @Override 149 public SSLSessionContext getSessionContext() { 150 return null; 151 } 152 153 @Override 154 public Object getValue(String name) { 155 throw new UnsupportedOperationException( 156 "All calls to this method should be intercepted by ProvidedSessionDecorator."); 157 } 158 159 @Override 160 public String[] getValueNames() { 161 throw new UnsupportedOperationException( 162 "All calls to this method should be intercepted by ProvidedSessionDecorator."); 163 } 164 165 @Override 166 public void invalidate() { 167 } 168 169 @Override 170 public boolean isValid() { 171 return false; 172 } 173 174 @Override 175 public void putValue(String name, Object value) { 176 throw new UnsupportedOperationException( 177 "All calls to this method should be intercepted by ProvidedSessionDecorator."); 178 } 179 180 @Override 181 public void removeValue(String name) { 182 throw new UnsupportedOperationException( 183 "All calls to this method should be intercepted by ProvidedSessionDecorator."); 184 } 185 } 186