00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "tls_bio.h"
00032 #include "../../compiler_opt.h"
00033 #include "../../dprint.h"
00034 #include "../../ut.h"
00035 #include "tls_cfg.h"
00036
00037
00038
00039 #define BIO_TYPE_TLS_MBUF (BIO_TYPE_SOURCE_SINK | 0xf2)
00040
00041
00042 #ifdef NO_TLS_BIO_DEBUG
00043 #undef TLS_BIO_DEBUG
00044 #endif
00045 #ifdef TLS_BIO_DEBUG
00046 #ifdef __SUNPRO_C
00047 #define TLS_BIO_DBG(...) \
00048 LOG_(DEFAULT_FACILITY, cfg_get(tls, tls_cfg, debug),\
00049 "tls_BIO: " LOC_INFO, __VA_ARGS__)
00050 #else
00051 #define TLS_BIO_DBG(args...) \
00052 LOG_(DEFAULT_FACILITY, cfg_get(tls, tls_cfg, debug),\
00053 "tls_BIO: " LOC_INFO, ## args)
00054 #endif
00055 #else
00056 #ifdef __SUNPRO_C
00057 #define TLS_BIO_DBG(...)
00058 #else
00059 #define TLS_BIO_DBG(fmt, args...)
00060 #endif
00061 #endif
00062
00063
00064 static int tls_bio_mbuf_new(BIO* b);
00065 static int tls_bio_mbuf_free(BIO* b);
00066 static int tls_bio_mbuf_write(BIO* b, const char* buf, int num);
00067 static int tls_bio_mbuf_read(BIO* b, char* buf, int num);
00068 static int tls_bio_mbuf_puts(BIO* b, const char* s);
00069 static long tls_bio_mbuf_ctrl(BIO* b, int cmd, long arg1, void* arg2);
00070
00071
00072 static BIO_METHOD tls_mbuf_method = {
00073 BIO_TYPE_TLS_MBUF,
00074 "sr_tls_mbuf",
00075 tls_bio_mbuf_write,
00076 tls_bio_mbuf_read,
00077 tls_bio_mbuf_puts,
00078 0,
00079 tls_bio_mbuf_ctrl,
00080 tls_bio_mbuf_new,
00081 tls_bio_mbuf_free,
00082 0
00083 };
00084
00085
00087 BIO_METHOD* tls_BIO_mbuf(void)
00088 {
00089 return &tls_mbuf_method;
00090 }
00091
00092
00093
00097 BIO* tls_BIO_new_mbuf(struct tls_mbuf* rd, struct tls_mbuf* wr)
00098 {
00099 BIO* ret;
00100
00101 TLS_BIO_DBG("tls_BIO_new_mbuf called (%p, %p)\n", rd, wr);
00102 ret = BIO_new(tls_BIO_mbuf());
00103 if (unlikely(ret == 0))
00104 return 0;
00105 if (unlikely(tls_BIO_mbuf_set(ret, rd, wr) == 0)) {
00106 BIO_free(ret);
00107 return 0;
00108 }
00109 return ret;
00110 }
00111
00112
00113
00117 int tls_BIO_mbuf_set(BIO* b, struct tls_mbuf* rd, struct tls_mbuf* wr)
00118 {
00119 struct tls_bio_mbuf_data* d;
00120
00121 TLS_BIO_DBG("tls_BIO_mbuf_set called (%p => %p, %p)\n", b, rd, wr);
00122 if (unlikely(b->ptr == 0)){
00123 BUG("null BIO ptr\n");
00124 return 0;
00125 }
00126 d = b->ptr;
00127 d->rd = rd;
00128 d->wr = wr;
00129 b->init = 1;
00130 return 1;
00131 }
00132
00133
00134
00139 static int tls_bio_mbuf_new(BIO* b)
00140 {
00141 struct tls_bio_mbuf_data* d;
00142
00143 TLS_BIO_DBG("tls_bio_mbuf_new called (%p)\n", b);
00144 b->init = 0;
00145 b->num = 0;
00146 b->ptr = 0;
00147 b->flags = 0;
00148 d = OPENSSL_malloc(sizeof(*d));
00149 if (unlikely(d == 0))
00150 return 0;
00151 d->rd = 0;
00152 d->wr = 0;
00153 b->ptr = d;
00154 return 1;
00155 }
00156
00157
00158
00163 static int tls_bio_mbuf_free(BIO* b)
00164 {
00165 TLS_BIO_DBG("tls_bio_mbuf_free called (%p)\n", b);
00166 if (unlikely( b == 0))
00167 return 0;
00168 if (likely(b->ptr)){
00169 OPENSSL_free(b->ptr);
00170 b->ptr = 0;
00171 b->init = 0;
00172 }
00173 return 1;
00174 }
00175
00176
00177
00183 static int tls_bio_mbuf_read(BIO* b, char* dst, int dst_len)
00184 {
00185 struct tls_bio_mbuf_data* d;
00186 struct tls_mbuf* rd;
00187 int ret;
00188
00189 ret = 0;
00190 if (likely(dst)) {
00191 d= b->ptr;
00192 BIO_clear_retry_flags(b);
00193 if (unlikely(d == 0 || d->rd->buf == 0)) {
00194 if (d == 0)
00195 BUG("tls_BIO_mbuf %p: read called with null b->ptr\n", b);
00196 else {
00197
00198
00199
00200 TLS_BIO_DBG("read (%p, %p, %d) called with null read buffer"
00201 "(%p->%p) => simulating EAGAIN/WANT_READ\n",
00202 b, dst, dst_len, d, d->rd);
00203 BIO_set_retry_read(b);
00204 }
00205 return -1;
00206 }
00207 rd = d->rd;
00208 if (unlikely(rd->used == rd->pos && dst_len)) {
00209
00210 TLS_BIO_DBG("read (%p, %p, %d) called with full rd (%d)"
00211 " => simulating EAGAIN/WANT_READ\n",
00212 b, dst, dst_len, rd->used);
00213 BIO_set_retry_read(b);
00214 return -1;
00215 }
00216 ret = MIN_int(rd->used - rd->pos, dst_len);
00217
00218 memcpy(dst, rd->buf+rd->pos, ret);
00219 TLS_BIO_DBG("read(%p, %p, %d) called with rd=%p pos=%d => %d bytes\n",
00220 b, dst, dst_len, rd->buf, rd->pos, ret);
00221 rd->pos += ret;
00222
00223
00224
00225 }
00226 return ret;
00227 }
00228
00229
00230
00236 static int tls_bio_mbuf_write(BIO* b, const char* src, int src_len)
00237 {
00238 struct tls_bio_mbuf_data* d;
00239 struct tls_mbuf* wr;
00240 int ret;
00241
00242 ret = 0;
00243 d= b->ptr;
00244 BIO_clear_retry_flags(b);
00245 if (unlikely(d == 0 || d->wr->buf == 0)) {
00246 if (d == 0)
00247 BUG("tls_BIO_mbuf %p: write called with null b->ptr\n", b);
00248 else {
00249
00250
00251
00252 TLS_BIO_DBG("write (%p, %p, %d) called with null buffer"
00253 " => simulating WANT_WRITE\n", b, src, src_len);
00254 BIO_set_retry_write(b);
00255 }
00256 return -1;
00257 }
00258 wr = d->wr;
00259 if (unlikely(wr->size == wr->used && src_len)) {
00260
00261 TLS_BIO_DBG("write (%p, %p, %d) called with full wr buffer (%d)"
00262 " => simulating WANT_WRITE\n", b, src, src_len, wr->used);
00263 BIO_set_retry_write(b);
00264 return -1;
00265 }
00266 ret = MIN_int(wr->size - wr->used, src_len);
00267 memcpy(wr->buf + wr->used, src, ret);
00268 wr->used += ret;
00269
00270
00271
00272 TLS_BIO_DBG("write called (%p, %p, %d) => %d\n", b, src, src_len, ret);
00273 return ret;
00274 }
00275
00276
00277
00278 static long tls_bio_mbuf_ctrl(BIO* b, int cmd, long arg1, void* arg2)
00279 {
00280 long ret;
00281 ret=0;
00282 switch(cmd) {
00283 case BIO_C_SET_FD:
00284 case BIO_C_GET_FD:
00285 ret = -1;
00286 break;
00287 case BIO_CTRL_GET_CLOSE:
00288 case BIO_CTRL_SET_CLOSE:
00289 ret = 0;
00290 break;
00291 case BIO_CTRL_DUP:
00292 case BIO_CTRL_FLUSH:
00293 ret = 1;
00294 break;
00295 case BIO_CTRL_RESET:
00296 case BIO_C_FILE_SEEK:
00297 case BIO_C_FILE_TELL:
00298 case BIO_CTRL_INFO:
00299 case BIO_CTRL_PENDING:
00300 case BIO_CTRL_WPENDING:
00301 default:
00302 ret = 0;
00303 break;
00304 }
00305 TLS_BIO_DBG("ctrl called (%p, %d, %ld, %p) => %ld\n",
00306 b, cmd, arg1, arg2, ret);
00307 return ret;
00308 }
00309
00310
00311
00312 static int tls_bio_mbuf_puts(BIO* b, const char* s)
00313 {
00314 int len;
00315
00316 TLS_BIO_DBG("puts called (%p, %s)\n", b, s);
00317 len=strlen(s);
00318 return tls_bio_mbuf_write(b, s, len);
00319 }
00320
00321
00322
00323