1f878e438660d93f8689b864165230492e7a412d4Kenny Root/* 2f878e438660d93f8689b864165230492e7a412d4Kenny Root * Copyright (C) 2014 The Android Open Source Project 3f878e438660d93f8689b864165230492e7a412d4Kenny Root * 4f878e438660d93f8689b864165230492e7a412d4Kenny Root * Licensed under the Apache License, Version 2.0 (the "License"); 5f878e438660d93f8689b864165230492e7a412d4Kenny Root * you may not use this file except in compliance with the License. 6f878e438660d93f8689b864165230492e7a412d4Kenny Root * You may obtain a copy of the License at 7f878e438660d93f8689b864165230492e7a412d4Kenny Root * 8f878e438660d93f8689b864165230492e7a412d4Kenny Root * http://www.apache.org/licenses/LICENSE-2.0 9f878e438660d93f8689b864165230492e7a412d4Kenny Root * 10f878e438660d93f8689b864165230492e7a412d4Kenny Root * Unless required by applicable law or agreed to in writing, software 11f878e438660d93f8689b864165230492e7a412d4Kenny Root * distributed under the License is distributed on an "AS IS" BASIS, 12f878e438660d93f8689b864165230492e7a412d4Kenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f878e438660d93f8689b864165230492e7a412d4Kenny Root * See the License for the specific language governing permissions and 14f878e438660d93f8689b864165230492e7a412d4Kenny Root * limitations under the License. 15f878e438660d93f8689b864165230492e7a412d4Kenny Root */ 16f878e438660d93f8689b864165230492e7a412d4Kenny Root 17f878e438660d93f8689b864165230492e7a412d4Kenny Rootpackage org.conscrypt; 18f878e438660d93f8689b864165230492e7a412d4Kenny Root 19f878e438660d93f8689b864165230492e7a412d4Kenny Rootimport java.io.IOException; 20f878e438660d93f8689b864165230492e7a412d4Kenny Rootimport java.io.InputStream; 21f878e438660d93f8689b864165230492e7a412d4Kenny Rootimport java.nio.ByteBuffer; 22f878e438660d93f8689b864165230492e7a412d4Kenny Root 23f878e438660d93f8689b864165230492e7a412d4Kenny Rootpublic final class OpenSSLBIOSource { 24f878e438660d93f8689b864165230492e7a412d4Kenny Root private OpenSSLBIOInputStream source; 25f878e438660d93f8689b864165230492e7a412d4Kenny Root 26f878e438660d93f8689b864165230492e7a412d4Kenny Root public static OpenSSLBIOSource wrap(ByteBuffer buffer) { 2766537ee0121bdd14737191d14927da223f0809eeAdam Langley return new OpenSSLBIOSource( 2866537ee0121bdd14737191d14927da223f0809eeAdam Langley new OpenSSLBIOInputStream(new ByteBufferInputStream(buffer), false)); 29f878e438660d93f8689b864165230492e7a412d4Kenny Root } 30f878e438660d93f8689b864165230492e7a412d4Kenny Root 31f878e438660d93f8689b864165230492e7a412d4Kenny Root public OpenSSLBIOSource(OpenSSLBIOInputStream source) { 32f878e438660d93f8689b864165230492e7a412d4Kenny Root this.source = source; 33f878e438660d93f8689b864165230492e7a412d4Kenny Root } 34f878e438660d93f8689b864165230492e7a412d4Kenny Root 35f878e438660d93f8689b864165230492e7a412d4Kenny Root public long getContext() { 36f878e438660d93f8689b864165230492e7a412d4Kenny Root return source.getBioContext(); 37f878e438660d93f8689b864165230492e7a412d4Kenny Root } 38f878e438660d93f8689b864165230492e7a412d4Kenny Root 39f878e438660d93f8689b864165230492e7a412d4Kenny Root public synchronized void release() { 40f878e438660d93f8689b864165230492e7a412d4Kenny Root if (source != null) { 41f878e438660d93f8689b864165230492e7a412d4Kenny Root NativeCrypto.BIO_free_all(source.getBioContext()); 42f878e438660d93f8689b864165230492e7a412d4Kenny Root source = null; 43f878e438660d93f8689b864165230492e7a412d4Kenny Root } 44f878e438660d93f8689b864165230492e7a412d4Kenny Root } 45f878e438660d93f8689b864165230492e7a412d4Kenny Root 46f878e438660d93f8689b864165230492e7a412d4Kenny Root @Override 47f878e438660d93f8689b864165230492e7a412d4Kenny Root protected void finalize() throws Throwable { 48f878e438660d93f8689b864165230492e7a412d4Kenny Root try { 49f878e438660d93f8689b864165230492e7a412d4Kenny Root release(); 50f878e438660d93f8689b864165230492e7a412d4Kenny Root } finally { 51f878e438660d93f8689b864165230492e7a412d4Kenny Root super.finalize(); 52f878e438660d93f8689b864165230492e7a412d4Kenny Root } 53f878e438660d93f8689b864165230492e7a412d4Kenny Root } 54f878e438660d93f8689b864165230492e7a412d4Kenny Root 55f878e438660d93f8689b864165230492e7a412d4Kenny Root private static class ByteBufferInputStream extends InputStream { 56f878e438660d93f8689b864165230492e7a412d4Kenny Root private final ByteBuffer source; 57f878e438660d93f8689b864165230492e7a412d4Kenny Root 58f878e438660d93f8689b864165230492e7a412d4Kenny Root public ByteBufferInputStream(ByteBuffer source) { 59f878e438660d93f8689b864165230492e7a412d4Kenny Root this.source = source; 60f878e438660d93f8689b864165230492e7a412d4Kenny Root } 61f878e438660d93f8689b864165230492e7a412d4Kenny Root 62f878e438660d93f8689b864165230492e7a412d4Kenny Root @Override 63f878e438660d93f8689b864165230492e7a412d4Kenny Root public int read() throws IOException { 64f878e438660d93f8689b864165230492e7a412d4Kenny Root if (source.remaining() > 0) { 65f878e438660d93f8689b864165230492e7a412d4Kenny Root return source.get(); 66f878e438660d93f8689b864165230492e7a412d4Kenny Root } else { 67f878e438660d93f8689b864165230492e7a412d4Kenny Root return -1; 68f878e438660d93f8689b864165230492e7a412d4Kenny Root } 69f878e438660d93f8689b864165230492e7a412d4Kenny Root } 70f878e438660d93f8689b864165230492e7a412d4Kenny Root 71f878e438660d93f8689b864165230492e7a412d4Kenny Root @Override 72f878e438660d93f8689b864165230492e7a412d4Kenny Root public int available() throws IOException { 73f878e438660d93f8689b864165230492e7a412d4Kenny Root return source.limit() - source.position(); 74f878e438660d93f8689b864165230492e7a412d4Kenny Root } 75f878e438660d93f8689b864165230492e7a412d4Kenny Root 76f878e438660d93f8689b864165230492e7a412d4Kenny Root @Override 77f878e438660d93f8689b864165230492e7a412d4Kenny Root public int read(byte[] buffer) throws IOException { 78f878e438660d93f8689b864165230492e7a412d4Kenny Root int originalPosition = source.position(); 79f878e438660d93f8689b864165230492e7a412d4Kenny Root source.get(buffer); 80f878e438660d93f8689b864165230492e7a412d4Kenny Root return source.position() - originalPosition; 81f878e438660d93f8689b864165230492e7a412d4Kenny Root } 82f878e438660d93f8689b864165230492e7a412d4Kenny Root 83f878e438660d93f8689b864165230492e7a412d4Kenny Root @Override 84f878e438660d93f8689b864165230492e7a412d4Kenny Root public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException { 85f878e438660d93f8689b864165230492e7a412d4Kenny Root int toRead = Math.min(source.remaining(), byteCount); 86f878e438660d93f8689b864165230492e7a412d4Kenny Root int originalPosition = source.position(); 87f878e438660d93f8689b864165230492e7a412d4Kenny Root source.get(buffer, byteOffset, toRead); 88f878e438660d93f8689b864165230492e7a412d4Kenny Root return source.position() - originalPosition; 89f878e438660d93f8689b864165230492e7a412d4Kenny Root } 90f878e438660d93f8689b864165230492e7a412d4Kenny Root 91f878e438660d93f8689b864165230492e7a412d4Kenny Root @Override 92f878e438660d93f8689b864165230492e7a412d4Kenny Root public void reset() throws IOException { 93f878e438660d93f8689b864165230492e7a412d4Kenny Root source.reset(); 94f878e438660d93f8689b864165230492e7a412d4Kenny Root } 95f878e438660d93f8689b864165230492e7a412d4Kenny Root 96f878e438660d93f8689b864165230492e7a412d4Kenny Root @Override 97f878e438660d93f8689b864165230492e7a412d4Kenny Root public long skip(long byteCount) throws IOException { 98f878e438660d93f8689b864165230492e7a412d4Kenny Root int originalPosition = source.position(); 99f878e438660d93f8689b864165230492e7a412d4Kenny Root source.position((int) (originalPosition + byteCount)); 100f878e438660d93f8689b864165230492e7a412d4Kenny Root return source.position() - originalPosition; 101f878e438660d93f8689b864165230492e7a412d4Kenny Root } 102f878e438660d93f8689b864165230492e7a412d4Kenny Root } 103f878e438660d93f8689b864165230492e7a412d4Kenny Root} 104