static NativeSslSession newInstance(
            AbstractSessionContext context, byte[] data, String host, int port) {
        ByteBuffer buf = ByteBuffer.wrap(data);
        try {
            int type = buf.getInt();
            if (!isSupportedType(type)) {
                throw new IOException("Unexpected type ID: " + type);
            }

            int length = buf.getInt();
            checkRemaining(buf, length);

            byte[] sessionData = new byte[length];
            buf.get(sessionData);

            int count = buf.getInt();
            checkRemaining(buf, count);

            java.security.cert.X509Certificate[] peerCerts =
                    new java.security.cert.X509Certificate[count];
            for (int i = 0; i < count; i++) {
                length = buf.getInt();
                checkRemaining(buf, length);

                byte[] certData = new byte[length];
                buf.get(certData);
                try {
                    peerCerts[i] = OpenSSLX509Certificate.fromX509Der(certData);
                } catch (Exception e) {
                    throw new IOException("Can not read certificate " + i + "/" + count);
                }
            }

            byte[] ocspData = null;
            if (type >= OPEN_SSL_WITH_OCSP.value) {
                // We only support one OCSP response now, but in the future
                // we may support RFC 6961 which has multiple.
                int countOcspResponses = buf.getInt();
                checkRemaining(buf, countOcspResponses);

                if (countOcspResponses >= 1) {
                    int ocspLength = buf.getInt();
                    checkRemaining(buf, ocspLength);

                    ocspData = new byte[ocspLength];
                    buf.get(ocspData);

                    // Skip the rest of the responses.
                    for (int i = 1; i < countOcspResponses; i++) {
                        ocspLength = buf.getInt();
                        checkRemaining(buf, ocspLength);
                        buf.position(buf.position() + ocspLength);
                    }
                }
            }

            byte[] tlsSctData = null;
            if (type == OPEN_SSL_WITH_TLS_SCT.value) {
                int tlsSctDataLength = buf.getInt();
                checkRemaining(buf, tlsSctDataLength);

                if (tlsSctDataLength > 0) {
                    tlsSctData = new byte[tlsSctDataLength];
                    buf.get(tlsSctData);
                }
            }

            if (buf.remaining() != 0) {
                log(new AssertionError("Read entire session, but data still remains; rejecting"));
                return null;
            }

            NativeRef.SSL_SESSION ref =
                    new NativeRef.SSL_SESSION(NativeCrypto.d2i_SSL_SESSION(sessionData));
            return new Impl(context, ref, host, port, peerCerts, ocspData, tlsSctData);
        } catch (IOException | BufferUnderflowException e) {
            log(e);
            return null;
        }
    }
Creates a new {@link NativeSslSession} instance from the provided serialized bytes, which
were generated by {@link #toBytes()}.

@return The new instance if successful. If unable to parse the bytes for any reason, returns
{@code null}.
common/src/main/java/org/conscrypt/NativeSslSession.java