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