Fix bio callback backward compatibility
[openssl.git] / crypto / bio / bio_lib.c
index 2bd337c36248db9e7926033ea97a770fec667cb0..95eef7d4bf5b85da2a2ba46f0887fd2577bea64d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -34,9 +34,8 @@ static long bio_call_callback(BIO *b, int oper, const char *argp, size_t len,
     long ret;
     int bareoper;
 
-    if (b->callback_ex != NULL) {
+    if (b->callback_ex != NULL)
         return b->callback_ex(b, oper, argp, len, argi, argl, inret, processed);
-    }
 
     /* Strip off any BIO_CB_RETURN flag */
     bareoper = oper & ~BIO_CB_RETURN;
@@ -51,17 +50,17 @@ static long bio_call_callback(BIO *b, int oper, const char *argp, size_t len,
             return -1;
 
         argi = (int)len;
+    }
 
-        if (inret && (oper & BIO_CB_RETURN)) {
-            if (*processed > INT_MAX)
-                return -1;
-            inret = *processed;
-        }
+    if (inret && (oper & BIO_CB_RETURN) && bareoper != BIO_CB_CTRL) {
+        if (*processed > INT_MAX)
+            return -1;
+        inret = *processed;
     }
 
     ret = b->callback(b, oper, argp, argi, argl, inret);
 
-    if (ret >= 0 && (HAS_LEN_OPER(bareoper) || bareoper == BIO_CB_PUTS)) {
+    if (ret >= 0 && (oper & BIO_CB_RETURN) && bareoper != BIO_CB_CTRL) {
         *processed = (size_t)ret;
         ret = 1;
     }
@@ -75,7 +74,7 @@ BIO *BIO_new(const BIO_METHOD *method)
 
     if (bio == NULL) {
         BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE);
-        return (NULL);
+        return NULL;
     }
 
     bio->method = method;
@@ -98,6 +97,8 @@ BIO *BIO_new(const BIO_METHOD *method)
         CRYPTO_THREAD_lock_free(bio->lock);
         goto err;
     }
+    if (method->create == NULL)
+        bio->init = 1;
 
     return bio;
 
@@ -113,7 +114,7 @@ int BIO_free(BIO *a)
     if (a == NULL)
         return 0;
 
-    if (CRYPTO_atomic_add(&a->references, -1, &ret, a->lock) <= 0)
+    if (CRYPTO_DOWN_REF(&a->references, &ret, a->lock) <= 0)
         return 0;
 
     REF_PRINT_COUNT("BIO", a);
@@ -178,7 +179,7 @@ int BIO_up_ref(BIO *a)
 {
     int i;
 
-    if (CRYPTO_atomic_add(&a->references, 1, &i, a->lock) <= 0)
+    if (CRYPTO_UP_REF(&a->references, &i, a->lock) <= 0)
         return 0;
 
     REF_PRINT_COUNT("BIO", a);
@@ -258,7 +259,7 @@ static int bio_read_intern(BIO *b, void *data, size_t dlen, size_t *readbytes)
 
     if ((b->callback != NULL || b->callback_ex != NULL) &&
         ((ret = (int)bio_call_callback(b, BIO_CB_READ, data, dlen, 0, 0L, 1L,
-                                       readbytes)) <= 0))
+                                       NULL)) <= 0))
         return ret;
 
     if (!b->init) {
@@ -269,7 +270,7 @@ static int bio_read_intern(BIO *b, void *data, size_t dlen, size_t *readbytes)
     ret = b->method->bread(b, data, dlen, readbytes);
 
     if (ret > 0)
-        b->num_read += (uint64_t)*read;
+        b->num_read += (uint64_t)*readbytes;
 
     if (b->callback != NULL || b->callback_ex != NULL)
         ret = (int)bio_call_callback(b, BIO_CB_READ | BIO_CB_RETURN, data,
@@ -295,7 +296,7 @@ int BIO_read(BIO *b, void *data, int dlen)
     ret = bio_read_intern(b, data, (size_t)dlen, &readbytes);
 
     if (ret > 0) {
-        /* *readbytes should always be <= outl */
+        /* *readbytes should always be <= dlen */
         ret = (int)readbytes;
     }
 
@@ -331,7 +332,7 @@ static int bio_write_intern(BIO *b, const void *data, size_t dlen,
 
     if ((b->callback != NULL || b->callback_ex != NULL) &&
         ((ret = (int)bio_call_callback(b, BIO_CB_WRITE, data, dlen, 0, 0L, 1L,
-                                       written)) <= 0))
+                                       NULL)) <= 0))
         return ret;
 
     if (!b->init) {
@@ -362,7 +363,7 @@ int BIO_write(BIO *b, const void *data, int dlen)
     ret = bio_write_intern(b, data, (size_t)dlen, &written);
 
     if (ret > 0) {
-        /* *written should always be <= inl */
+        /* *written should always be <= dlen */
         ret = (int)written;
     }
 
@@ -383,7 +384,7 @@ int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written)
     return ret;
 }
 
-int BIO_puts(BIO *b, const char *in)
+int BIO_puts(BIO *b, const char *buf)
 {
     int ret;
     size_t written = 0;
@@ -394,7 +395,7 @@ int BIO_puts(BIO *b, const char *in)
     }
 
     if (b->callback != NULL || b->callback_ex != NULL) {
-        ret = (int)bio_call_callback(b, BIO_CB_PUTS, in, 0, 0, 0L, 1L, NULL);
+        ret = (int)bio_call_callback(b, BIO_CB_PUTS, buf, 0, 0, 0L, 1L, NULL);
         if (ret <= 0)
             return ret;
     }
@@ -404,7 +405,7 @@ int BIO_puts(BIO *b, const char *in)
         return -2;
     }
 
-    ret = b->method->bputs(b, in);
+    ret = b->method->bputs(b, buf);
 
     if (ret > 0) {
         b->num_write += (uint64_t)ret;
@@ -413,7 +414,7 @@ int BIO_puts(BIO *b, const char *in)
     }
 
     if (b->callback != NULL || b->callback_ex != NULL)
-        ret = (int)bio_call_callback(b, BIO_CB_PUTS | BIO_CB_RETURN, in, 0, 0,
+        ret = (int)bio_call_callback(b, BIO_CB_PUTS | BIO_CB_RETURN, buf, 0, 0,
                                      0L, ret, &written);
 
     if (ret > 0) {
@@ -428,33 +429,33 @@ int BIO_puts(BIO *b, const char *in)
     return ret;
 }
 
-int BIO_gets(BIO *b, char *out, int outl)
+int BIO_gets(BIO *b, char *buf, int size)
 {
     int ret;
     size_t readbytes = 0;
 
     if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) {
         BIOerr(BIO_F_BIO_GETS, BIO_R_UNSUPPORTED_METHOD);
-        return (-2);
+        return -2;
     }
 
-    if (outl < 0) {
+    if (size < 0) {
         BIOerr(BIO_F_BIO_GETS, BIO_R_INVALID_ARGUMENT);
         return 0;
     }
 
     if (b->callback != NULL || b->callback_ex != NULL) {
-        ret = (int)bio_call_callback(b, BIO_CB_GETS, out, outl, 0, 0L, 1, NULL);
+        ret = (int)bio_call_callback(b, BIO_CB_GETS, buf, size, 0, 0L, 1, NULL);
         if (ret <= 0)
             return ret;
     }
 
     if (!b->init) {
         BIOerr(BIO_F_BIO_GETS, BIO_R_UNINITIALIZED);
-        return (-2);
+        return -2;
     }
 
-    ret = b->method->bgets(b, out, outl);
+    ret = b->method->bgets(b, buf, size);
 
     if (ret > 0) {
         readbytes = ret;
@@ -462,12 +463,12 @@ int BIO_gets(BIO *b, char *out, int outl)
     }
 
     if (b->callback != NULL || b->callback_ex != NULL)
-        ret = (int)bio_call_callback(b, BIO_CB_GETS | BIO_CB_RETURN, out, outl,
+        ret = (int)bio_call_callback(b, BIO_CB_GETS | BIO_CB_RETURN, buf, size,
                                      0, 0L, ret, &readbytes);
 
     if (ret > 0) {
         /* Shouldn't happen */
-        if (readbytes > (size_t)outl)
+        if (readbytes > (size_t)size)
             ret = -1;
         else
             ret = (int)readbytes;
@@ -493,7 +494,7 @@ long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
     int i;
 
     i = iarg;
-    return (BIO_ctrl(b, cmd, larg, (char *)&i));
+    return BIO_ctrl(b, cmd, larg, (char *)&i);
 }
 
 void *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
@@ -501,9 +502,9 @@ void *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
     void *p = NULL;
 
     if (BIO_ctrl(b, cmd, larg, (char *)&p) <= 0)
-        return (NULL);
+        return NULL;
     else
-        return (p);
+        return p;
 }
 
 long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
@@ -533,18 +534,17 @@ long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
     return ret;
 }
 
-long BIO_callback_ctrl(BIO *b, int cmd,
-                       void (*fp) (struct bio_st *, int, const char *, int,
-                                   long, long))
+long BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
 {
     long ret;
 
     if (b == NULL)
-        return (0);
+        return 0;
 
-    if ((b->method == NULL) || (b->method->callback_ctrl == NULL)) {
+    if ((b->method == NULL) || (b->method->callback_ctrl == NULL)
+            || (cmd != BIO_CTRL_SET_CALLBACK)) {
         BIOerr(BIO_F_BIO_CALLBACK_CTRL, BIO_R_UNSUPPORTED_METHOD);
-        return (-2);
+        return -2;
     }
 
     if (b->callback != NULL || b->callback_ex != NULL) {
@@ -584,7 +584,7 @@ BIO *BIO_push(BIO *b, BIO *bio)
     BIO *lb;
 
     if (b == NULL)
-        return (bio);
+        return bio;
     lb = b;
     while (lb->next_bio != NULL)
         lb = lb->next_bio;
@@ -593,7 +593,7 @@ BIO *BIO_push(BIO *b, BIO *bio)
         bio->prev_bio = lb;
     /* called to do internal processing */
     BIO_ctrl(b, BIO_CTRL_PUSH, 0, lb);
-    return (b);
+    return b;
 }
 
 /* Remove the first and return the rest */
@@ -602,7 +602,7 @@ BIO *BIO_pop(BIO *b)
     BIO *ret;
 
     if (b == NULL)
-        return (NULL);
+        return NULL;
     ret = b->next_bio;
 
     BIO_ctrl(b, BIO_CTRL_POP, 0, b);
@@ -614,7 +614,7 @@ BIO *BIO_pop(BIO *b)
 
     b->next_bio = NULL;
     b->prev_bio = NULL;
-    return (ret);
+    return ret;
 }
 
 BIO *BIO_get_retry_BIO(BIO *bio, int *reason)
@@ -632,12 +632,12 @@ BIO *BIO_get_retry_BIO(BIO *bio, int *reason)
     }
     if (reason != NULL)
         *reason = last->retry_reason;
-    return (last);
+    return last;
 }
 
 int BIO_get_retry_reason(BIO *bio)
 {
-    return (bio->retry_reason);
+    return bio->retry_reason;
 }
 
 void BIO_set_retry_reason(BIO *bio, int reason)
@@ -658,13 +658,13 @@ BIO *BIO_find_type(BIO *bio, int type)
 
             if (!mask) {
                 if (mt & type)
-                    return (bio);
+                    return bio;
             } else if (mt == type)
-                return (bio);
+                return bio;
         }
         bio = bio->next_bio;
     } while (bio != NULL);
-    return (NULL);
+    return NULL;
 }
 
 BIO *BIO_next(BIO *b)
@@ -732,11 +732,11 @@ BIO *BIO_dup_chain(BIO *in)
             eoc = new_bio;
         }
     }
-    return (ret);
+    return ret;
  err:
     BIO_free_all(ret);
 
-    return (NULL);
+    return NULL;
 }
 
 void BIO_copy_next_retry(BIO *b)
@@ -747,12 +747,12 @@ void BIO_copy_next_retry(BIO *b)
 
 int BIO_set_ex_data(BIO *bio, int idx, void *data)
 {
-    return (CRYPTO_set_ex_data(&(bio->ex_data), idx, data));
+    return CRYPTO_set_ex_data(&(bio->ex_data), idx, data);
 }
 
 void *BIO_get_ex_data(BIO *bio, int idx)
 {
-    return (CRYPTO_get_ex_data(&(bio->ex_data), idx));
+    return CRYPTO_get_ex_data(&(bio->ex_data), idx);
 }
 
 uint64_t BIO_number_read(BIO *bio)