PageRenderTime 5107ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/src/java/org/jruby/ext/openssl/impl/BIO.java

https://github.com/nahi/jruby-openssl
Java | 345 lines | 223 code | 42 blank | 80 comment | 24 complexity | beca71765fa44118593af8feb2dfcf14 MD5 | raw file
  1. /***** BEGIN LICENSE BLOCK *****
  2. * Version: CPL 1.0/GPL 2.0/LGPL 2.1
  3. *
  4. * The contents of this file are subject to the Common Public
  5. * License Version 1.0 (the "License"); you may not use this file
  6. * except in compliance with the License. You may obtain a copy of
  7. * the License at http://www.eclipse.org/legal/cpl-v10.html
  8. *
  9. * Software distributed under the License is distributed on an "AS
  10. * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  11. * implied. See the License for the specific language governing
  12. * rights and limitations under the License.
  13. *
  14. * Copyright (C) 2008 Ola Bini <ola.bini@gmail.com>
  15. *
  16. * Alternatively, the contents of this file may be used under the terms of
  17. * either of the GNU General Public License Version 2 or later (the "GPL"),
  18. * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  19. * in which case the provisions of the GPL or the LGPL are applicable instead
  20. * of those above. If you wish to allow use of your version of this file only
  21. * under the terms of either the GPL or the LGPL, and not to allow others to
  22. * use your version of this file under the terms of the CPL, indicate your
  23. * decision by deleting the provisions above and replace them with the notice
  24. * and other provisions required by the GPL or the LGPL. If you do not delete
  25. * the provisions above, a recipient may use your version of this file under
  26. * the terms of any one of the CPL, the GPL or the LGPL.
  27. ***** END LICENSE BLOCK *****/
  28. package org.jruby.ext.openssl.impl;
  29. import java.io.IOException;
  30. import java.io.InputStream;
  31. import java.io.OutputStream;
  32. import java.security.MessageDigest;
  33. import javax.crypto.Cipher;
  34. /** c: BIO
  35. *
  36. * @author <a href="mailto:ola.bini@gmail.com">Ola Bini</a>
  37. */
  38. public class BIO {
  39. public final static int TYPE_DESCRIPTOR = 0x0100;
  40. public final static int TYPE_FILTER = 0x0200;
  41. public final static int TYPE_SOURCE_SINK = 0x0400;
  42. public final static int TYPE_NONE = 0;
  43. public final static int TYPE_MEM = 1 | TYPE_SOURCE_SINK;
  44. public final static int TYPE_FILE = 2 | TYPE_SOURCE_SINK;
  45. public final static int TYPE_FD = 4 | TYPE_SOURCE_SINK | TYPE_DESCRIPTOR;
  46. public final static int TYPE_SOCKET = 5 | TYPE_SOURCE_SINK | TYPE_DESCRIPTOR;
  47. public final static int TYPE_NULL = 6 | TYPE_SOURCE_SINK;
  48. public final static int TYPE_SSL = 7 | TYPE_FILTER;
  49. public final static int TYPE_MD = 8 | TYPE_FILTER;
  50. public final static int TYPE_BUFFER = 9 | TYPE_FILTER;
  51. public final static int TYPE_CIPHER = 10 | TYPE_FILTER;
  52. public final static int TYPE_BASE64 = 11 | TYPE_FILTER;
  53. public final static int TYPE_CONNECT = 12 | TYPE_SOURCE_SINK | TYPE_DESCRIPTOR;
  54. public final static int TYPE_ACCEPT = 13 | TYPE_SOURCE_SINK | TYPE_DESCRIPTOR;
  55. public final static int TYPE_PROXY_CLIENT = 14 | TYPE_FILTER;
  56. public final static int TYPE_PROXY_SERVER = 15 | TYPE_FILTER;
  57. public final static int TYPE_NBIO_TEST = 16 | TYPE_FILTER;
  58. public final static int TYPE_NULL_FILTER = 17 | TYPE_FILTER;
  59. public final static int TYPE_BER = 18 | TYPE_FILTER;
  60. public final static int TYPE_BIO = 19 | TYPE_SOURCE_SINK;
  61. private static final class BIOInputStream extends InputStream {
  62. private BIO bio;
  63. public BIOInputStream(BIO bio) {
  64. this.bio = bio;
  65. }
  66. @Override
  67. public int read() throws IOException {
  68. byte[] buffer = new byte[1];
  69. int read = bio.read(buffer, 0, 1);
  70. if(read == 0) {
  71. return -1;
  72. }
  73. return ((int)buffer[0])&0xFF;
  74. }
  75. @Override
  76. public int read(byte[] into) throws IOException {
  77. return this.read(into, 0, into.length);
  78. }
  79. @Override
  80. public int read(byte[] into, int off, int len) throws IOException {
  81. int read = bio.read(into, off, len);
  82. if(read == 0) {
  83. return -1;
  84. }
  85. return read;
  86. }
  87. }
  88. private static final class BIOOutputStream extends OutputStream {
  89. private BIO bio;
  90. public BIOOutputStream(BIO bio) {
  91. this.bio = bio;
  92. }
  93. @Override
  94. public void write(int b) throws IOException {
  95. }
  96. @Override
  97. public void write(byte[] out) throws IOException {
  98. this.write(out, 0, out.length);
  99. }
  100. @Override
  101. public void write(byte[] out, int off, int len) throws IOException {
  102. bio.write(out, off, len);
  103. }
  104. }
  105. public static InputStream asInputStream(BIO input) {
  106. return new BIOInputStream(input);
  107. }
  108. public static OutputStream asOutputStream(BIO output) {
  109. return new BIOOutputStream(output);
  110. }
  111. public static BIO base64Filter(BIO real) {
  112. BIO b64 = new Base64BIOFilter();
  113. b64.push(real);
  114. return b64;
  115. }
  116. public static BIO mdFilter(MessageDigest md) {
  117. return new MessageDigestBIOFilter(md);
  118. }
  119. public static BIO cipherFilter(Cipher cipher) {
  120. return new CipherBIOFilter(cipher);
  121. }
  122. public static BIO fromString(String input) {
  123. MemBIO bio = new MemBIO();
  124. byte[] buf = null;
  125. try {
  126. buf = input.getBytes("ISO8859-1");
  127. bio.write(buf, 0, buf.length);
  128. } catch(Exception e) {}
  129. return bio;
  130. }
  131. /** c: BIO_new(BIO_f_buffered())
  132. *
  133. */
  134. public static BIO buffered() {
  135. return null;
  136. }
  137. /** c: BIO_new(BIO_s_mem())
  138. *
  139. */
  140. public static BIO mem() {
  141. return new MemBIO();
  142. }
  143. /** c: BIO_new(BIO_s_null())
  144. *
  145. */
  146. public static BIO nullSink() {
  147. return new NullSinkBIO();
  148. }
  149. /** c: BIO_new_mem_buf
  150. *
  151. */
  152. public static BIO memBuf(byte[] arr) {
  153. return memBuf(arr, 0, arr.length);
  154. }
  155. /** c: BIO_new_mem_buf
  156. *
  157. */
  158. public static BIO memBuf(byte[] arr, int offset, int length) {
  159. // TODO: create real readonly version of MemBIO.
  160. try {
  161. BIO bio = new MemBIO();
  162. bio.write(arr, offset, length);
  163. return bio;
  164. } catch(IOException e) {
  165. return null;
  166. }
  167. }
  168. protected BIO nextBio;
  169. protected BIO prevBio;
  170. /** c: BIO_flush
  171. *
  172. */
  173. public void flush() throws IOException {
  174. }
  175. private final static byte[] CONTENT_TEXT;
  176. static {
  177. byte[] val = null;
  178. try {
  179. val = "Content-Type: text/plain\r\n\r\n".getBytes("ISO8859-1");
  180. } catch(Exception e) {
  181. val = null;
  182. }
  183. CONTENT_TEXT = val;
  184. }
  185. /** c: SMIME_crlf_copy
  186. *
  187. */
  188. public void crlfCopy(BIO out, int flags) throws IOException {
  189. BIO in = this;
  190. byte[] linebuf = new byte[SMIME.MAX_SMLEN];
  191. int[] len = new int[]{0};
  192. if((flags & PKCS7.BINARY) > 0 ) {
  193. while((len[0] = in.read(linebuf, 0, SMIME.MAX_SMLEN)) > 0) {
  194. out.write(linebuf, 0, len[0]);
  195. }
  196. return;
  197. }
  198. if((flags & PKCS7.TEXT) > 0) {
  199. out.write(CONTENT_TEXT, 0, CONTENT_TEXT.length);
  200. }
  201. while((len[0] = in.gets(linebuf, SMIME.MAX_SMLEN)) > 0) {
  202. boolean eol = SMIME.stripEol(linebuf, len);
  203. if(len[0] != 0) {
  204. out.write(linebuf, 0, len[0]);
  205. }
  206. if(eol) {
  207. out.write(SMIME.NEWLINE, 0, 2);
  208. }
  209. }
  210. }
  211. /** c: BIO_gets
  212. *
  213. */
  214. public int gets(byte[] in, int len) throws IOException {
  215. throw new UnsupportedOperationException("for " + this.getClass().getName());
  216. }
  217. /** c: BIO_write
  218. *
  219. */
  220. public int write(byte[] out, int offset, int len) throws IOException {
  221. throw new UnsupportedOperationException("for " + this.getClass().getName());
  222. }
  223. /** c: BIO_read
  224. *
  225. */
  226. public int read(byte[] into, int offset, int len) throws IOException {
  227. throw new UnsupportedOperationException("for " + this.getClass().getName());
  228. }
  229. /** c: BIO_set_mem_eof_return
  230. *
  231. */
  232. public void setMemEofReturn(int value) {
  233. throw new UnsupportedOperationException("for " + this.getClass().getName());
  234. }
  235. /** c: BIO_push
  236. *
  237. */
  238. public BIO push(BIO bio) {
  239. BIO lb = this;
  240. while(lb.nextBio != null) {
  241. lb = lb.nextBio;
  242. }
  243. if(bio != null) {
  244. bio.prevBio = lb;
  245. }
  246. lb.nextBio = bio;
  247. return this;
  248. }
  249. /** c: BIO_pop
  250. *
  251. */
  252. public BIO pop() {
  253. BIO ret = this.nextBio;
  254. if(this.prevBio != null) {
  255. this.prevBio.nextBio = this.nextBio;
  256. }
  257. if(this.nextBio != null) {
  258. this.nextBio.prevBio = this.prevBio;
  259. }
  260. this.nextBio = null;
  261. this.prevBio = null;
  262. return ret;
  263. }
  264. /** c: BIO_find_type
  265. *
  266. */
  267. public BIO findType(int type) {
  268. int mask = type & 0xFF;
  269. BIO bio = this;
  270. do {
  271. int mt = bio.getType();
  272. if(mask == 0) {
  273. if((mt & type) != 0) {
  274. return bio;
  275. }
  276. } else if(mt == type) {
  277. return bio;
  278. }
  279. bio = bio.nextBio;
  280. } while(bio != null);
  281. return null;
  282. }
  283. /** c: BIO_next
  284. *
  285. */
  286. public BIO next() {
  287. return this.nextBio;
  288. }
  289. public int getType() {
  290. return TYPE_BIO;
  291. }
  292. /** c: BIO_reset
  293. *
  294. */
  295. public void reset() {
  296. throw new UnsupportedOperationException();
  297. }
  298. @Override
  299. public String toString() {
  300. String[] names = getClass().getName().split("\\.");
  301. return "#<BIO:" + names[names.length-1] + " next=" + next() + ">";
  302. }
  303. }// BIO