tls_bio.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. /*
  2. * Kamailio TLS module
  3. *
  4. * Copyright (C) 2010 iptelorg GmbH
  5. *
  6. * Permission to use, copy, modify, and distribute this software for any
  7. * purpose with or without fee is hereby granted, provided that the above
  8. * copyright notice and this permission notice appear in all copies.
  9. *
  10. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  13. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  16. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17. */
  18. /**
  19. * openssl BIOs for reading/writing via a fixed memory buffer.
  20. * @file
  21. * @ingroup tls
  22. */
  23. #include "tls_bio.h"
  24. #include "../../compiler_opt.h"
  25. #include "../../dprint.h"
  26. #include "../../ut.h"
  27. #include "tls_cfg.h"
  28. /* 0xf2 should be unused (as of openssl 1.0.0 max.
  29. internal defined BIO is 23) */
  30. #define BIO_TYPE_TLS_MBUF (BIO_TYPE_SOURCE_SINK | 0xf2)
  31. /* debugging */
  32. #ifdef NO_TLS_BIO_DEBUG
  33. #undef TLS_BIO_DEBUG
  34. #endif
  35. #ifdef TLS_BIO_DEBUG
  36. #ifdef __SUNPRO_C
  37. #define TLS_BIO_DBG(...) \
  38. LOG_(DEFAULT_FACILITY, cfg_get(tls, tls_cfg, debug),\
  39. "tls_BIO: " LOC_INFO, __VA_ARGS__)
  40. #else
  41. #define TLS_BIO_DBG(args...) \
  42. LOG_(DEFAULT_FACILITY, cfg_get(tls, tls_cfg, debug),\
  43. "tls_BIO: " LOC_INFO, ## args)
  44. #endif /* __SUNPRO_c */
  45. #else /* TLS_BIO_DEBUG */
  46. #ifdef __SUNPRO_C
  47. #define TLS_BIO_DBG(...)
  48. #else
  49. #define TLS_BIO_DBG(fmt, args...)
  50. #endif /* __SUNPRO_c */
  51. #endif /* TLS_BIO_DEBUG */
  52. static int tls_bio_mbuf_new(BIO* b);
  53. static int tls_bio_mbuf_free(BIO* b);
  54. static int tls_bio_mbuf_write(BIO* b, const char* buf, int num);
  55. static int tls_bio_mbuf_read(BIO* b, char* buf, int num);
  56. static int tls_bio_mbuf_puts(BIO* b, const char* s);
  57. static long tls_bio_mbuf_ctrl(BIO* b, int cmd, long arg1, void* arg2);
  58. static BIO_METHOD tls_mbuf_method = {
  59. BIO_TYPE_TLS_MBUF, /* type */
  60. "sr_tls_mbuf", /* name */
  61. tls_bio_mbuf_write, /* write function */
  62. tls_bio_mbuf_read, /* read function */
  63. tls_bio_mbuf_puts, /* puts function */
  64. 0, /* gets function */
  65. tls_bio_mbuf_ctrl, /* ctrl function */
  66. tls_bio_mbuf_new, /* create(new) function */
  67. tls_bio_mbuf_free, /* destroy(free) function */
  68. 0 /* ctrl callback */
  69. };
  70. /** returns a custom tls_mbuf BIO. */
  71. BIO_METHOD* tls_BIO_mbuf(void)
  72. {
  73. return &tls_mbuf_method;
  74. }
  75. /** create an initialize a new tls_BIO_mbuf.
  76. * @return new BIO on success (!=0), 0 on error.
  77. */
  78. BIO* tls_BIO_new_mbuf(struct tls_mbuf* rd, struct tls_mbuf* wr)
  79. {
  80. BIO* ret;
  81. TLS_BIO_DBG("tls_BIO_new_mbuf called (%p, %p)\n", rd, wr);
  82. ret = BIO_new(tls_BIO_mbuf());
  83. if (unlikely(ret == 0))
  84. return 0;
  85. if (unlikely(tls_BIO_mbuf_set(ret, rd, wr) == 0)) {
  86. BIO_free(ret);
  87. return 0;
  88. }
  89. return ret;
  90. }
  91. /** sets the read and write mbuf for an mbuf BIO.
  92. * @return 1 on success, 0 on error (openssl BIO convention).
  93. */
  94. int tls_BIO_mbuf_set(BIO* b, struct tls_mbuf* rd, struct tls_mbuf* wr)
  95. {
  96. struct tls_bio_mbuf_data* d;
  97. TLS_BIO_DBG("tls_BIO_mbuf_set called (%p => %p, %p)\n", b, rd, wr);
  98. if (unlikely(b->ptr == 0)){
  99. BUG("null BIO ptr\n");
  100. return 0;
  101. }
  102. d = b->ptr;
  103. d->rd = rd;
  104. d->wr = wr;
  105. b->init = 1;
  106. return 1;
  107. }
  108. /** create a new BIO.
  109. * (internal openssl use via the tls_mbuf method)
  110. * @return 1 on success, 0 on error.
  111. */
  112. static int tls_bio_mbuf_new(BIO* b)
  113. {
  114. struct tls_bio_mbuf_data* d;
  115. TLS_BIO_DBG("tls_bio_mbuf_new called (%p)\n", b);
  116. b->init = 0; /* not initialized yet */
  117. b->num = 0;
  118. b->ptr = 0;
  119. b->flags = 0;
  120. d = OPENSSL_malloc(sizeof(*d));
  121. if (unlikely(d == 0))
  122. return 0;
  123. d->rd = 0;
  124. d->wr = 0;
  125. b->ptr = d;
  126. return 1;
  127. }
  128. /** destroy a tls mbuf BIO.
  129. * (internal openssl use via the tls_mbuf method)
  130. * @return 1 on success, 0 on error.
  131. */
  132. static int tls_bio_mbuf_free(BIO* b)
  133. {
  134. TLS_BIO_DBG("tls_bio_mbuf_free called (%p)\n", b);
  135. if (unlikely( b == 0))
  136. return 0;
  137. if (likely(b->ptr)){
  138. OPENSSL_free(b->ptr);
  139. b->ptr = 0;
  140. b->init = 0;
  141. }
  142. return 1;
  143. }
  144. /** read from a mbuf.
  145. * (internal openssl use via the tls_mbuf method)
  146. * @return bytes read on success (0< ret <=dst_len), -1 on empty buffer & sets
  147. * should_retry_read, -1 on some other errors (w/o should_retry_read set).
  148. */
  149. static int tls_bio_mbuf_read(BIO* b, char* dst, int dst_len)
  150. {
  151. struct tls_bio_mbuf_data* d;
  152. struct tls_mbuf* rd;
  153. int ret;
  154. ret = 0;
  155. if (likely(dst)) {
  156. d= b->ptr;
  157. BIO_clear_retry_flags(b);
  158. if (unlikely(d == 0 || d->rd->buf == 0)) {
  159. if (d == 0)
  160. BUG("tls_BIO_mbuf %p: read called with null b->ptr\n", b);
  161. else {
  162. /* this form of calling read with a null buffer is used
  163. as a shortcut when no data is available =>
  164. simulate EAGIAN/WANT_READ */
  165. TLS_BIO_DBG("read (%p, %p, %d) called with null read buffer"
  166. "(%p->%p) => simulating EAGAIN/WANT_READ\n",
  167. b, dst, dst_len, d, d->rd);
  168. BIO_set_retry_read(b);
  169. }
  170. return -1;
  171. }
  172. rd = d->rd;
  173. if (unlikely(rd->used == rd->pos && dst_len)) {
  174. /* mimic non-blocking read behaviour */
  175. TLS_BIO_DBG("read (%p, %p, %d) called with full rd (%d)"
  176. " => simulating EAGAIN/WANT_READ\n",
  177. b, dst, dst_len, rd->used);
  178. BIO_set_retry_read(b);
  179. return -1;
  180. }
  181. ret = MIN_int(rd->used - rd->pos, dst_len);
  182. /* copy data from rd.buf into dst */
  183. memcpy(dst, rd->buf+rd->pos, ret);
  184. TLS_BIO_DBG("read(%p, %p, %d) called with rd=%p pos=%d => %d bytes\n",
  185. b, dst, dst_len, rd->buf, rd->pos, ret);
  186. rd->pos += ret;
  187. /* if (unlikely(rd->pos < rd->used))
  188. BIO_set_retry_read(b);
  189. */
  190. }
  191. return ret;
  192. }
  193. /** write to a mbuf.
  194. * (internal openssl use via the tls_mbuf method)
  195. * @return bytes written on success (0<= ret <=src_len), -1 on error or buffer
  196. * full (in this case sets should_retry_write).
  197. */
  198. static int tls_bio_mbuf_write(BIO* b, const char* src, int src_len)
  199. {
  200. struct tls_bio_mbuf_data* d;
  201. struct tls_mbuf* wr;
  202. int ret;
  203. ret = 0;
  204. d= b->ptr;
  205. BIO_clear_retry_flags(b);
  206. if (unlikely(d == 0 || d->wr->buf == 0)) {
  207. if (d == 0)
  208. BUG("tls_BIO_mbuf %p: write called with null b->ptr\n", b);
  209. else {
  210. /* this form of calling write with a null buffer is used
  211. as a shortcut when no data is available =>
  212. simulate EAGAIN/WANT_WRITE */
  213. TLS_BIO_DBG("write (%p, %p, %d) called with null buffer"
  214. " => simulating WANT_WRITE\n", b, src, src_len);
  215. BIO_set_retry_write(b);
  216. }
  217. return -1;
  218. }
  219. wr = d->wr;
  220. if (unlikely(wr->size == wr->used && src_len)) {
  221. /* mimic non-blocking socket behaviour */
  222. TLS_BIO_DBG("write (%p, %p, %d) called with full wr buffer (%d)"
  223. " => simulating WANT_WRITE\n", b, src, src_len, wr->used);
  224. BIO_set_retry_write(b);
  225. return -1;
  226. }
  227. ret = MIN_int(wr->size - wr->used, src_len);
  228. memcpy(wr->buf + wr->used, src, ret);
  229. wr->used += ret;
  230. /* if (unlikely(ret < src_len))
  231. BIO_set_retry_write();
  232. */
  233. TLS_BIO_DBG("write called (%p, %p, %d) => %d\n", b, src, src_len, ret);
  234. return ret;
  235. }
  236. static long tls_bio_mbuf_ctrl(BIO* b, int cmd, long arg1, void* arg2)
  237. {
  238. long ret;
  239. ret=0;
  240. switch(cmd) {
  241. case BIO_C_SET_FD:
  242. case BIO_C_GET_FD:
  243. ret = -1; /* error, not supported */
  244. break;
  245. case BIO_CTRL_GET_CLOSE:
  246. case BIO_CTRL_SET_CLOSE:
  247. ret = 0;
  248. break;
  249. case BIO_CTRL_DUP:
  250. case BIO_CTRL_FLUSH:
  251. ret = 1;
  252. break;
  253. case BIO_CTRL_RESET:
  254. case BIO_C_FILE_SEEK:
  255. case BIO_C_FILE_TELL:
  256. case BIO_CTRL_INFO:
  257. case BIO_CTRL_PENDING:
  258. case BIO_CTRL_WPENDING:
  259. default:
  260. ret = 0;
  261. break;
  262. }
  263. TLS_BIO_DBG("ctrl called (%p, %d, %ld, %p) => %ld\n",
  264. b, cmd, arg1, arg2, ret);
  265. return ret;
  266. }
  267. static int tls_bio_mbuf_puts(BIO* b, const char* s)
  268. {
  269. int len;
  270. TLS_BIO_DBG("puts called (%p, %s)\n", b, s);
  271. len=strlen(s);
  272. return tls_bio_mbuf_write(b, s, len);
  273. }
  274. /* vi: set ts=4 sw=4 tw=79:ai:cindent: */