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