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