1d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root/* 2d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root * Copyright (C) 2012 The Android Open Source Project 3d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root * 4d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root * Licensed under the Apache License, Version 2.0 (the "License"); 5d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root * you may not use this file except in compliance with the License. 6d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root * You may obtain a copy of the License at 7d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root * 8d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root * http://www.apache.org/licenses/LICENSE-2.0 9d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root * 10d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root * Unless required by applicable law or agreed to in writing, software 11d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root * distributed under the License is distributed on an "AS IS" BASIS, 12d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root * See the License for the specific language governing permissions and 14d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root * limitations under the License. 15d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root */ 16d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root 17860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootpackage org.conscrypt; 18d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root 19d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Rootimport java.io.FilterInputStream; 20d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Rootimport java.io.IOException; 21d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Rootimport java.io.InputStream; 22d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root 23d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root/** 24d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root * Provides an interface to OpenSSL's BIO system directly from a Java 25d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root * InputStream. It allows an OpenSSL API to read directly from something more 26d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root * flexible interface than a byte array. 27d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root */ 2829916ef38dc9cb4e4c6e3fdb87d4e921546d3ef4Nathan Mittlerclass OpenSSLBIOInputStream extends FilterInputStream { 29d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root private long ctx; 30d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root 3129916ef38dc9cb4e4c6e3fdb87d4e921546d3ef4Nathan Mittler OpenSSLBIOInputStream(InputStream is, boolean isFinite) { 32d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root super(is); 33d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root 3466537ee0121bdd14737191d14927da223f0809eeAdam Langley ctx = NativeCrypto.create_BIO_InputStream(this, isFinite); 35d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root } 36d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root 3729916ef38dc9cb4e4c6e3fdb87d4e921546d3ef4Nathan Mittler long getBioContext() { 38d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root return ctx; 39d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root } 40d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root 4129916ef38dc9cb4e4c6e3fdb87d4e921546d3ef4Nathan Mittler void release() { 4219fdf1af6bada9ebf4820839780d8713ac3824faKenny Root NativeCrypto.BIO_free_all(ctx); 4319fdf1af6bada9ebf4820839780d8713ac3824faKenny Root } 4419fdf1af6bada9ebf4820839780d8713ac3824faKenny Root 4532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root /** 4632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * Similar to a {@code readLine} method, but matches what OpenSSL expects 4732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * from a {@code BIO_gets} method. 4832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root */ 4929916ef38dc9cb4e4c6e3fdb87d4e921546d3ef4Nathan Mittler int gets(byte[] buffer) throws IOException { 50d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root if (buffer == null || buffer.length == 0) { 51d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root return 0; 52d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root } 53d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root 54d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root int offset = 0; 5532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root int inputByte = 0; 5632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root while (offset < buffer.length) { 57d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root inputByte = read(); 5877be80dd2cfed6c565ffb64fd87131f3e6f43ec7Kenny Root if (inputByte == -1) { 5977be80dd2cfed6c565ffb64fd87131f3e6f43ec7Kenny Root // EOF 6077be80dd2cfed6c565ffb64fd87131f3e6f43ec7Kenny Root break; 6177be80dd2cfed6c565ffb64fd87131f3e6f43ec7Kenny Root } 6277be80dd2cfed6c565ffb64fd87131f3e6f43ec7Kenny Root if (inputByte == '\n') { 6332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root if (offset == 0) { 6432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root // If we haven't read anything yet, ignore CRLF. 6532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root continue; 6632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } else { 6732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root break; 6832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 6932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 70d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root 7132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root buffer[offset++] = (byte) inputByte; 72d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root } 73d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root 74d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root return offset; 75d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root } 76d05ac5ff95fa7d673de209a780d5f9b4f106e50dKenny Root} 77