1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.ssl;
17
18 import io.netty.buffer.ByteBuf;
19 import io.netty.buffer.ByteBufAllocator;
20 import io.netty.handler.ssl.util.LazyJavaxX509Certificate;
21 import io.netty.handler.ssl.util.LazyX509Certificate;
22 import io.netty.internal.tcnative.AsyncTask;
23 import io.netty.internal.tcnative.Buffer;
24 import io.netty.internal.tcnative.SSL;
25 import io.netty.util.AbstractReferenceCounted;
26 import io.netty.util.CharsetUtil;
27 import io.netty.util.ReferenceCounted;
28 import io.netty.util.ResourceLeakDetector;
29 import io.netty.util.ResourceLeakDetectorFactory;
30 import io.netty.util.ResourceLeakTracker;
31 import io.netty.util.internal.EmptyArrays;
32 import io.netty.util.internal.PlatformDependent;
33 import io.netty.util.internal.StringUtil;
34 import io.netty.util.internal.ThrowableUtil;
35 import io.netty.util.internal.UnstableApi;
36 import io.netty.util.internal.logging.InternalLogger;
37 import io.netty.util.internal.logging.InternalLoggerFactory;
38
39 import java.nio.ByteBuffer;
40 import java.nio.ReadOnlyBufferException;
41 import java.security.AlgorithmConstraints;
42 import java.security.Principal;
43 import java.security.cert.Certificate;
44 import java.util.ArrayList;
45 import java.util.Arrays;
46 import java.util.Collection;
47 import java.util.Collections;
48 import java.util.HashSet;
49 import java.util.LinkedHashSet;
50 import java.util.List;
51 import java.util.Map;
52 import java.util.Set;
53 import java.util.concurrent.ConcurrentHashMap;
54 import java.util.concurrent.locks.Lock;
55 import javax.crypto.spec.SecretKeySpec;
56 import javax.net.ssl.SNIHostName;
57 import javax.net.ssl.SNIMatcher;
58 import javax.net.ssl.SNIServerName;
59 import javax.net.ssl.SSLEngine;
60 import javax.net.ssl.SSLEngineResult;
61 import javax.net.ssl.SSLException;
62 import javax.net.ssl.SSLHandshakeException;
63 import javax.net.ssl.SSLParameters;
64 import javax.net.ssl.SSLPeerUnverifiedException;
65 import javax.net.ssl.SSLSession;
66 import javax.net.ssl.SSLSessionBindingEvent;
67 import javax.net.ssl.SSLSessionBindingListener;
68 import javax.security.cert.X509Certificate;
69
70 import static io.netty.handler.ssl.OpenSsl.memoryAddress;
71 import static io.netty.handler.ssl.SslUtils.SSL_RECORD_HEADER_LENGTH;
72 import static io.netty.util.internal.EmptyArrays.EMPTY_STRINGS;
73 import static io.netty.util.internal.ObjectUtil.checkNotNull;
74 import static io.netty.util.internal.ObjectUtil.checkNotNullArrayParam;
75 import static io.netty.util.internal.ObjectUtil.checkNotNullWithIAE;
76 import static java.lang.Integer.MAX_VALUE;
77 import static java.lang.Math.min;
78 import static javax.net.ssl.SSLEngineResult.HandshakeStatus.FINISHED;
79 import static javax.net.ssl.SSLEngineResult.HandshakeStatus.NEED_TASK;
80 import static javax.net.ssl.SSLEngineResult.HandshakeStatus.NEED_UNWRAP;
81 import static javax.net.ssl.SSLEngineResult.HandshakeStatus.NEED_WRAP;
82 import static javax.net.ssl.SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING;
83 import static javax.net.ssl.SSLEngineResult.Status.BUFFER_OVERFLOW;
84 import static javax.net.ssl.SSLEngineResult.Status.BUFFER_UNDERFLOW;
85 import static javax.net.ssl.SSLEngineResult.Status.CLOSED;
86 import static javax.net.ssl.SSLEngineResult.Status.OK;
87
88
89
90
91
92
93
94
95
96
97 public class ReferenceCountedOpenSslEngine extends SSLEngine implements ReferenceCounted, ApplicationProtocolAccessor {
98
99 private static final InternalLogger logger = InternalLoggerFactory.getInstance(ReferenceCountedOpenSslEngine.class);
100
101 private static final ResourceLeakDetector<ReferenceCountedOpenSslEngine> leakDetector =
102 ResourceLeakDetectorFactory.instance().newResourceLeakDetector(ReferenceCountedOpenSslEngine.class);
103 private static final int OPENSSL_OP_NO_PROTOCOL_INDEX_SSLV2 = 0;
104 private static final int OPENSSL_OP_NO_PROTOCOL_INDEX_SSLV3 = 1;
105 private static final int OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1 = 2;
106 private static final int OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_1 = 3;
107 private static final int OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_2 = 4;
108 private static final int OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_3 = 5;
109 private static final int[] OPENSSL_OP_NO_PROTOCOLS = {
110 SSL.SSL_OP_NO_SSLv2,
111 SSL.SSL_OP_NO_SSLv3,
112 SSL.SSL_OP_NO_TLSv1,
113 SSL.SSL_OP_NO_TLSv1_1,
114 SSL.SSL_OP_NO_TLSv1_2,
115 SSL.SSL_OP_NO_TLSv1_3
116 };
117
118
119
120
121 static final int MAX_PLAINTEXT_LENGTH = SSL.SSL_MAX_PLAINTEXT_LENGTH;
122
123
124
125 static final int MAX_RECORD_SIZE = SSL.SSL_MAX_RECORD_LENGTH;
126
127 private static final SSLEngineResult NEED_UNWRAP_OK = new SSLEngineResult(OK, NEED_UNWRAP, 0, 0);
128 private static final SSLEngineResult NEED_UNWRAP_CLOSED = new SSLEngineResult(CLOSED, NEED_UNWRAP, 0, 0);
129 private static final SSLEngineResult NEED_WRAP_OK = new SSLEngineResult(OK, NEED_WRAP, 0, 0);
130 private static final SSLEngineResult NEED_WRAP_CLOSED = new SSLEngineResult(CLOSED, NEED_WRAP, 0, 0);
131 private static final SSLEngineResult CLOSED_NOT_HANDSHAKING = new SSLEngineResult(CLOSED, NOT_HANDSHAKING, 0, 0);
132
133
134 private long ssl;
135 private long networkBIO;
136
137 private enum HandshakeState {
138
139
140
141 NOT_STARTED,
142
143
144
145 STARTED_IMPLICITLY,
146
147
148
149 STARTED_EXPLICITLY,
150
151
152
153 FINISHED
154 }
155
156 private HandshakeState handshakeState = HandshakeState.NOT_STARTED;
157 private boolean receivedShutdown;
158 private volatile boolean destroyed;
159 private volatile String applicationProtocol;
160 private volatile boolean needTask;
161 private boolean hasTLSv13Cipher;
162 private boolean sessionSet;
163
164
165 private final ResourceLeakTracker<ReferenceCountedOpenSslEngine> leak;
166 private final AbstractReferenceCounted refCnt = new AbstractReferenceCounted() {
167 @Override
168 public ReferenceCounted touch(Object hint) {
169 if (leak != null) {
170 leak.record(hint);
171 }
172
173 return ReferenceCountedOpenSslEngine.this;
174 }
175
176 @Override
177 protected void deallocate() {
178 shutdown();
179 if (leak != null) {
180 boolean closed = leak.close(ReferenceCountedOpenSslEngine.this);
181 assert closed;
182 }
183 parentContext.release();
184 }
185 };
186
187 private final Set<String> enabledProtocols = new LinkedHashSet<String>();
188
189 private volatile ClientAuth clientAuth = ClientAuth.NONE;
190
191 private String endpointIdentificationAlgorithm;
192 private List<SNIServerName> serverNames;
193 private AlgorithmConstraints algorithmConstraints;
194
195
196 private volatile Collection<SNIMatcher> matchers;
197
198
199 private boolean isInboundDone;
200 private boolean outboundClosed;
201
202 final boolean jdkCompatibilityMode;
203 private final boolean clientMode;
204 final ByteBufAllocator alloc;
205 private final OpenSslEngineMap engineMap;
206 private final OpenSslApplicationProtocolNegotiator apn;
207 private final ReferenceCountedOpenSslContext parentContext;
208 private final OpenSslInternalSession session;
209 private final ByteBuffer[] singleSrcBuffer = new ByteBuffer[1];
210 private final ByteBuffer[] singleDstBuffer = new ByteBuffer[1];
211 private final boolean enableOcsp;
212 private int maxWrapOverhead;
213 private int maxWrapBufferSize;
214 private Throwable pendingException;
215
216
217
218
219
220
221
222
223
224
225
226
227
228 ReferenceCountedOpenSslEngine(ReferenceCountedOpenSslContext context, final ByteBufAllocator alloc, String peerHost,
229 int peerPort, boolean jdkCompatibilityMode, boolean leakDetection,
230 String endpointIdentificationAlgorithm, List<SNIServerName> serverNames) {
231 super(peerHost, peerPort);
232 OpenSsl.ensureAvailability();
233 engineMap = context.engineMap;
234 enableOcsp = context.enableOcsp;
235 this.jdkCompatibilityMode = jdkCompatibilityMode;
236 this.alloc = checkNotNull(alloc, "alloc");
237 apn = (OpenSslApplicationProtocolNegotiator) context.applicationProtocolNegotiator();
238 clientMode = context.isClient();
239 this.endpointIdentificationAlgorithm = endpointIdentificationAlgorithm;
240 this.serverNames = serverNames;
241
242 session = new ExtendedOpenSslSession(new DefaultOpenSslSession(context.sessionContext())) {
243 private String[] peerSupportedSignatureAlgorithms;
244 private List<SNIServerName> requestedServerNames;
245
246 @Override
247 public List<SNIServerName> getRequestedServerNames() {
248 if (clientMode) {
249 List<SNIServerName> names = ReferenceCountedOpenSslEngine.this.serverNames;
250 return names == null ? Collections.emptyList() :
251 Collections.unmodifiableList(new ArrayList<>(names));
252 } else {
253 synchronized (ReferenceCountedOpenSslEngine.this) {
254 if (requestedServerNames == null) {
255 if (isDestroyed()) {
256 requestedServerNames = Collections.emptyList();
257 } else {
258 String name = SSL.getSniHostname(ssl);
259 if (name == null) {
260 requestedServerNames = Collections.emptyList();
261 } else {
262
263
264 byte[] hostname = SSL.getSniHostname(ssl).getBytes(CharsetUtil.UTF_8);
265 requestedServerNames = hostname == null || hostname.length == 0 ?
266 Collections.emptyList() :
267 Collections.singletonList(new SNIHostName(hostname));
268 }
269 }
270 }
271 return requestedServerNames;
272 }
273 }
274 }
275
276 @Override
277 public String[] getPeerSupportedSignatureAlgorithms() {
278 synchronized (ReferenceCountedOpenSslEngine.this) {
279 if (peerSupportedSignatureAlgorithms == null) {
280 if (isDestroyed()) {
281 peerSupportedSignatureAlgorithms = EMPTY_STRINGS;
282 } else {
283 String[] algs = SSL.getSigAlgs(ssl);
284 if (algs == null) {
285 peerSupportedSignatureAlgorithms = EMPTY_STRINGS;
286 } else {
287 Set<String> algorithmList = new LinkedHashSet<String>(algs.length);
288 for (String alg: algs) {
289 String converted = SignatureAlgorithmConverter.toJavaName(alg);
290
291 if (converted != null) {
292 algorithmList.add(converted);
293 }
294 }
295 peerSupportedSignatureAlgorithms = algorithmList.toArray(EMPTY_STRINGS);
296 }
297 }
298 }
299 return peerSupportedSignatureAlgorithms.clone();
300 }
301 }
302
303 @Override
304 public List<byte[]> getStatusResponses() {
305 byte[] ocspResponse = null;
306 if (enableOcsp && clientMode) {
307 synchronized (ReferenceCountedOpenSslEngine.this) {
308 if (!isDestroyed()) {
309 ocspResponse = SSL.getOcspResponse(ssl);
310 }
311 }
312 }
313 return ocspResponse == null ?
314 Collections.<byte[]>emptyList() : Collections.singletonList(ocspResponse);
315 }
316 };
317
318 if (!context.sessionContext().useKeyManager()) {
319 session.setLocalCertificate(context.keyCertChain);
320 }
321
322 Lock readerLock = context.ctxLock.readLock();
323 readerLock.lock();
324 final long finalSsl;
325 try {
326 finalSsl = SSL.newSSL(context.ctx, !context.isClient());
327 } finally {
328 readerLock.unlock();
329 }
330 synchronized (this) {
331 ssl = finalSsl;
332 try {
333 networkBIO = SSL.bioNewByteBuffer(ssl, context.getBioNonApplicationBufferSize());
334
335
336
337 setClientAuth(clientMode ? ClientAuth.NONE : context.clientAuth);
338
339 assert context.protocols != null;
340 hasTLSv13Cipher = context.hasTLSv13Cipher;
341
342 setEnabledProtocols(context.protocols);
343
344
345
346 boolean usePeerHost = SslUtils.isValidHostNameForSNI(peerHost) && isValidHostNameForSNI(peerHost);
347 boolean useServerNames = serverNames != null && !serverNames.isEmpty();
348 if (clientMode && (usePeerHost || useServerNames)) {
349
350 if (usePeerHost) {
351 SSL.setTlsExtHostName(ssl, peerHost);
352 this.serverNames = Collections.singletonList(new SNIHostName(peerHost));
353 } else if (useServerNames) {
354 for (SNIServerName serverName : serverNames) {
355 if (serverName instanceof SNIHostName) {
356 SNIHostName name = (SNIHostName) serverName;
357 SSL.setTlsExtHostName(ssl, name.getAsciiName());
358 } else {
359 throw new IllegalArgumentException("Only " + SNIHostName.class.getName()
360 + " instances are supported, but found: " + serverName);
361 }
362 }
363 }
364 }
365
366 if (enableOcsp) {
367 SSL.enableOcsp(ssl);
368 }
369
370 if (!jdkCompatibilityMode) {
371 SSL.setMode(ssl, SSL.getMode(ssl) | SSL.SSL_MODE_ENABLE_PARTIAL_WRITE);
372 }
373
374 if (isProtocolEnabled(SSL.getOptions(ssl), SSL.SSL_OP_NO_TLSv1_3, SslProtocols.TLS_v1_3)) {
375 final boolean enableTickets = clientMode ?
376 ReferenceCountedOpenSslContext.CLIENT_ENABLE_SESSION_TICKET_TLSV13 :
377 ReferenceCountedOpenSslContext.SERVER_ENABLE_SESSION_TICKET_TLSV13;
378 if (enableTickets) {
379
380
381
382
383
384
385
386 SSL.clearOptions(ssl, SSL.SSL_OP_NO_TICKET);
387 }
388 }
389
390 if (OpenSsl.isBoringSSL() && clientMode) {
391
392
393
394
395 SSL.setRenegotiateMode(ssl, SSL.SSL_RENEGOTIATE_ONCE);
396 }
397
398 calculateMaxWrapOverhead();
399
400
401 configureEndpointVerification(endpointIdentificationAlgorithm);
402 } catch (Throwable cause) {
403
404
405 shutdown();
406
407 PlatformDependent.throwException(cause);
408 }
409 }
410
411
412
413 parentContext = context;
414 parentContext.retain();
415
416
417
418 leak = leakDetection ? leakDetector.track(this) : null;
419 }
420
421 private static boolean isValidHostNameForSNI(String hostname) {
422 try {
423 new SNIHostName(hostname);
424 return true;
425 } catch (IllegalArgumentException illegal) {
426 return false;
427 }
428 }
429
430 final synchronized String[] authMethods() {
431 if (isDestroyed()) {
432 return EMPTY_STRINGS;
433 }
434 return SSL.authenticationMethods(ssl);
435 }
436
437 final boolean setKeyMaterial(OpenSslKeyMaterial keyMaterial) throws Exception {
438 synchronized (this) {
439 if (isDestroyed()) {
440 return false;
441 }
442 SSL.setKeyMaterial(ssl, keyMaterial.certificateChainAddress(), keyMaterial.privateKeyAddress());
443 }
444 session.setLocalCertificate(keyMaterial.certificateChain());
445 return true;
446 }
447
448 final synchronized SecretKeySpec masterKey() {
449 if (isDestroyed()) {
450 return null;
451 }
452 return new SecretKeySpec(SSL.getMasterKey(ssl), "AES");
453 }
454
455 synchronized boolean isSessionReused() {
456 if (isDestroyed()) {
457 return false;
458 }
459 return SSL.isSessionReused(ssl);
460 }
461
462
463
464
465 @UnstableApi
466 public void setOcspResponse(byte[] response) {
467 if (!enableOcsp) {
468 throw new IllegalStateException("OCSP stapling is not enabled");
469 }
470
471 if (clientMode) {
472 throw new IllegalStateException("Not a server SSLEngine");
473 }
474
475 synchronized (this) {
476 if (!isDestroyed()) {
477 SSL.setOcspResponse(ssl, response);
478 }
479 }
480 }
481
482
483
484
485 @UnstableApi
486 public byte[] getOcspResponse() {
487 if (!enableOcsp) {
488 throw new IllegalStateException("OCSP stapling is not enabled");
489 }
490
491 if (!clientMode) {
492 throw new IllegalStateException("Not a client SSLEngine");
493 }
494
495 synchronized (this) {
496 if (isDestroyed()) {
497 return EmptyArrays.EMPTY_BYTES;
498 }
499 return SSL.getOcspResponse(ssl);
500 }
501 }
502
503 @Override
504 public final int refCnt() {
505 return refCnt.refCnt();
506 }
507
508 @Override
509 public final ReferenceCounted retain() {
510 refCnt.retain();
511 return this;
512 }
513
514 @Override
515 public final ReferenceCounted retain(int increment) {
516 refCnt.retain(increment);
517 return this;
518 }
519
520 @Override
521 public final ReferenceCounted touch() {
522 refCnt.touch();
523 return this;
524 }
525
526 @Override
527 public final ReferenceCounted touch(Object hint) {
528 refCnt.touch(hint);
529 return this;
530 }
531
532 @Override
533 public final boolean release() {
534 return refCnt.release();
535 }
536
537 @Override
538 public final boolean release(int decrement) {
539 return refCnt.release(decrement);
540 }
541
542
543
544 public String getApplicationProtocol() {
545 return applicationProtocol;
546 }
547
548
549
550 public String getHandshakeApplicationProtocol() {
551 return applicationProtocol;
552 }
553
554 @Override
555 public final synchronized SSLSession getHandshakeSession() {
556
557
558
559
560 switch(handshakeState) {
561 case NOT_STARTED:
562 case FINISHED:
563 return null;
564 default:
565 return session;
566 }
567 }
568
569
570
571
572
573
574 public final synchronized long sslPointer() {
575 return ssl;
576 }
577
578
579
580
581 public final synchronized void shutdown() {
582 if (!destroyed) {
583 destroyed = true;
584
585
586
587 if (engineMap != null) {
588 engineMap.remove(ssl);
589 }
590 SSL.freeSSL(ssl);
591 ssl = networkBIO = 0;
592
593 isInboundDone = outboundClosed = true;
594 }
595
596
597 SSL.clearError();
598 }
599
600
601
602
603
604
605 private int writePlaintextData(final ByteBuffer src, int len) {
606 final int pos = src.position();
607 final int limit = src.limit();
608 final int sslWrote;
609
610 if (src.isDirect()) {
611 sslWrote = SSL.writeToSSL(ssl, bufferAddress(src) + pos, len);
612 if (sslWrote > 0) {
613 src.position(pos + sslWrote);
614 }
615 } else {
616 ByteBuf buf = alloc.directBuffer(len);
617 try {
618 src.limit(pos + len);
619
620 buf.setBytes(0, src);
621 src.limit(limit);
622
623 sslWrote = SSL.writeToSSL(ssl, memoryAddress(buf), len);
624 if (sslWrote > 0) {
625 src.position(pos + sslWrote);
626 } else {
627 src.position(pos);
628 }
629 } finally {
630 buf.release();
631 }
632 }
633 return sslWrote;
634 }
635
636 synchronized void bioSetFd(int fd) {
637 if (!isDestroyed()) {
638 SSL.bioSetFd(this.ssl, fd);
639 }
640 }
641
642
643
644
645 private ByteBuf writeEncryptedData(final ByteBuffer src, int len) throws SSLException {
646 final int pos = src.position();
647 if (src.isDirect()) {
648 SSL.bioSetByteBuffer(networkBIO, bufferAddress(src) + pos, len, false);
649 } else {
650 final ByteBuf buf = alloc.directBuffer(len);
651 try {
652 final int limit = src.limit();
653 src.limit(pos + len);
654 buf.writeBytes(src);
655
656 src.position(pos);
657 src.limit(limit);
658
659 SSL.bioSetByteBuffer(networkBIO, memoryAddress(buf), len, false);
660 return buf;
661 } catch (Throwable cause) {
662 buf.release();
663 PlatformDependent.throwException(cause);
664 }
665 }
666 return null;
667 }
668
669
670
671
672 private int readPlaintextData(final ByteBuffer dst) throws SSLException {
673 final int sslRead;
674 final int pos = dst.position();
675 if (dst.isDirect()) {
676 sslRead = SSL.readFromSSL(ssl, bufferAddress(dst) + pos, dst.limit() - pos);
677 if (sslRead > 0) {
678 dst.position(pos + sslRead);
679 }
680 } else {
681 final int limit = dst.limit();
682 final int len = min(maxEncryptedPacketLength0(), limit - pos);
683 final ByteBuf buf = alloc.directBuffer(len);
684 try {
685 sslRead = SSL.readFromSSL(ssl, memoryAddress(buf), len);
686 if (sslRead > 0) {
687 dst.limit(pos + sslRead);
688 buf.getBytes(buf.readerIndex(), dst);
689 dst.limit(limit);
690 }
691 } finally {
692 buf.release();
693 }
694 }
695
696 return sslRead;
697 }
698
699
700
701
702 final synchronized int maxWrapOverhead() {
703 return maxWrapOverhead;
704 }
705
706
707
708
709 final synchronized int maxEncryptedPacketLength() {
710 return maxEncryptedPacketLength0();
711 }
712
713
714
715
716
717 final int maxEncryptedPacketLength0() {
718 return maxWrapOverhead + MAX_PLAINTEXT_LENGTH;
719 }
720
721
722
723
724
725
726
727
728
729 final int calculateMaxLengthForWrap(int plaintextLength, int numComponents) {
730 return (int) min(maxWrapBufferSize, plaintextLength + (long) maxWrapOverhead * numComponents);
731 }
732
733
734
735
736
737
738
739
740 final int calculateOutNetBufSize(int plaintextLength, int numComponents) {
741 return (int) min(MAX_VALUE, plaintextLength + (long) maxWrapOverhead * numComponents);
742 }
743
744 final synchronized int sslPending() {
745 return sslPending0();
746 }
747
748
749
750
751 private void calculateMaxWrapOverhead() {
752 maxWrapOverhead = SSL.getMaxWrapOverhead(ssl);
753
754
755
756
757 maxWrapBufferSize = jdkCompatibilityMode ? maxEncryptedPacketLength0() : maxEncryptedPacketLength0() << 4;
758 }
759
760 private int sslPending0() {
761
762
763
764
765 return handshakeState != HandshakeState.FINISHED ? 0 : SSL.sslPending(ssl);
766 }
767
768 private boolean isBytesAvailableEnoughForWrap(int bytesAvailable, int plaintextLength, int numComponents) {
769 return bytesAvailable - (long) maxWrapOverhead * numComponents >= plaintextLength;
770 }
771
772 @Override
773 public final SSLEngineResult wrap(
774 final ByteBuffer[] srcs, int offset, final int length, final ByteBuffer dst) throws SSLException {
775
776 checkNotNullWithIAE(srcs, "srcs");
777 checkNotNullWithIAE(dst, "dst");
778
779 if (offset >= srcs.length || offset + length > srcs.length) {
780 throw new IndexOutOfBoundsException(
781 "offset: " + offset + ", length: " + length +
782 " (expected: offset <= offset + length <= srcs.length (" + srcs.length + "))");
783 }
784
785 if (dst.isReadOnly()) {
786 throw new ReadOnlyBufferException();
787 }
788
789 synchronized (this) {
790 if (isOutboundDone()) {
791
792 return isInboundDone() || isDestroyed() ? CLOSED_NOT_HANDSHAKING : NEED_UNWRAP_CLOSED;
793 }
794
795 int bytesProduced = 0;
796 ByteBuf bioReadCopyBuf = null;
797 try {
798
799 if (dst.isDirect()) {
800 SSL.bioSetByteBuffer(networkBIO, bufferAddress(dst) + dst.position(), dst.remaining(),
801 true);
802 } else {
803 bioReadCopyBuf = alloc.directBuffer(dst.remaining());
804 SSL.bioSetByteBuffer(networkBIO, memoryAddress(bioReadCopyBuf), bioReadCopyBuf.writableBytes(),
805 true);
806 }
807
808 int bioLengthBefore = SSL.bioLengthByteBuffer(networkBIO);
809
810
811 if (outboundClosed) {
812
813
814
815
816
817 if (!isBytesAvailableEnoughForWrap(dst.remaining(), 2, 1)) {
818 return new SSLEngineResult(BUFFER_OVERFLOW, getHandshakeStatus(), 0, 0);
819 }
820
821
822
823 bytesProduced = SSL.bioFlushByteBuffer(networkBIO);
824 if (bytesProduced <= 0) {
825 return newResultMayFinishHandshake(NOT_HANDSHAKING, 0, 0);
826 }
827
828
829
830 if (!doSSLShutdown()) {
831 return newResultMayFinishHandshake(NOT_HANDSHAKING, 0, bytesProduced);
832 }
833 bytesProduced = bioLengthBefore - SSL.bioLengthByteBuffer(networkBIO);
834 return newResultMayFinishHandshake(NEED_WRAP, 0, bytesProduced);
835 }
836
837
838 SSLEngineResult.HandshakeStatus status = NOT_HANDSHAKING;
839 HandshakeState oldHandshakeState = handshakeState;
840
841
842 if (handshakeState != HandshakeState.FINISHED) {
843 if (handshakeState != HandshakeState.STARTED_EXPLICITLY) {
844
845 handshakeState = HandshakeState.STARTED_IMPLICITLY;
846 }
847
848
849 bytesProduced = SSL.bioFlushByteBuffer(networkBIO);
850
851 if (pendingException != null) {
852
853
854
855
856
857
858
859
860
861
862
863 if (bytesProduced > 0) {
864 return newResult(NEED_WRAP, 0, bytesProduced);
865 }
866
867
868
869 return newResult(handshakeException(), 0, 0);
870 }
871
872 status = handshake();
873
874
875
876 bytesProduced = bioLengthBefore - SSL.bioLengthByteBuffer(networkBIO);
877
878 if (status == NEED_TASK) {
879 return newResult(status, 0, bytesProduced);
880 }
881
882 if (bytesProduced > 0) {
883
884
885
886 return newResult(mayFinishHandshake(status != FINISHED ?
887 bytesProduced == bioLengthBefore ? NEED_WRAP :
888 getHandshakeStatus(SSL.bioLengthNonApplication(networkBIO)) : FINISHED),
889 0, bytesProduced);
890 }
891
892 if (status == NEED_UNWRAP) {
893
894 return isOutboundDone() ? NEED_UNWRAP_CLOSED : NEED_UNWRAP_OK;
895 }
896
897
898
899 if (outboundClosed) {
900 bytesProduced = SSL.bioFlushByteBuffer(networkBIO);
901 return newResultMayFinishHandshake(status, 0, bytesProduced);
902 }
903 }
904
905 final int endOffset = offset + length;
906 if (jdkCompatibilityMode ||
907
908
909
910 oldHandshakeState != HandshakeState.FINISHED) {
911 int srcsLen = 0;
912 for (int i = offset; i < endOffset; ++i) {
913 final ByteBuffer src = srcs[i];
914 if (src == null) {
915 throw new IllegalArgumentException("srcs[" + i + "] is null");
916 }
917 if (srcsLen == MAX_PLAINTEXT_LENGTH) {
918 continue;
919 }
920
921 srcsLen += src.remaining();
922 if (srcsLen > MAX_PLAINTEXT_LENGTH || srcsLen < 0) {
923
924
925
926 srcsLen = MAX_PLAINTEXT_LENGTH;
927 }
928 }
929
930
931
932 if (!isBytesAvailableEnoughForWrap(dst.remaining(), srcsLen, 1)) {
933 return new SSLEngineResult(BUFFER_OVERFLOW, getHandshakeStatus(), 0, 0);
934 }
935 }
936
937
938 int bytesConsumed = 0;
939 assert bytesProduced == 0;
940
941
942 bytesProduced = SSL.bioFlushByteBuffer(networkBIO);
943
944 if (bytesProduced > 0) {
945 return newResultMayFinishHandshake(status, bytesConsumed, bytesProduced);
946 }
947
948
949 if (pendingException != null) {
950 Throwable error = pendingException;
951 pendingException = null;
952 shutdown();
953
954
955 throw new SSLException(error);
956 }
957
958 for (; offset < endOffset; ++offset) {
959 final ByteBuffer src = srcs[offset];
960 final int remaining = src.remaining();
961 if (remaining == 0) {
962 continue;
963 }
964
965 final int bytesWritten;
966 if (jdkCompatibilityMode) {
967
968
969
970 bytesWritten = writePlaintextData(src, min(remaining, MAX_PLAINTEXT_LENGTH - bytesConsumed));
971 } else {
972
973
974
975 final int availableCapacityForWrap = dst.remaining() - bytesProduced - maxWrapOverhead;
976 if (availableCapacityForWrap <= 0) {
977 return new SSLEngineResult(BUFFER_OVERFLOW, getHandshakeStatus(), bytesConsumed,
978 bytesProduced);
979 }
980 bytesWritten = writePlaintextData(src, min(remaining, availableCapacityForWrap));
981 }
982
983
984
985
986
987
988 final int pendingNow = SSL.bioLengthByteBuffer(networkBIO);
989 bytesProduced += bioLengthBefore - pendingNow;
990 bioLengthBefore = pendingNow;
991
992 if (bytesWritten > 0) {
993 bytesConsumed += bytesWritten;
994
995 if (jdkCompatibilityMode || bytesProduced == dst.remaining()) {
996 return newResultMayFinishHandshake(status, bytesConsumed, bytesProduced);
997 }
998 } else {
999 int sslError = SSL.getError(ssl, bytesWritten);
1000 if (sslError == SSL.SSL_ERROR_ZERO_RETURN) {
1001
1002 if (!receivedShutdown) {
1003 closeAll();
1004
1005 bytesProduced += bioLengthBefore - SSL.bioLengthByteBuffer(networkBIO);
1006
1007
1008
1009
1010 SSLEngineResult.HandshakeStatus hs = mayFinishHandshake(
1011 status != FINISHED ? bytesProduced == dst.remaining() ? NEED_WRAP
1012 : getHandshakeStatus(SSL.bioLengthNonApplication(networkBIO))
1013 : FINISHED);
1014 return newResult(hs, bytesConsumed, bytesProduced);
1015 }
1016
1017 return newResult(NOT_HANDSHAKING, bytesConsumed, bytesProduced);
1018 } else if (sslError == SSL.SSL_ERROR_WANT_READ) {
1019
1020
1021
1022 return newResult(NEED_UNWRAP, bytesConsumed, bytesProduced);
1023 } else if (sslError == SSL.SSL_ERROR_WANT_WRITE) {
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036 if (bytesProduced > 0) {
1037
1038
1039 return newResult(NEED_WRAP, bytesConsumed, bytesProduced);
1040 }
1041 return newResult(BUFFER_OVERFLOW, status, bytesConsumed, bytesProduced);
1042 } else if (sslError == SSL.SSL_ERROR_WANT_X509_LOOKUP ||
1043 sslError == SSL.SSL_ERROR_WANT_CERTIFICATE_VERIFY ||
1044 sslError == SSL.SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) {
1045
1046 return newResult(NEED_TASK, bytesConsumed, bytesProduced);
1047 } else {
1048
1049 throw shutdownWithError("SSL_write", sslError, SSL.getLastErrorNumber());
1050 }
1051 }
1052 }
1053 return newResultMayFinishHandshake(status, bytesConsumed, bytesProduced);
1054 } finally {
1055 SSL.bioClearByteBuffer(networkBIO);
1056 if (bioReadCopyBuf == null) {
1057 dst.position(dst.position() + bytesProduced);
1058 } else {
1059 assert bioReadCopyBuf.readableBytes() <= dst.remaining() : "The destination buffer " + dst +
1060 " didn't have enough remaining space to hold the encrypted content in " + bioReadCopyBuf;
1061 dst.put(bioReadCopyBuf.internalNioBuffer(bioReadCopyBuf.readerIndex(), bytesProduced));
1062 bioReadCopyBuf.release();
1063 }
1064 }
1065 }
1066 }
1067
1068 private SSLEngineResult newResult(SSLEngineResult.HandshakeStatus hs, int bytesConsumed, int bytesProduced) {
1069 return newResult(OK, hs, bytesConsumed, bytesProduced);
1070 }
1071
1072 private SSLEngineResult newResult(SSLEngineResult.Status status, SSLEngineResult.HandshakeStatus hs,
1073 int bytesConsumed, int bytesProduced) {
1074
1075
1076
1077 if (isOutboundDone()) {
1078 if (isInboundDone()) {
1079
1080 hs = NOT_HANDSHAKING;
1081
1082
1083 shutdown();
1084 }
1085 return new SSLEngineResult(CLOSED, hs, bytesConsumed, bytesProduced);
1086 }
1087 if (hs == NEED_TASK) {
1088
1089 needTask = true;
1090 }
1091 return new SSLEngineResult(status, hs, bytesConsumed, bytesProduced);
1092 }
1093
1094 private SSLEngineResult newResultMayFinishHandshake(SSLEngineResult.HandshakeStatus hs,
1095 int bytesConsumed, int bytesProduced) throws SSLException {
1096 return newResult(mayFinishHandshake(hs, bytesConsumed, bytesProduced), bytesConsumed, bytesProduced);
1097 }
1098
1099 private SSLEngineResult newResultMayFinishHandshake(SSLEngineResult.Status status,
1100 SSLEngineResult.HandshakeStatus hs,
1101 int bytesConsumed, int bytesProduced) throws SSLException {
1102 return newResult(status, mayFinishHandshake(hs, bytesConsumed, bytesProduced), bytesConsumed, bytesProduced);
1103 }
1104
1105
1106
1107
1108 private SSLException shutdownWithError(String operation, int sslError, int error) {
1109 if (logger.isDebugEnabled()) {
1110 String errorString = SSL.getErrorString(error);
1111 logger.debug("{} failed with {}: OpenSSL error: {} {}",
1112 operation, sslError, error, errorString);
1113 }
1114
1115
1116 shutdown();
1117
1118 SSLException exception = newSSLExceptionForError(error);
1119
1120 if (pendingException != null) {
1121 exception.initCause(pendingException);
1122 pendingException = null;
1123 }
1124 return exception;
1125 }
1126
1127 private SSLEngineResult handleUnwrapException(int bytesConsumed, int bytesProduced, SSLException e)
1128 throws SSLException {
1129 int lastError = SSL.getLastErrorNumber();
1130 if (lastError != 0) {
1131 return sslReadErrorResult(SSL.SSL_ERROR_SSL, lastError, bytesConsumed,
1132 bytesProduced);
1133 }
1134 throw e;
1135 }
1136
1137 public final SSLEngineResult unwrap(
1138 final ByteBuffer[] srcs, int srcsOffset, final int srcsLength,
1139 final ByteBuffer[] dsts, int dstsOffset, final int dstsLength) throws SSLException {
1140
1141
1142 checkNotNullWithIAE(srcs, "srcs");
1143 if (srcsOffset >= srcs.length
1144 || srcsOffset + srcsLength > srcs.length) {
1145 throw new IndexOutOfBoundsException(
1146 "offset: " + srcsOffset + ", length: " + srcsLength +
1147 " (expected: offset <= offset + length <= srcs.length (" + srcs.length + "))");
1148 }
1149 checkNotNullWithIAE(dsts, "dsts");
1150 if (dstsOffset >= dsts.length || dstsOffset + dstsLength > dsts.length) {
1151 throw new IndexOutOfBoundsException(
1152 "offset: " + dstsOffset + ", length: " + dstsLength +
1153 " (expected: offset <= offset + length <= dsts.length (" + dsts.length + "))");
1154 }
1155 long capacity = 0;
1156 final int dstsEndOffset = dstsOffset + dstsLength;
1157 for (int i = dstsOffset; i < dstsEndOffset; i ++) {
1158 ByteBuffer dst = checkNotNullArrayParam(dsts[i], i, "dsts");
1159 if (dst.isReadOnly()) {
1160 throw new ReadOnlyBufferException();
1161 }
1162 capacity += dst.remaining();
1163 }
1164
1165 final int srcsEndOffset = srcsOffset + srcsLength;
1166 long len = 0;
1167 for (int i = srcsOffset; i < srcsEndOffset; i++) {
1168 ByteBuffer src = checkNotNullArrayParam(srcs[i], i, "srcs");
1169 len += src.remaining();
1170 }
1171
1172 synchronized (this) {
1173 if (isInboundDone()) {
1174 return isOutboundDone() || isDestroyed() ? CLOSED_NOT_HANDSHAKING : NEED_WRAP_CLOSED;
1175 }
1176
1177 SSLEngineResult.HandshakeStatus status = NOT_HANDSHAKING;
1178 HandshakeState oldHandshakeState = handshakeState;
1179
1180 if (handshakeState != HandshakeState.FINISHED) {
1181 if (handshakeState != HandshakeState.STARTED_EXPLICITLY) {
1182
1183 handshakeState = HandshakeState.STARTED_IMPLICITLY;
1184 }
1185
1186 status = handshake();
1187
1188 if (status == NEED_TASK) {
1189 return newResult(status, 0, 0);
1190 }
1191
1192 if (status == NEED_WRAP) {
1193 return NEED_WRAP_OK;
1194 }
1195
1196 if (isInboundDone) {
1197 return NEED_WRAP_CLOSED;
1198 }
1199 }
1200
1201 int sslPending = sslPending0();
1202 int packetLength;
1203
1204
1205
1206
1207 if (jdkCompatibilityMode ||
1208
1209
1210
1211 oldHandshakeState != HandshakeState.FINISHED) {
1212 if (len < SSL_RECORD_HEADER_LENGTH) {
1213 return newResultMayFinishHandshake(BUFFER_UNDERFLOW, status, 0, 0);
1214 }
1215
1216 packetLength = SslUtils.getEncryptedPacketLength(srcs, srcsOffset);
1217 if (packetLength == SslUtils.NOT_ENCRYPTED) {
1218 throw new NotSslRecordException("not an SSL/TLS record");
1219 }
1220
1221 assert packetLength >= 0;
1222
1223 final int packetLengthDataOnly = packetLength - SSL_RECORD_HEADER_LENGTH;
1224 if (packetLengthDataOnly > capacity) {
1225
1226
1227 if (packetLengthDataOnly > MAX_RECORD_SIZE) {
1228
1229
1230
1231
1232
1233 throw new SSLException("Illegal packet length: " + packetLengthDataOnly + " > " +
1234 session.getApplicationBufferSize());
1235 } else {
1236 session.tryExpandApplicationBufferSize(packetLengthDataOnly);
1237 }
1238 return newResultMayFinishHandshake(BUFFER_OVERFLOW, status, 0, 0);
1239 }
1240
1241 if (len < packetLength) {
1242
1243
1244 return newResultMayFinishHandshake(BUFFER_UNDERFLOW, status, 0, 0);
1245 }
1246 } else if (len == 0 && sslPending <= 0) {
1247 return newResultMayFinishHandshake(BUFFER_UNDERFLOW, status, 0, 0);
1248 } else if (capacity == 0) {
1249 return newResultMayFinishHandshake(BUFFER_OVERFLOW, status, 0, 0);
1250 } else {
1251 packetLength = (int) min(MAX_VALUE, len);
1252 }
1253
1254
1255 assert srcsOffset < srcsEndOffset;
1256
1257
1258 assert capacity > 0;
1259
1260
1261 int bytesProduced = 0;
1262 int bytesConsumed = 0;
1263 try {
1264 srcLoop:
1265 for (;;) {
1266 ByteBuffer src = srcs[srcsOffset];
1267 int remaining = src.remaining();
1268 final ByteBuf bioWriteCopyBuf;
1269 int pendingEncryptedBytes;
1270 if (remaining == 0) {
1271 if (sslPending <= 0) {
1272
1273
1274 if (++srcsOffset >= srcsEndOffset) {
1275 break;
1276 }
1277 continue;
1278 } else {
1279 bioWriteCopyBuf = null;
1280 pendingEncryptedBytes = SSL.bioLengthByteBuffer(networkBIO);
1281 }
1282 } else {
1283
1284
1285 pendingEncryptedBytes = min(packetLength, remaining);
1286 try {
1287 bioWriteCopyBuf = writeEncryptedData(src, pendingEncryptedBytes);
1288 } catch (SSLException e) {
1289
1290 return handleUnwrapException(bytesConsumed, bytesProduced, e);
1291 }
1292 }
1293 try {
1294 for (;;) {
1295 ByteBuffer dst = dsts[dstsOffset];
1296 if (!dst.hasRemaining()) {
1297
1298 if (++dstsOffset >= dstsEndOffset) {
1299 break srcLoop;
1300 }
1301 continue;
1302 }
1303
1304 int bytesRead;
1305 try {
1306 bytesRead = readPlaintextData(dst);
1307 } catch (SSLException e) {
1308
1309 return handleUnwrapException(bytesConsumed, bytesProduced, e);
1310 }
1311
1312
1313
1314 int localBytesConsumed = pendingEncryptedBytes - SSL.bioLengthByteBuffer(networkBIO);
1315 bytesConsumed += localBytesConsumed;
1316 packetLength -= localBytesConsumed;
1317 pendingEncryptedBytes -= localBytesConsumed;
1318 src.position(src.position() + localBytesConsumed);
1319
1320 if (bytesRead > 0) {
1321 bytesProduced += bytesRead;
1322
1323 if (!dst.hasRemaining()) {
1324 sslPending = sslPending0();
1325
1326 if (++dstsOffset >= dstsEndOffset) {
1327 return sslPending > 0 ?
1328 newResult(BUFFER_OVERFLOW, status, bytesConsumed, bytesProduced) :
1329 newResultMayFinishHandshake(isInboundDone() ? CLOSED : OK, status,
1330 bytesConsumed, bytesProduced);
1331 }
1332 } else if (packetLength == 0 || jdkCompatibilityMode) {
1333
1334
1335 break srcLoop;
1336 }
1337 } else {
1338 int sslError = SSL.getError(ssl, bytesRead);
1339 if (sslError == SSL.SSL_ERROR_WANT_READ || sslError == SSL.SSL_ERROR_WANT_WRITE) {
1340
1341
1342 break;
1343 } else if (sslError == SSL.SSL_ERROR_ZERO_RETURN) {
1344
1345 if (!receivedShutdown) {
1346 closeAll();
1347 }
1348 return newResultMayFinishHandshake(isInboundDone() ? CLOSED : OK, status,
1349 bytesConsumed, bytesProduced);
1350 } else if (sslError == SSL.SSL_ERROR_WANT_X509_LOOKUP ||
1351 sslError == SSL.SSL_ERROR_WANT_CERTIFICATE_VERIFY ||
1352 sslError == SSL.SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) {
1353 return newResult(isInboundDone() ? CLOSED : OK,
1354 NEED_TASK, bytesConsumed, bytesProduced);
1355 } else {
1356 return sslReadErrorResult(sslError, SSL.getLastErrorNumber(), bytesConsumed,
1357 bytesProduced);
1358 }
1359 }
1360 }
1361
1362 if (++srcsOffset >= srcsEndOffset) {
1363 break;
1364 }
1365 } finally {
1366 if (bioWriteCopyBuf != null) {
1367 bioWriteCopyBuf.release();
1368 }
1369 }
1370 }
1371 } finally {
1372 SSL.bioClearByteBuffer(networkBIO);
1373 rejectRemoteInitiatedRenegotiation();
1374 }
1375
1376
1377 if (!receivedShutdown && (SSL.getShutdown(ssl) & SSL.SSL_RECEIVED_SHUTDOWN) == SSL.SSL_RECEIVED_SHUTDOWN) {
1378 closeAll();
1379 }
1380
1381 return newResultMayFinishHandshake(isInboundDone() ? CLOSED : OK, status, bytesConsumed, bytesProduced);
1382 }
1383 }
1384
1385 private boolean needWrapAgain(int stackError) {
1386
1387
1388
1389
1390 if (SSL.bioLengthNonApplication(networkBIO) > 0) {
1391
1392
1393 if (pendingException == null) {
1394 pendingException = newSSLExceptionForError(stackError);
1395 } else if (shouldAddSuppressed(pendingException, stackError)) {
1396 ThrowableUtil.addSuppressed(pendingException, newSSLExceptionForError(stackError));
1397 }
1398
1399
1400 SSL.clearError();
1401 return true;
1402 }
1403 return false;
1404 }
1405
1406 private SSLException newSSLExceptionForError(int stackError) {
1407 String message = SSL.getErrorString(stackError);
1408 return handshakeState == HandshakeState.FINISHED ?
1409 new OpenSslException(message, stackError) : new OpenSslHandshakeException(message, stackError);
1410 }
1411
1412 private static boolean shouldAddSuppressed(Throwable target, int errorCode) {
1413 for (Throwable suppressed: ThrowableUtil.getSuppressed(target)) {
1414 if (suppressed instanceof NativeSslException &&
1415 ((NativeSslException) suppressed).errorCode() == errorCode) {
1416
1417 return false;
1418 }
1419 }
1420 return true;
1421 }
1422
1423 private SSLEngineResult sslReadErrorResult(int error, int stackError, int bytesConsumed, int bytesProduced)
1424 throws SSLException {
1425 if (needWrapAgain(stackError)) {
1426
1427
1428 return new SSLEngineResult(OK, NEED_WRAP, bytesConsumed, bytesProduced);
1429 }
1430 throw shutdownWithError("SSL_read", error, stackError);
1431 }
1432
1433 private void closeAll() throws SSLException {
1434 receivedShutdown = true;
1435 closeOutbound();
1436 closeInbound();
1437 }
1438
1439 private void rejectRemoteInitiatedRenegotiation() throws SSLHandshakeException {
1440
1441
1442
1443 if (!isDestroyed() && (!clientMode && SSL.getHandshakeCount(ssl) > 1 ||
1444
1445 clientMode && SSL.getHandshakeCount(ssl) > 2) &&
1446
1447
1448 !SslProtocols.TLS_v1_3.equals(session.getProtocol()) && handshakeState == HandshakeState.FINISHED) {
1449
1450
1451 shutdown();
1452 throw new SSLHandshakeException("remote-initiated renegotiation not allowed");
1453 }
1454 }
1455
1456 public final SSLEngineResult unwrap(final ByteBuffer[] srcs, final ByteBuffer[] dsts) throws SSLException {
1457 return unwrap(srcs, 0, srcs.length, dsts, 0, dsts.length);
1458 }
1459
1460 private ByteBuffer[] singleSrcBuffer(ByteBuffer src) {
1461 singleSrcBuffer[0] = src;
1462 return singleSrcBuffer;
1463 }
1464
1465 private void resetSingleSrcBuffer() {
1466 singleSrcBuffer[0] = null;
1467 }
1468
1469 private ByteBuffer[] singleDstBuffer(ByteBuffer src) {
1470 singleDstBuffer[0] = src;
1471 return singleDstBuffer;
1472 }
1473
1474 private void resetSingleDstBuffer() {
1475 singleDstBuffer[0] = null;
1476 }
1477
1478 @Override
1479 public final synchronized SSLEngineResult unwrap(
1480 final ByteBuffer src, final ByteBuffer[] dsts, final int offset, final int length) throws SSLException {
1481 try {
1482 return unwrap(singleSrcBuffer(src), 0, 1, dsts, offset, length);
1483 } finally {
1484 resetSingleSrcBuffer();
1485 }
1486 }
1487
1488 @Override
1489 public final synchronized SSLEngineResult wrap(ByteBuffer src, ByteBuffer dst) throws SSLException {
1490 try {
1491 return wrap(singleSrcBuffer(src), dst);
1492 } finally {
1493 resetSingleSrcBuffer();
1494 }
1495 }
1496
1497 @Override
1498 public final synchronized SSLEngineResult unwrap(ByteBuffer src, ByteBuffer dst) throws SSLException {
1499 try {
1500 return unwrap(singleSrcBuffer(src), singleDstBuffer(dst));
1501 } finally {
1502 resetSingleSrcBuffer();
1503 resetSingleDstBuffer();
1504 }
1505 }
1506
1507 @Override
1508 public final synchronized SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts) throws SSLException {
1509 try {
1510 return unwrap(singleSrcBuffer(src), dsts);
1511 } finally {
1512 resetSingleSrcBuffer();
1513 }
1514 }
1515
1516 private class TaskDecorator<R extends Runnable> implements Runnable {
1517 protected final R task;
1518 TaskDecorator(R task) {
1519 this.task = task;
1520 }
1521
1522 @Override
1523 public void run() {
1524 runAndResetNeedTask(task);
1525 }
1526 }
1527
1528 private final class AsyncTaskDecorator extends TaskDecorator<AsyncTask> implements AsyncRunnable {
1529 AsyncTaskDecorator(AsyncTask task) {
1530 super(task);
1531 }
1532
1533 @Override
1534 public void run(final Runnable runnable) {
1535 if (isDestroyed()) {
1536
1537 return;
1538 }
1539 task.runAsync(new TaskDecorator<Runnable>(runnable));
1540 }
1541 }
1542
1543 private void runAndResetNeedTask(Runnable task) {
1544
1545
1546 synchronized (ReferenceCountedOpenSslEngine.this) {
1547 try {
1548 if (isDestroyed()) {
1549
1550 return;
1551 }
1552 task.run();
1553 if (handshakeState != HandshakeState.FINISHED && !isDestroyed()) {
1554
1555
1556
1557 if (SSL.doHandshake(ssl) <= 0) {
1558 SSL.clearError();
1559 }
1560 }
1561 } finally {
1562
1563 needTask = false;
1564 }
1565 }
1566 }
1567
1568 @Override
1569 public final synchronized Runnable getDelegatedTask() {
1570 if (isDestroyed()) {
1571 return null;
1572 }
1573 final Runnable task = SSL.getTask(ssl);
1574 if (task == null) {
1575 return null;
1576 }
1577 if (task instanceof AsyncTask) {
1578 return new AsyncTaskDecorator((AsyncTask) task);
1579 }
1580 return new TaskDecorator<Runnable>(task);
1581 }
1582
1583 @Override
1584 public final synchronized void closeInbound() throws SSLException {
1585 if (isInboundDone) {
1586 return;
1587 }
1588
1589 isInboundDone = true;
1590
1591 if (isOutboundDone()) {
1592
1593
1594 shutdown();
1595 }
1596
1597 if (handshakeState != HandshakeState.NOT_STARTED && !receivedShutdown) {
1598 throw new SSLException(
1599 "Inbound closed before receiving peer's close_notify: possible truncation attack?");
1600 }
1601 }
1602
1603 @Override
1604 public final synchronized boolean isInboundDone() {
1605 return isInboundDone;
1606 }
1607
1608 @Override
1609 public final synchronized void closeOutbound() {
1610 if (outboundClosed) {
1611 return;
1612 }
1613
1614 outboundClosed = true;
1615
1616 if (handshakeState != HandshakeState.NOT_STARTED && !isDestroyed()) {
1617 int mode = SSL.getShutdown(ssl);
1618 if ((mode & SSL.SSL_SENT_SHUTDOWN) != SSL.SSL_SENT_SHUTDOWN) {
1619 doSSLShutdown();
1620 }
1621 } else {
1622
1623 shutdown();
1624 }
1625 }
1626
1627
1628
1629
1630
1631 private boolean doSSLShutdown() {
1632 if (SSL.isInInit(ssl) != 0) {
1633
1634
1635
1636
1637 return false;
1638 }
1639 int err = SSL.shutdownSSL(ssl);
1640 if (err < 0) {
1641 int sslErr = SSL.getError(ssl, err);
1642 if (sslErr == SSL.SSL_ERROR_SYSCALL || sslErr == SSL.SSL_ERROR_SSL) {
1643 if (logger.isDebugEnabled()) {
1644 int error = SSL.getLastErrorNumber();
1645 logger.debug("SSL_shutdown failed: OpenSSL error: {} {}", error, SSL.getErrorString(error));
1646 }
1647
1648 shutdown();
1649 return false;
1650 }
1651 SSL.clearError();
1652 }
1653 return true;
1654 }
1655
1656 @Override
1657 public final synchronized boolean isOutboundDone() {
1658
1659
1660 return outboundClosed && (networkBIO == 0 || SSL.bioLengthNonApplication(networkBIO) == 0);
1661 }
1662
1663 @Override
1664 public final String[] getSupportedCipherSuites() {
1665 return OpenSsl.AVAILABLE_CIPHER_SUITES.toArray(EMPTY_STRINGS);
1666 }
1667
1668 @Override
1669 public final String[] getEnabledCipherSuites() {
1670 final String[] extraCiphers;
1671 final String[] enabled;
1672 final boolean tls13Enabled;
1673 synchronized (this) {
1674 if (!isDestroyed()) {
1675 enabled = SSL.getCiphers(ssl);
1676 int opts = SSL.getOptions(ssl);
1677 if (isProtocolEnabled(opts, SSL.SSL_OP_NO_TLSv1_3, SslProtocols.TLS_v1_3)) {
1678 extraCiphers = OpenSsl.EXTRA_SUPPORTED_TLS_1_3_CIPHERS;
1679 tls13Enabled = true;
1680 } else {
1681 extraCiphers = EMPTY_STRINGS;
1682 tls13Enabled = false;
1683 }
1684 } else {
1685 return EMPTY_STRINGS;
1686 }
1687 }
1688 if (enabled == null) {
1689 return EMPTY_STRINGS;
1690 } else {
1691 Set<String> enabledSet = new LinkedHashSet<String>(enabled.length + extraCiphers.length);
1692 synchronized (this) {
1693 for (int i = 0; i < enabled.length; i++) {
1694 String mapped = toJavaCipherSuite(enabled[i]);
1695 final String cipher = mapped == null ? enabled[i] : mapped;
1696 if ((!tls13Enabled || !OpenSsl.isTlsv13Supported()) && SslUtils.isTLSv13Cipher(cipher)) {
1697 continue;
1698 }
1699 enabledSet.add(cipher);
1700 }
1701 Collections.addAll(enabledSet, extraCiphers);
1702 }
1703 return enabledSet.toArray(EMPTY_STRINGS);
1704 }
1705 }
1706
1707 @Override
1708 public final void setEnabledCipherSuites(String[] cipherSuites) {
1709 checkNotNull(cipherSuites, "cipherSuites");
1710
1711 final StringBuilder buf = new StringBuilder();
1712 final StringBuilder bufTLSv13 = new StringBuilder();
1713
1714 CipherSuiteConverter.convertToCipherStrings(Arrays.asList(cipherSuites), buf, bufTLSv13, OpenSsl.isBoringSSL());
1715 final String cipherSuiteSpec = buf.toString();
1716 final String cipherSuiteSpecTLSv13 = bufTLSv13.toString();
1717
1718 if (!OpenSsl.isTlsv13Supported() && !cipherSuiteSpecTLSv13.isEmpty()) {
1719 throw new IllegalArgumentException("TLSv1.3 is not supported by this java version.");
1720 }
1721 synchronized (this) {
1722 hasTLSv13Cipher = !cipherSuiteSpecTLSv13.isEmpty();
1723 if (!isDestroyed()) {
1724 try {
1725
1726 SSL.setCipherSuites(ssl, cipherSuiteSpec, false);
1727 if (OpenSsl.isTlsv13Supported()) {
1728
1729 SSL.setCipherSuites(ssl, OpenSsl.checkTls13Ciphers(logger, cipherSuiteSpecTLSv13), true);
1730 }
1731
1732
1733
1734 Set<String> protocols = new HashSet<String>(enabledProtocols);
1735
1736
1737
1738 if (cipherSuiteSpec.isEmpty()) {
1739 protocols.remove(SslProtocols.TLS_v1);
1740 protocols.remove(SslProtocols.TLS_v1_1);
1741 protocols.remove(SslProtocols.TLS_v1_2);
1742 protocols.remove(SslProtocols.SSL_v3);
1743 protocols.remove(SslProtocols.SSL_v2);
1744 protocols.remove(SslProtocols.SSL_v2_HELLO);
1745 }
1746
1747 if (cipherSuiteSpecTLSv13.isEmpty()) {
1748 protocols.remove(SslProtocols.TLS_v1_3);
1749 }
1750
1751
1752 setEnabledProtocols0(protocols.toArray(EMPTY_STRINGS), !hasTLSv13Cipher);
1753 } catch (Exception e) {
1754 throw new IllegalStateException("failed to enable cipher suites: " + cipherSuiteSpec, e);
1755 }
1756 } else {
1757 throw new IllegalStateException("failed to enable cipher suites: " + cipherSuiteSpec);
1758 }
1759 }
1760 }
1761
1762 @Override
1763 public final String[] getSupportedProtocols() {
1764 return OpenSsl.SUPPORTED_PROTOCOLS_SET.toArray(EMPTY_STRINGS);
1765 }
1766
1767 @Override
1768 public final String[] getEnabledProtocols() {
1769 return enabledProtocols.toArray(EMPTY_STRINGS);
1770 }
1771
1772 private static boolean isProtocolEnabled(int opts, int disableMask, String protocolString) {
1773
1774
1775 return (opts & disableMask) == 0 && OpenSsl.SUPPORTED_PROTOCOLS_SET.contains(protocolString);
1776 }
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787 @Override
1788 public final void setEnabledProtocols(String[] protocols) {
1789 checkNotNullWithIAE(protocols, "protocols");
1790 synchronized (this) {
1791 enabledProtocols.clear();
1792
1793 enabledProtocols.add(SslProtocols.SSL_v2_HELLO);
1794
1795 Collections.addAll(enabledProtocols, protocols);
1796
1797 setEnabledProtocols0(protocols, !hasTLSv13Cipher);
1798 }
1799 }
1800
1801 private void setEnabledProtocols0(String[] protocols, boolean explicitDisableTLSv13) {
1802 assert Thread.holdsLock(this);
1803
1804 int minProtocolIndex = OPENSSL_OP_NO_PROTOCOLS.length;
1805 int maxProtocolIndex = 0;
1806 for (String p: protocols) {
1807 if (!OpenSsl.SUPPORTED_PROTOCOLS_SET.contains(p)) {
1808 throw new IllegalArgumentException("Protocol " + p + " is not supported.");
1809 }
1810 if (p.equals(SslProtocols.SSL_v2)) {
1811 if (minProtocolIndex > OPENSSL_OP_NO_PROTOCOL_INDEX_SSLV2) {
1812 minProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_SSLV2;
1813 }
1814 if (maxProtocolIndex < OPENSSL_OP_NO_PROTOCOL_INDEX_SSLV2) {
1815 maxProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_SSLV2;
1816 }
1817 } else if (p.equals(SslProtocols.SSL_v3)) {
1818 if (minProtocolIndex > OPENSSL_OP_NO_PROTOCOL_INDEX_SSLV3) {
1819 minProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_SSLV3;
1820 }
1821 if (maxProtocolIndex < OPENSSL_OP_NO_PROTOCOL_INDEX_SSLV3) {
1822 maxProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_SSLV3;
1823 }
1824 } else if (p.equals(SslProtocols.TLS_v1)) {
1825 if (minProtocolIndex > OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1) {
1826 minProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1;
1827 }
1828 if (maxProtocolIndex < OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1) {
1829 maxProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1;
1830 }
1831 } else if (p.equals(SslProtocols.TLS_v1_1)) {
1832 if (minProtocolIndex > OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_1) {
1833 minProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_1;
1834 }
1835 if (maxProtocolIndex < OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_1) {
1836 maxProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_1;
1837 }
1838 } else if (p.equals(SslProtocols.TLS_v1_2)) {
1839 if (minProtocolIndex > OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_2) {
1840 minProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_2;
1841 }
1842 if (maxProtocolIndex < OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_2) {
1843 maxProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_2;
1844 }
1845 } else if (!explicitDisableTLSv13 && p.equals(SslProtocols.TLS_v1_3)) {
1846 if (minProtocolIndex > OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_3) {
1847 minProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_3;
1848 }
1849 if (maxProtocolIndex < OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_3) {
1850 maxProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_3;
1851 }
1852 }
1853 }
1854 if (!isDestroyed()) {
1855
1856 SSL.clearOptions(ssl, SSL.SSL_OP_NO_SSLv2 | SSL.SSL_OP_NO_SSLv3 | SSL.SSL_OP_NO_TLSv1 |
1857 SSL.SSL_OP_NO_TLSv1_1 | SSL.SSL_OP_NO_TLSv1_2 | SSL.SSL_OP_NO_TLSv1_3);
1858
1859 int opts = 0;
1860 for (int i = 0; i < minProtocolIndex; ++i) {
1861 opts |= OPENSSL_OP_NO_PROTOCOLS[i];
1862 }
1863 assert maxProtocolIndex != MAX_VALUE;
1864 for (int i = maxProtocolIndex + 1; i < OPENSSL_OP_NO_PROTOCOLS.length; ++i) {
1865 opts |= OPENSSL_OP_NO_PROTOCOLS[i];
1866 }
1867
1868
1869 SSL.setOptions(ssl, opts);
1870 } else {
1871 throw new IllegalStateException("failed to enable protocols: " + Arrays.asList(protocols));
1872 }
1873 }
1874
1875 @Override
1876 public final SSLSession getSession() {
1877 return session;
1878 }
1879
1880 @Override
1881 public final synchronized void beginHandshake() throws SSLException {
1882 switch (handshakeState) {
1883 case STARTED_IMPLICITLY:
1884 checkEngineClosed();
1885
1886
1887
1888
1889
1890
1891
1892 handshakeState = HandshakeState.STARTED_EXPLICITLY;
1893 calculateMaxWrapOverhead();
1894
1895 break;
1896 case STARTED_EXPLICITLY:
1897
1898 break;
1899 case FINISHED:
1900 throw new SSLException("renegotiation unsupported");
1901 case NOT_STARTED:
1902 handshakeState = HandshakeState.STARTED_EXPLICITLY;
1903 if (handshake() == NEED_TASK) {
1904
1905 needTask = true;
1906 }
1907 calculateMaxWrapOverhead();
1908 break;
1909 default:
1910 throw new Error();
1911 }
1912 }
1913
1914 private void checkEngineClosed() throws SSLException {
1915 if (isDestroyed()) {
1916 throw new SSLException("engine closed");
1917 }
1918 }
1919
1920 private static SSLEngineResult.HandshakeStatus pendingStatus(int pendingStatus) {
1921
1922 return pendingStatus > 0 ? NEED_WRAP : NEED_UNWRAP;
1923 }
1924
1925 private static boolean isEmpty(Object[] arr) {
1926 return arr == null || arr.length == 0;
1927 }
1928
1929 private static boolean isEmpty(byte[] cert) {
1930 return cert == null || cert.length == 0;
1931 }
1932
1933 private SSLEngineResult.HandshakeStatus handshakeException() throws SSLException {
1934 if (SSL.bioLengthNonApplication(networkBIO) > 0) {
1935
1936 return NEED_WRAP;
1937 }
1938
1939 Throwable exception = pendingException;
1940 assert exception != null;
1941 pendingException = null;
1942 shutdown();
1943 if (exception instanceof SSLHandshakeException) {
1944 throw (SSLHandshakeException) exception;
1945 }
1946 SSLHandshakeException e = new SSLHandshakeException("General OpenSslEngine problem");
1947 e.initCause(exception);
1948 throw e;
1949 }
1950
1951
1952
1953
1954
1955 final void initHandshakeException(Throwable cause) {
1956 if (pendingException == null) {
1957 pendingException = cause;
1958 } else {
1959 ThrowableUtil.addSuppressed(pendingException, cause);
1960 }
1961 }
1962
1963 private SSLEngineResult.HandshakeStatus handshake() throws SSLException {
1964 if (needTask) {
1965 return NEED_TASK;
1966 }
1967 if (handshakeState == HandshakeState.FINISHED) {
1968 return FINISHED;
1969 }
1970
1971 checkEngineClosed();
1972
1973 if (pendingException != null) {
1974
1975
1976 if (SSL.doHandshake(ssl) <= 0) {
1977
1978 SSL.clearError();
1979 }
1980 return handshakeException();
1981 }
1982
1983
1984 engineMap.add(this);
1985
1986 if (!sessionSet) {
1987 if (!parentContext.sessionContext().setSessionFromCache(ssl, session, getPeerHost(), getPeerPort())) {
1988
1989
1990 session.prepareHandshake();
1991 }
1992 sessionSet = true;
1993 }
1994
1995 int code = SSL.doHandshake(ssl);
1996 if (code <= 0) {
1997 int sslError = SSL.getError(ssl, code);
1998 if (sslError == SSL.SSL_ERROR_WANT_READ || sslError == SSL.SSL_ERROR_WANT_WRITE) {
1999 return pendingStatus(SSL.bioLengthNonApplication(networkBIO));
2000 }
2001
2002 if (sslError == SSL.SSL_ERROR_WANT_X509_LOOKUP ||
2003 sslError == SSL.SSL_ERROR_WANT_CERTIFICATE_VERIFY ||
2004 sslError == SSL.SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) {
2005 return NEED_TASK;
2006 }
2007
2008 int errorNumber = SSL.getLastErrorNumber();
2009 if (needWrapAgain(errorNumber)) {
2010
2011
2012 return NEED_WRAP;
2013 }
2014
2015
2016 if (pendingException != null) {
2017 return handshakeException();
2018 }
2019
2020
2021 throw shutdownWithError("SSL_do_handshake", sslError, errorNumber);
2022 }
2023
2024 if (SSL.bioLengthNonApplication(networkBIO) > 0) {
2025 return NEED_WRAP;
2026 }
2027
2028 session.handshakeFinished(SSL.getSessionId(ssl), SSL.getCipherForSSL(ssl), SSL.getVersion(ssl),
2029 SSL.getPeerCertificate(ssl), SSL.getPeerCertChain(ssl),
2030 SSL.getTime(ssl) * 1000L, parentContext.sessionTimeout() * 1000L);
2031 selectApplicationProtocol();
2032 return FINISHED;
2033 }
2034
2035 private SSLEngineResult.HandshakeStatus mayFinishHandshake(
2036 SSLEngineResult.HandshakeStatus hs, int bytesConsumed, int bytesProduced) throws SSLException {
2037 return hs == NEED_UNWRAP && bytesProduced > 0 || hs == NEED_WRAP && bytesConsumed > 0 ?
2038 handshake() : mayFinishHandshake(hs != FINISHED ? getHandshakeStatus() : FINISHED);
2039 }
2040
2041 private SSLEngineResult.HandshakeStatus mayFinishHandshake(SSLEngineResult.HandshakeStatus status)
2042 throws SSLException {
2043 if (status == NOT_HANDSHAKING) {
2044 if (handshakeState != HandshakeState.FINISHED) {
2045
2046
2047 return handshake();
2048 }
2049 if (!isDestroyed() && SSL.bioLengthNonApplication(networkBIO) > 0) {
2050
2051 return NEED_WRAP;
2052 }
2053 }
2054 return status;
2055 }
2056
2057 @Override
2058 public final synchronized SSLEngineResult.HandshakeStatus getHandshakeStatus() {
2059
2060 if (needPendingStatus()) {
2061 if (needTask) {
2062
2063 return NEED_TASK;
2064 }
2065 return pendingStatus(SSL.bioLengthNonApplication(networkBIO));
2066 }
2067 return NOT_HANDSHAKING;
2068 }
2069
2070 private SSLEngineResult.HandshakeStatus getHandshakeStatus(int pending) {
2071
2072 if (needPendingStatus()) {
2073 if (needTask) {
2074
2075 return NEED_TASK;
2076 }
2077 return pendingStatus(pending);
2078 }
2079 return NOT_HANDSHAKING;
2080 }
2081
2082 private boolean needPendingStatus() {
2083 return handshakeState != HandshakeState.NOT_STARTED && !isDestroyed()
2084 && (handshakeState != HandshakeState.FINISHED || isInboundDone() || isOutboundDone());
2085 }
2086
2087
2088
2089
2090 private String toJavaCipherSuite(String openSslCipherSuite) {
2091 if (openSslCipherSuite == null) {
2092 return null;
2093 }
2094
2095 String version = SSL.getVersion(ssl);
2096 String prefix = toJavaCipherSuitePrefix(version);
2097 return CipherSuiteConverter.toJava(openSslCipherSuite, prefix);
2098 }
2099
2100
2101
2102
2103 private static String toJavaCipherSuitePrefix(String protocolVersion) {
2104 final char c;
2105 if (protocolVersion == null || protocolVersion.isEmpty()) {
2106 c = 0;
2107 } else {
2108 c = protocolVersion.charAt(0);
2109 }
2110
2111 switch (c) {
2112 case 'T':
2113 return "TLS";
2114 case 'S':
2115 return "SSL";
2116 default:
2117 return "UNKNOWN";
2118 }
2119 }
2120
2121 @Override
2122 public final void setUseClientMode(boolean clientMode) {
2123 if (clientMode != this.clientMode) {
2124 throw new UnsupportedOperationException();
2125 }
2126 }
2127
2128 @Override
2129 public final boolean getUseClientMode() {
2130 return clientMode;
2131 }
2132
2133 @Override
2134 public final void setNeedClientAuth(boolean b) {
2135 setClientAuth(b ? ClientAuth.REQUIRE : ClientAuth.NONE);
2136 }
2137
2138 @Override
2139 public final boolean getNeedClientAuth() {
2140 return clientAuth == ClientAuth.REQUIRE;
2141 }
2142
2143 @Override
2144 public final void setWantClientAuth(boolean b) {
2145 setClientAuth(b ? ClientAuth.OPTIONAL : ClientAuth.NONE);
2146 }
2147
2148 @Override
2149 public final boolean getWantClientAuth() {
2150 return clientAuth == ClientAuth.OPTIONAL;
2151 }
2152
2153
2154
2155
2156
2157 @UnstableApi
2158 public final synchronized void setVerify(int verifyMode, int depth) {
2159 if (!isDestroyed()) {
2160 SSL.setVerify(ssl, verifyMode, depth);
2161 }
2162 }
2163
2164 private void setClientAuth(ClientAuth mode) {
2165 if (clientMode) {
2166 return;
2167 }
2168 synchronized (this) {
2169 if (clientAuth == mode) {
2170
2171 return;
2172 }
2173 if (!isDestroyed()) {
2174 switch (mode) {
2175 case NONE:
2176 SSL.setVerify(ssl, SSL.SSL_CVERIFY_NONE, ReferenceCountedOpenSslContext.VERIFY_DEPTH);
2177 break;
2178 case REQUIRE:
2179 SSL.setVerify(ssl, SSL.SSL_CVERIFY_REQUIRED, ReferenceCountedOpenSslContext.VERIFY_DEPTH);
2180 break;
2181 case OPTIONAL:
2182 SSL.setVerify(ssl, SSL.SSL_CVERIFY_OPTIONAL, ReferenceCountedOpenSslContext.VERIFY_DEPTH);
2183 break;
2184 default:
2185 throw new Error(mode.toString());
2186 }
2187 }
2188 clientAuth = mode;
2189 }
2190 }
2191
2192 @Override
2193 public final void setEnableSessionCreation(boolean b) {
2194 if (b) {
2195 throw new UnsupportedOperationException();
2196 }
2197 }
2198
2199 @Override
2200 public final boolean getEnableSessionCreation() {
2201 return false;
2202 }
2203
2204 @Override
2205 public final synchronized SSLParameters getSSLParameters() {
2206 SSLParameters sslParameters = super.getSSLParameters();
2207
2208 sslParameters.setEndpointIdentificationAlgorithm(endpointIdentificationAlgorithm);
2209 sslParameters.setAlgorithmConstraints(algorithmConstraints);
2210 sslParameters.setServerNames(serverNames);
2211 if (!isDestroyed()) {
2212 sslParameters.setUseCipherSuitesOrder((SSL.getOptions(ssl) & SSL.SSL_OP_CIPHER_SERVER_PREFERENCE) != 0);
2213 }
2214
2215 sslParameters.setSNIMatchers(matchers);
2216 return sslParameters;
2217 }
2218
2219 @Override
2220 public final synchronized void setSSLParameters(SSLParameters sslParameters) {
2221 if (sslParameters.getAlgorithmConstraints() != null) {
2222 throw new IllegalArgumentException("AlgorithmConstraints are not supported.");
2223 }
2224
2225 boolean isDestroyed = isDestroyed();
2226 if (!isDestroyed) {
2227 if (clientMode) {
2228 List<SNIServerName> proposedServerNames = sslParameters.getServerNames();
2229 if (proposedServerNames != null && !proposedServerNames.isEmpty()) {
2230 for (SNIServerName serverName : proposedServerNames) {
2231 if (!(serverName instanceof SNIHostName)) {
2232 throw new IllegalArgumentException("Only " + SNIHostName.class.getName()
2233 + " instances are supported, but found: " + serverName);
2234 }
2235 }
2236 for (SNIServerName serverName : proposedServerNames) {
2237 SNIHostName name = (SNIHostName) serverName;
2238 SSL.setTlsExtHostName(ssl, name.getAsciiName());
2239 }
2240 }
2241 serverNames = proposedServerNames;
2242 }
2243 if (sslParameters.getUseCipherSuitesOrder()) {
2244 SSL.setOptions(ssl, SSL.SSL_OP_CIPHER_SERVER_PREFERENCE);
2245 } else {
2246 SSL.clearOptions(ssl, SSL.SSL_OP_CIPHER_SERVER_PREFERENCE);
2247 }
2248 }
2249 matchers = sslParameters.getSNIMatchers();
2250
2251 final String endpointIdentificationAlgorithm = sslParameters.getEndpointIdentificationAlgorithm();
2252 if (!isDestroyed) {
2253 configureEndpointVerification(endpointIdentificationAlgorithm);
2254 }
2255 this.endpointIdentificationAlgorithm = endpointIdentificationAlgorithm;
2256 algorithmConstraints = sslParameters.getAlgorithmConstraints();
2257 super.setSSLParameters(sslParameters);
2258 }
2259
2260 private void configureEndpointVerification(String endpointIdentificationAlgorithm) {
2261
2262
2263 if (clientMode && isEndPointVerificationEnabled(endpointIdentificationAlgorithm)) {
2264 SSL.setVerify(ssl, SSL.SSL_CVERIFY_REQUIRED, -1);
2265 }
2266 }
2267
2268 private static boolean isEndPointVerificationEnabled(String endPointIdentificationAlgorithm) {
2269 return endPointIdentificationAlgorithm != null && !endPointIdentificationAlgorithm.isEmpty();
2270 }
2271
2272 private boolean isDestroyed() {
2273 return destroyed;
2274 }
2275
2276 final boolean checkSniHostnameMatch(byte[] hostname) {
2277 Collection<SNIMatcher> matchers = this.matchers;
2278 if (matchers != null && !matchers.isEmpty()) {
2279 SNIHostName name = new SNIHostName(hostname);
2280 for (SNIMatcher matcher : matchers) {
2281
2282 if (matcher.getType() == 0 && matcher.matches(name)) {
2283 return true;
2284 }
2285 }
2286 return false;
2287 }
2288 return true;
2289 }
2290
2291 @Override
2292 public String getNegotiatedApplicationProtocol() {
2293 return applicationProtocol;
2294 }
2295
2296 private static long bufferAddress(ByteBuffer b) {
2297 assert b.isDirect();
2298 if (PlatformDependent.hasUnsafe()) {
2299 return PlatformDependent.directBufferAddress(b);
2300 }
2301 return Buffer.address(b);
2302 }
2303
2304
2305
2306
2307 private void selectApplicationProtocol() throws SSLException {
2308 ApplicationProtocolConfig.SelectedListenerFailureBehavior behavior = apn.selectedListenerFailureBehavior();
2309 List<String> protocols = apn.protocols();
2310 String applicationProtocol;
2311 switch (apn.protocol()) {
2312 case NONE:
2313 break;
2314
2315
2316 case ALPN:
2317 applicationProtocol = SSL.getAlpnSelected(ssl);
2318 if (applicationProtocol != null) {
2319 this.applicationProtocol = selectApplicationProtocol(
2320 protocols, behavior, applicationProtocol);
2321 }
2322 break;
2323 case NPN:
2324 applicationProtocol = SSL.getNextProtoNegotiated(ssl);
2325 if (applicationProtocol != null) {
2326 this.applicationProtocol = selectApplicationProtocol(
2327 protocols, behavior, applicationProtocol);
2328 }
2329 break;
2330 case NPN_AND_ALPN:
2331 applicationProtocol = SSL.getAlpnSelected(ssl);
2332 if (applicationProtocol == null) {
2333 applicationProtocol = SSL.getNextProtoNegotiated(ssl);
2334 }
2335 if (applicationProtocol != null) {
2336 this.applicationProtocol = selectApplicationProtocol(
2337 protocols, behavior, applicationProtocol);
2338 }
2339 break;
2340 default:
2341 throw new Error();
2342 }
2343 }
2344
2345 private static String selectApplicationProtocol(List<String> protocols,
2346 ApplicationProtocolConfig.SelectedListenerFailureBehavior behavior,
2347 String applicationProtocol) throws SSLException {
2348 if (behavior == ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT) {
2349 return applicationProtocol;
2350 } else {
2351 int size = protocols.size();
2352 assert size > 0;
2353 if (protocols.contains(applicationProtocol)) {
2354 return applicationProtocol;
2355 } else {
2356 if (behavior == ApplicationProtocolConfig.SelectedListenerFailureBehavior.CHOOSE_MY_LAST_PROTOCOL) {
2357 return protocols.get(size - 1);
2358 } else {
2359 throw new SSLException("unknown protocol " + applicationProtocol);
2360 }
2361 }
2362 }
2363 }
2364
2365 private static final X509Certificate[] JAVAX_CERTS_NOT_SUPPORTED = new X509Certificate[0];
2366
2367 private final class DefaultOpenSslSession implements OpenSslInternalSession {
2368 private final OpenSslSessionContext sessionContext;
2369
2370
2371
2372 private X509Certificate[] x509PeerCerts;
2373 private Certificate[] peerCerts;
2374
2375 private boolean valid = true;
2376 private String protocol;
2377 private String cipher;
2378 private OpenSslSessionId id = OpenSslSessionId.NULL_ID;
2379 private long creationTime;
2380
2381
2382 private long lastAccessed = -1;
2383
2384 private volatile int applicationBufferSize = MAX_PLAINTEXT_LENGTH;
2385 private volatile Certificate[] localCertificateChain;
2386 private volatile Map<String, Object> keyValueStorage = new ConcurrentHashMap<String, Object>();
2387
2388 DefaultOpenSslSession(OpenSslSessionContext sessionContext) {
2389 this.sessionContext = sessionContext;
2390 }
2391
2392 private SSLSessionBindingEvent newSSLSessionBindingEvent(String name) {
2393 return new SSLSessionBindingEvent(session, name);
2394 }
2395
2396 @Override
2397 public void prepareHandshake() {
2398 keyValueStorage.clear();
2399 }
2400
2401 @Override
2402 public void setSessionDetails(
2403 long creationTime, long lastAccessedTime, OpenSslSessionId sessionId,
2404 Map<String, Object> keyValueStorage) {
2405 synchronized (ReferenceCountedOpenSslEngine.this) {
2406 if (id == OpenSslSessionId.NULL_ID) {
2407 id = sessionId;
2408 this.creationTime = creationTime;
2409 lastAccessed = lastAccessedTime;
2410
2411
2412
2413
2414 this.keyValueStorage = keyValueStorage;
2415 }
2416 }
2417 }
2418
2419 @Override
2420 public Map<String, Object> keyValueStorage() {
2421 return keyValueStorage;
2422 }
2423
2424 @Override
2425 public OpenSslSessionId sessionId() {
2426 synchronized (ReferenceCountedOpenSslEngine.this) {
2427 if (this.id == OpenSslSessionId.NULL_ID && !isDestroyed()) {
2428 byte[] sessionId = SSL.getSessionId(ssl);
2429 if (sessionId != null) {
2430 id = new OpenSslSessionId(sessionId);
2431 }
2432 }
2433
2434 return id;
2435 }
2436 }
2437
2438 @Override
2439 public void setLocalCertificate(Certificate[] localCertificate) {
2440 localCertificateChain = localCertificate;
2441 }
2442
2443 @Override
2444 public byte[] getId() {
2445 return sessionId().cloneBytes();
2446 }
2447
2448 @Override
2449 public OpenSslSessionContext getSessionContext() {
2450 return sessionContext;
2451 }
2452
2453 @Override
2454 public long getCreationTime() {
2455 synchronized (ReferenceCountedOpenSslEngine.this) {
2456 return creationTime;
2457 }
2458 }
2459
2460 @Override
2461 public void setLastAccessedTime(long time) {
2462 synchronized (ReferenceCountedOpenSslEngine.this) {
2463 lastAccessed = time;
2464 }
2465 }
2466
2467 @Override
2468 public long getLastAccessedTime() {
2469
2470 synchronized (ReferenceCountedOpenSslEngine.this) {
2471 return lastAccessed == -1 ? creationTime : lastAccessed;
2472 }
2473 }
2474
2475 @Override
2476 public void invalidate() {
2477 synchronized (ReferenceCountedOpenSslEngine.this) {
2478 valid = false;
2479 sessionContext.removeFromCache(id);
2480 }
2481 }
2482
2483 @Override
2484 public boolean isValid() {
2485 synchronized (ReferenceCountedOpenSslEngine.this) {
2486 return valid || sessionContext.isInCache(id);
2487 }
2488 }
2489
2490 @Override
2491 public void putValue(String name, Object value) {
2492 checkNotNull(name, "name");
2493 checkNotNull(value, "value");
2494
2495 final Object old = keyValueStorage.put(name, value);
2496 if (value instanceof SSLSessionBindingListener) {
2497
2498 ((SSLSessionBindingListener) value).valueBound(newSSLSessionBindingEvent(name));
2499 }
2500 notifyUnbound(old, name);
2501 }
2502
2503 @Override
2504 public Object getValue(String name) {
2505 checkNotNull(name, "name");
2506 return keyValueStorage.get(name);
2507 }
2508
2509 @Override
2510 public void removeValue(String name) {
2511 checkNotNull(name, "name");
2512 final Object old = keyValueStorage.remove(name);
2513 notifyUnbound(old, name);
2514 }
2515
2516 @Override
2517 public String[] getValueNames() {
2518 return keyValueStorage.keySet().toArray(EMPTY_STRINGS);
2519 }
2520
2521 private void notifyUnbound(Object value, String name) {
2522 if (value instanceof SSLSessionBindingListener) {
2523
2524 ((SSLSessionBindingListener) value).valueUnbound(newSSLSessionBindingEvent(name));
2525 }
2526 }
2527
2528
2529
2530
2531
2532 @Override
2533 public void handshakeFinished(byte[] id, String cipher, String protocol, byte[] peerCertificate,
2534 byte[][] peerCertificateChain, long creationTime, long timeout)
2535 throws SSLException {
2536 synchronized (ReferenceCountedOpenSslEngine.this) {
2537 if (!isDestroyed()) {
2538 if (this.id == OpenSslSessionId.NULL_ID) {
2539
2540
2541 this.id = id == null ? OpenSslSessionId.NULL_ID : new OpenSslSessionId(id);
2542
2543
2544 this.creationTime = lastAccessed = creationTime;
2545 }
2546 this.cipher = toJavaCipherSuite(cipher);
2547 this.protocol = protocol;
2548
2549 if (clientMode) {
2550 if (isEmpty(peerCertificateChain)) {
2551 peerCerts = EmptyArrays.EMPTY_CERTIFICATES;
2552 if (OpenSsl.JAVAX_CERTIFICATE_CREATION_SUPPORTED) {
2553 x509PeerCerts = EmptyArrays.EMPTY_JAVAX_X509_CERTIFICATES;
2554 } else {
2555 x509PeerCerts = JAVAX_CERTS_NOT_SUPPORTED;
2556 }
2557 } else {
2558 peerCerts = new Certificate[peerCertificateChain.length];
2559 if (OpenSsl.JAVAX_CERTIFICATE_CREATION_SUPPORTED) {
2560 x509PeerCerts = new X509Certificate[peerCertificateChain.length];
2561 } else {
2562 x509PeerCerts = JAVAX_CERTS_NOT_SUPPORTED;
2563 }
2564 initCerts(peerCertificateChain, 0);
2565 }
2566 } else {
2567
2568
2569
2570
2571
2572 if (isEmpty(peerCertificate)) {
2573 peerCerts = EmptyArrays.EMPTY_CERTIFICATES;
2574 x509PeerCerts = EmptyArrays.EMPTY_JAVAX_X509_CERTIFICATES;
2575 } else {
2576 if (isEmpty(peerCertificateChain)) {
2577 peerCerts = new Certificate[] {new LazyX509Certificate(peerCertificate)};
2578 if (OpenSsl.JAVAX_CERTIFICATE_CREATION_SUPPORTED) {
2579 x509PeerCerts = new X509Certificate[] {
2580 new LazyJavaxX509Certificate(peerCertificate)
2581 };
2582 } else {
2583 x509PeerCerts = JAVAX_CERTS_NOT_SUPPORTED;
2584 }
2585 } else {
2586 peerCerts = new Certificate[peerCertificateChain.length + 1];
2587 peerCerts[0] = new LazyX509Certificate(peerCertificate);
2588
2589 if (OpenSsl.JAVAX_CERTIFICATE_CREATION_SUPPORTED) {
2590 x509PeerCerts = new X509Certificate[peerCertificateChain.length + 1];
2591 x509PeerCerts[0] = new LazyJavaxX509Certificate(peerCertificate);
2592 } else {
2593 x509PeerCerts = JAVAX_CERTS_NOT_SUPPORTED;
2594 }
2595
2596 initCerts(peerCertificateChain, 1);
2597 }
2598 }
2599 }
2600
2601 calculateMaxWrapOverhead();
2602
2603 handshakeState = HandshakeState.FINISHED;
2604 } else {
2605 throw new SSLException("Already closed");
2606 }
2607 }
2608 }
2609
2610 private void initCerts(byte[][] chain, int startPos) {
2611 for (int i = 0; i < chain.length; i++) {
2612 int certPos = startPos + i;
2613 peerCerts[certPos] = new LazyX509Certificate(chain[i]);
2614 if (x509PeerCerts != JAVAX_CERTS_NOT_SUPPORTED) {
2615 x509PeerCerts[certPos] = new LazyJavaxX509Certificate(chain[i]);
2616 }
2617 }
2618 }
2619
2620 @Override
2621 public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
2622 synchronized (ReferenceCountedOpenSslEngine.this) {
2623 if (isEmpty(peerCerts)) {
2624 throw new SSLPeerUnverifiedException("peer not verified");
2625 }
2626 return peerCerts.clone();
2627 }
2628 }
2629
2630 @Override
2631 public boolean hasPeerCertificates() {
2632 synchronized (ReferenceCountedOpenSslEngine.this) {
2633 return !isEmpty(peerCerts);
2634 }
2635 }
2636
2637 @Override
2638 public Certificate[] getLocalCertificates() {
2639 Certificate[] localCerts = localCertificateChain;
2640 if (localCerts == null) {
2641 return null;
2642 }
2643 return localCerts.clone();
2644 }
2645
2646 @Override
2647 public X509Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException {
2648 synchronized (ReferenceCountedOpenSslEngine.this) {
2649 if (x509PeerCerts == JAVAX_CERTS_NOT_SUPPORTED) {
2650
2651
2652 throw new UnsupportedOperationException();
2653 }
2654 if (isEmpty(x509PeerCerts)) {
2655 throw new SSLPeerUnverifiedException("peer not verified");
2656 }
2657 return x509PeerCerts.clone();
2658 }
2659 }
2660
2661 @Override
2662 public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
2663 Certificate[] peer = getPeerCertificates();
2664
2665
2666 return ((java.security.cert.X509Certificate) peer[0]).getSubjectX500Principal();
2667 }
2668
2669 @Override
2670 public Principal getLocalPrincipal() {
2671 Certificate[] local = localCertificateChain;
2672 if (local == null || local.length == 0) {
2673 return null;
2674 }
2675 return ((java.security.cert.X509Certificate) local[0]).getSubjectX500Principal();
2676 }
2677
2678 @Override
2679 public String getCipherSuite() {
2680 synchronized (ReferenceCountedOpenSslEngine.this) {
2681 if (cipher == null) {
2682 return SslUtils.INVALID_CIPHER;
2683 }
2684 return cipher;
2685 }
2686 }
2687
2688 @Override
2689 public String getProtocol() {
2690 String protocol = this.protocol;
2691 if (protocol == null) {
2692 synchronized (ReferenceCountedOpenSslEngine.this) {
2693 if (!isDestroyed()) {
2694 protocol = SSL.getVersion(ssl);
2695 } else {
2696 protocol = StringUtil.EMPTY_STRING;
2697 }
2698 }
2699 }
2700 return protocol;
2701 }
2702
2703 @Override
2704 public String getPeerHost() {
2705 return ReferenceCountedOpenSslEngine.this.getPeerHost();
2706 }
2707
2708 @Override
2709 public int getPeerPort() {
2710 return ReferenceCountedOpenSslEngine.this.getPeerPort();
2711 }
2712
2713 @Override
2714 public int getPacketBufferSize() {
2715 return SSL.SSL_MAX_ENCRYPTED_LENGTH;
2716 }
2717
2718 @Override
2719 public int getApplicationBufferSize() {
2720 return applicationBufferSize;
2721 }
2722
2723 @Override
2724 public void tryExpandApplicationBufferSize(int packetLengthDataOnly) {
2725 if (packetLengthDataOnly > MAX_PLAINTEXT_LENGTH && applicationBufferSize != MAX_RECORD_SIZE) {
2726 applicationBufferSize = MAX_RECORD_SIZE;
2727 }
2728 }
2729
2730 @Override
2731 public String toString() {
2732 return "DefaultOpenSslSession{" +
2733 "sessionContext=" + sessionContext +
2734 ", id=" + id +
2735 '}';
2736 }
2737
2738 @Override
2739 public int hashCode() {
2740 return sessionId().hashCode();
2741 }
2742
2743 @Override
2744 public boolean equals(Object o) {
2745 if (o == this) {
2746 return true;
2747 }
2748
2749 if (!(o instanceof OpenSslInternalSession)) {
2750 return false;
2751 }
2752 return sessionId().equals(((OpenSslInternalSession) o).sessionId());
2753 }
2754 }
2755
2756 private interface NativeSslException {
2757 int errorCode();
2758 }
2759
2760 private static final class OpenSslException extends SSLException implements NativeSslException {
2761 private final int errorCode;
2762
2763 OpenSslException(String reason, int errorCode) {
2764 super(reason);
2765 this.errorCode = errorCode;
2766 }
2767
2768 @Override
2769 public int errorCode() {
2770 return errorCode;
2771 }
2772 }
2773
2774 private static final class OpenSslHandshakeException extends SSLHandshakeException implements NativeSslException {
2775 private final int errorCode;
2776
2777 OpenSslHandshakeException(String reason, int errorCode) {
2778 super(reason);
2779 this.errorCode = errorCode;
2780 }
2781
2782 @Override
2783 public int errorCode() {
2784 return errorCode;
2785 }
2786 }
2787 }