[openssl] master update

Richard Levitte levitte at openssl.org
Wed Dec 18 18:42:50 UTC 2019


The branch master has been updated
       via  51a7c4b5f2a0b2d0f6bc0c87ec2ee44b9697dc78 (commit)
       via  f1299839b7763d293925d57b28f533ab24c084ad (commit)
       via  0e79d20f1e9f9e32bfe45eb3760cb233fa8dfa5e (commit)
       via  e79ae962fbed99cf80feb32b326f701778ca7434 (commit)
       via  319cee9e2fc6fcf6ad865564eccdac4c55e92c0a (commit)
       via  a0848daee50b30f441813ecc90042c6af14c62aa (commit)
      from  8913378a552e470c66277c47b19699f20b84aa3b (commit)


- Log -----------------------------------------------------------------
commit 51a7c4b5f2a0b2d0f6bc0c87ec2ee44b9697dc78
Author: Richard Levitte <levitte at openssl.org>
Date:   Thu Dec 12 14:51:59 2019 +0100

    TEST: Add test recipe and help program to test BIO_f_prefix()
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/10531)

commit f1299839b7763d293925d57b28f533ab24c084ad
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Nov 27 18:35:48 2019 +0100

    EVP: Adapt EVP_PKEY_print_ routines to use BIO_f_prefix()
    
    We take the opportunity to refactor EVP_PKEY_print_public,
    EVP_PKEY_print_private, EVP_PKEY_print_params to lessen the amount of
    code copying.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/10531)

commit 0e79d20f1e9f9e32bfe45eb3760cb233fa8dfa5e
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Nov 27 17:58:01 2019 +0100

    ASN1: Adapt ASN.1 output routines to use BIO_f_prefix()
    
    We modify asn1_print_info() to print the full line.  It pushes a
    BIO_f_prefix() BIO to the given |bp| if it can't detect that it's
    already present, then uses both the prefix and indent settings to get
    formatting right.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/10531)

commit e79ae962fbed99cf80feb32b326f701778ca7434
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Nov 27 16:13:12 2019 +0100

    APPS & TEST: Adapt to use the new BIO_f_prefix()
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/10531)

commit 319cee9e2fc6fcf6ad865564eccdac4c55e92c0a
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Nov 27 16:02:33 2019 +0100

    BIO: Add BIO_f_prefix(), a text line prefixing filter
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/10531)

commit a0848daee50b30f441813ecc90042c6af14c62aa
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Nov 27 16:01:32 2019 +0100

    crypto/bio/build.info: split the source files in categories
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/10531)

-----------------------------------------------------------------------

Summary of changes:
 apps/include/apps.h                           |  14 --
 apps/lib/apps.c                               |  15 +-
 apps/lib/build.info                           |   2 +-
 apps/openssl.c                                |  15 +-
 crypto/asn1/asn1_par.c                        |  62 +++---
 {apps/lib => crypto/bio}/bf_prefix.c          | 106 ++++++----
 crypto/bio/build.info                         |  20 +-
 crypto/evp/p_lib.c                            | 110 +++++++----
 doc/man3/BIO_f_prefix.pod                     |  70 +++++++
 include/openssl/bio.h                         |  11 ++
 test/README                                   |   5 +-
 test/bio_prefix_text.c                        | 267 ++++++++++++++++++++++++++
 test/build.info                               |   7 +-
 test/recipes/61-test_bio_prefix.t             |  55 ++++++
 test/recipes/61-test_bio_prefix_data/args1.pl |   6 +
 test/recipes/61-test_bio_prefix_data/args2.pl |   3 +
 test/recipes/61-test_bio_prefix_data/in1.txt  |   1 +
 test/recipes/61-test_bio_prefix_data/in2.txt  |   1 +
 test/recipes/61-test_bio_prefix_data/out1.txt |   1 +
 test/recipes/61-test_bio_prefix_data/out2.txt |   1 +
 util/libcrypto.num                            |   1 +
 util/other.syms                               |   3 +
 22 files changed, 626 insertions(+), 150 deletions(-)
 rename {apps/lib => crypto/bio}/bf_prefix.c (61%)
 create mode 100644 doc/man3/BIO_f_prefix.pod
 create mode 100644 test/bio_prefix_text.c
 create mode 100644 test/recipes/61-test_bio_prefix.t
 create mode 100644 test/recipes/61-test_bio_prefix_data/args1.pl
 create mode 100644 test/recipes/61-test_bio_prefix_data/args2.pl
 create mode 100644 test/recipes/61-test_bio_prefix_data/in1.txt
 create mode 100644 test/recipes/61-test_bio_prefix_data/in2.txt
 create mode 100644 test/recipes/61-test_bio_prefix_data/out1.txt
 create mode 100644 test/recipes/61-test_bio_prefix_data/out2.txt

diff --git a/apps/include/apps.h b/apps/include/apps.h
index 21a2a90544..c33a98772b 100644
--- a/apps/include/apps.h
+++ b/apps/include/apps.h
@@ -58,20 +58,6 @@ extern const unsigned char tls13_aes128gcmsha256_id[];
 extern const unsigned char tls13_aes256gcmsha384_id[];
 extern BIO_ADDR *ourpeer;
 
-BIO_METHOD *apps_bf_prefix(void);
-/*
- * The control used to set the prefix with BIO_ctrl()
- * We make it high enough so the chance of ever clashing with the BIO library
- * remains unlikely for the foreseeable future and beyond.
- */
-#define PREFIX_CTRL_SET_PREFIX  (1 << 15)
-/*
- * apps_bf_prefix() returns a dynamically created BIO_METHOD, which we
- * need to destroy at some point.  When created internally, it's stored
- * in an internal pointer which can be freed with the following function
- */
-void destroy_prefix_method(void);
-
 BIO *dup_bio_in(int format);
 BIO *dup_bio_out(int format);
 BIO *dup_bio_err(int format);
diff --git a/apps/lib/apps.c b/apps/lib/apps.c
index 8b840bb2a1..3a18cd007c 100644
--- a/apps/lib/apps.c
+++ b/apps/lib/apps.c
@@ -2324,8 +2324,8 @@ BIO *dup_bio_out(int format)
 
     if (FMT_istext(format)
         && (prefix = getenv("HARNESS_OSSL_PREFIX")) != NULL) {
-        b = BIO_push(BIO_new(apps_bf_prefix()), b);
-        BIO_ctrl(b, PREFIX_CTRL_SET_PREFIX, 0, prefix);
+        b = BIO_push(BIO_new(BIO_f_prefix()), b);
+        BIO_set_prefix(b, prefix);
     }
 
     return b;
@@ -2342,17 +2342,6 @@ BIO *dup_bio_err(int format)
     return b;
 }
 
-/*
- * Because the prefix method is created dynamically, we must also be able
- * to destroy it.
- */
-void destroy_prefix_method(void)
-{
-    BIO_METHOD *prefix_method = apps_bf_prefix();
-    BIO_meth_free(prefix_method);
-    prefix_method = NULL;
-}
-
 void unbuffer(FILE *fp)
 {
 /*
diff --git a/apps/lib/build.info b/apps/lib/build.info
index 7a2536af24..3f68a2ed35 100644
--- a/apps/lib/build.info
+++ b/apps/lib/build.info
@@ -9,7 +9,7 @@ ENDIF
 
 # Source for libapps
 $LIBAPPSSRC=apps.c apps_ui.c opt.c fmt.c s_cb.c s_socket.c app_rand.c \
-        bf_prefix.c columns.c app_params.c names.c
+        columns.c app_params.c names.c
 
 IF[{- !$disabled{apps} -}]
   LIBS{noinst}=../libapps.a
diff --git a/apps/openssl.c b/apps/openssl.c
index d60267d742..00ad9ca0bd 100644
--- a/apps/openssl.c
+++ b/apps/openssl.c
@@ -116,8 +116,7 @@ static size_t internal_trace_cb(const char *buf, size_t cnt,
                      hex == NULL ? "<null>" : hex,
                      OSSL_trace_get_category_name(category));
         OPENSSL_free(hex);
-        BIO_ctrl(trace_data->bio, PREFIX_CTRL_SET_PREFIX,
-                 strlen(buffer), buffer);
+        BIO_set_prefix(trace_data->bio, buffer);
         break;
     case OSSL_TRACE_CTRL_WRITE:
         if (!ossl_assert(trace_data->ingroup))
@@ -130,7 +129,7 @@ static size_t internal_trace_cb(const char *buf, size_t cnt,
             return 0;
         trace_data->ingroup = 0;
 
-        BIO_ctrl(trace_data->bio, PREFIX_CTRL_SET_PREFIX, 0, NULL);
+        BIO_set_prefix(trace_data->bio, NULL);
 
         break;
     }
@@ -162,8 +161,7 @@ static void setup_trace_category(int category)
     if (OSSL_trace_enabled(category))
         return;
 
-    channel = BIO_push(BIO_new(apps_bf_prefix()),
-                       dup_bio_err(FORMAT_TEXT));
+    channel = BIO_push(BIO_new(BIO_f_prefix()), dup_bio_err(FORMAT_TEXT));
     trace_data = OPENSSL_zalloc(sizeof(*trace_data));
 
     if (trace_data == NULL
@@ -247,13 +245,6 @@ int main(int argc, char *argv[])
     win32_utf8argv(&argc, &argv);
 #endif
 
-    /*
-     * We use the prefix method to get the trace output we want.  Since some
-     * trace outputs happen with OPENSSL_cleanup(), which is run automatically
-     * after exit(), we need to destroy the prefix method as late as possible.
-     */
-    atexit(destroy_prefix_method);
-
 #ifndef OPENSSL_NO_TRACE
     setup_trace(getenv("OPENSSL_TRACE"));
 #endif
diff --git a/crypto/asn1/asn1_par.c b/crypto/asn1/asn1_par.c
index f722bed0b5..eaba666cf2 100644
--- a/crypto/asn1/asn1_par.c
+++ b/crypto/asn1/asn1_par.c
@@ -17,25 +17,44 @@
 #define ASN1_PARSE_MAXDEPTH 128
 #endif
 
-static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
-                           int indent);
 static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
                        int offset, int depth, int indent, int dump);
-static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
-                           int indent)
+static int asn1_print_info(BIO *bp, long offset, int depth, int hl, long len,
+                           int tag, int xclass, int constructed, int indent)
 {
-    static const char fmt[] = "%-18s";
     char str[128];
     const char *p;
+    int pop_f_prefix = 0;
+    long saved_indent = -1;
+    int i = 0;
 
     if (constructed & V_ASN1_CONSTRUCTED)
         p = "cons: ";
     else
         p = "prim: ";
-    if (BIO_write(bp, p, 6) < 6)
+    if (constructed != (V_ASN1_CONSTRUCTED | 1)) {
+        if (BIO_snprintf(str, sizeof(str), "%5ld:d=%-2d hl=%ld l=%4ld %s",
+                         offset, depth, (long)hl, len, p) <= 0)
+            goto err;
+    } else {
+        if (BIO_snprintf(str, sizeof(str), "%5ld:d=%-2d hl=%ld l=inf  %s",
+                         offset, depth, (long)hl, p) <= 0)
+            goto err;
+    }
+    if (BIO_set_prefix(bp, str) <= 0) {
+        if ((bp = BIO_push(BIO_new(BIO_f_prefix()), bp)) == NULL)
+            goto err;
+        pop_f_prefix = 1;
+    }
+    saved_indent = BIO_get_indent(bp);
+    if (BIO_set_prefix(bp, str) <= 0
+        || BIO_set_indent(bp, indent) < 0)
         goto err;
-    BIO_indent(bp, indent, 128);
 
+    /*
+     * BIO_set_prefix made a copy of |str|, so we can safely use it for
+     * something else, ASN.1 tag printout.
+     */
     p = str;
     if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
         BIO_snprintf(str, sizeof(str), "priv [ %d ] ", tag);
@@ -48,11 +67,17 @@ static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
     else
         p = ASN1_tag2str(tag);
 
-    if (BIO_printf(bp, fmt, p) <= 0)
-        goto err;
-    return 1;
+    i = (BIO_printf(bp, "%-18s", p) > 0);
  err:
-    return 0;
+    if (saved_indent >= 0)
+        BIO_set_indent(bp, saved_indent);
+    if (pop_f_prefix) {
+        BIO *next = BIO_pop(bp);
+
+        BIO_free(bp);
+        bp = next;
+    }
+    return i;
 }
 
 int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent)
@@ -100,19 +125,8 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
         /*
          * if j == 0x21 it is a constructed indefinite length object
          */
-        if (BIO_printf(bp, "%5ld:", (long)offset + (long)(op - *pp))
-            <= 0)
-            goto end;
-
-        if (j != (V_ASN1_CONSTRUCTED | 1)) {
-            if (BIO_printf(bp, "d=%-2d hl=%ld l=%4ld ",
-                           depth, (long)hl, len) <= 0)
-                goto end;
-        } else {
-            if (BIO_printf(bp, "d=%-2d hl=%ld l=inf  ", depth, (long)hl) <= 0)
-                goto end;
-        }
-        if (!asn1_print_info(bp, tag, xclass, j, (indent) ? depth : 0))
+        if (!asn1_print_info(bp, (long)offset + (long)(op - *pp), depth,
+                             hl, len, tag, xclass, j, (indent) ? depth : 0))
             goto end;
         if (j & V_ASN1_CONSTRUCTED) {
             const unsigned char *sp = p;
diff --git a/apps/lib/bf_prefix.c b/crypto/bio/bf_prefix.c
similarity index 61%
rename from apps/lib/bf_prefix.c
rename to crypto/bio/bf_prefix.c
index 8cedca90ce..5727c14950 100644
--- a/apps/lib/bf_prefix.c
+++ b/crypto/bio/bf_prefix.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2018-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -10,8 +10,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
-#include <openssl/bio.h>
-#include "apps.h"
+#include "bio_local.h"
 
 static int prefix_write(BIO *b, const char *out, size_t outl,
                         size_t *numwritten);
@@ -23,31 +22,31 @@ static int prefix_create(BIO *b);
 static int prefix_destroy(BIO *b);
 static long prefix_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp);
 
-static BIO_METHOD *prefix_meth = NULL;
-
-BIO_METHOD *apps_bf_prefix(void)
+static const BIO_METHOD prefix_meth = {
+    BIO_TYPE_BUFFER,
+    "prefix",
+    prefix_write,
+    NULL,
+    prefix_read,
+    NULL,
+    prefix_puts,
+    prefix_gets,
+    prefix_ctrl,
+    prefix_create,
+    prefix_destroy,
+    prefix_callback_ctrl,
+};
+
+const BIO_METHOD *BIO_f_prefix(void)
 {
-    if (prefix_meth == NULL) {
-        if ((prefix_meth =
-             BIO_meth_new(BIO_TYPE_FILTER, "Prefix filter")) == NULL
-            || !BIO_meth_set_create(prefix_meth, prefix_create)
-            || !BIO_meth_set_destroy(prefix_meth, prefix_destroy)
-            || !BIO_meth_set_write_ex(prefix_meth, prefix_write)
-            || !BIO_meth_set_read_ex(prefix_meth, prefix_read)
-            || !BIO_meth_set_puts(prefix_meth, prefix_puts)
-            || !BIO_meth_set_gets(prefix_meth, prefix_gets)
-            || !BIO_meth_set_ctrl(prefix_meth, prefix_ctrl)
-            || !BIO_meth_set_callback_ctrl(prefix_meth, prefix_callback_ctrl)) {
-            BIO_meth_free(prefix_meth);
-            prefix_meth = NULL;
-        }
-    }
-    return prefix_meth;
+    return &prefix_meth;
 }
 
 typedef struct prefix_ctx_st {
-    char *prefix;
-    int linestart;               /* flag to indicate we're at the line start */
+    char *prefix;              /* Text prefix, given by user */
+    unsigned int indent;       /* Indentation amount, given by user */
+
+    int linestart;             /* flag to indicate we're at the line start */
 } PREFIX_CTX;
 
 static int prefix_create(BIO *b)
@@ -58,6 +57,7 @@ static int prefix_create(BIO *b)
         return 0;
 
     ctx->prefix = NULL;
+    ctx->indent = 0;
     ctx->linestart = 1;
     BIO_set_data(b, ctx);
     BIO_set_init(b, 1);
@@ -86,9 +86,16 @@ static int prefix_write(BIO *b, const char *out, size_t outl,
     if (ctx == NULL)
         return 0;
 
-    /* If no prefix is set or if it's empty, we've got nothing to do here */
-    if (ctx->prefix == NULL || *ctx->prefix == '\0') {
-        /* We do note if what comes next will be a new line, though */
+    /*
+     * If no prefix is set or if it's empty, and no indentation amount is set,
+     * we've got nothing to do here
+     */
+    if ((ctx->prefix == NULL || *ctx->prefix == '\0')
+        && ctx->indent == 0) {
+        /*
+         * We do note if what comes next will be a new line, though, so we're
+         * prepared to handle prefix and indentation the next time around.
+         */
         if (outl > 0)
             ctx->linestart = (out[outl-1] == '\n');
         return BIO_write_ex(BIO_next(b), out, outl, numwritten);
@@ -100,13 +107,18 @@ static int prefix_write(BIO *b, const char *out, size_t outl,
         size_t i;
         char c;
 
-        /* If we know that we're at the start of the line, output the prefix */
+        /*
+         * If we know that we're at the start of the line, output prefix and
+         * indentation.
+         */
         if (ctx->linestart) {
             size_t dontcare;
 
-            if (!BIO_write_ex(BIO_next(b), ctx->prefix, strlen(ctx->prefix),
-                              &dontcare))
+            if (ctx->prefix != NULL
+                && !BIO_write_ex(BIO_next(b), ctx->prefix, strlen(ctx->prefix),
+                                 &dontcare))
                 return 0;
+            BIO_printf(BIO_next(b), "%*s", ctx->indent, "");
             ctx->linestart = 0;
         }
 
@@ -139,21 +151,39 @@ static int prefix_write(BIO *b, const char *out, size_t outl,
 static long prefix_ctrl(BIO *b, int cmd, long num, void *ptr)
 {
     long ret = 0;
+    PREFIX_CTX *ctx = BIO_get_data(b);
 
-    switch (cmd) {
-    case PREFIX_CTRL_SET_PREFIX:
-        {
-            PREFIX_CTX *ctx = BIO_get_data(b);
-
-            if (ctx == NULL)
-                break;
+    if (ctx == NULL)
+        return -1;
 
-            OPENSSL_free(ctx->prefix);
+    switch (cmd) {
+    case BIO_CTRL_SET_PREFIX:
+        OPENSSL_free(ctx->prefix);
+        if (ptr == NULL) {
+            ctx->prefix = NULL;
+            ret = 1;
+        } else {
             ctx->prefix = OPENSSL_strdup((const char *)ptr);
             ret = ctx->prefix != NULL;
         }
         break;
+    case BIO_CTRL_SET_INDENT:
+        if (num >= 0) {
+            ctx->indent = (unsigned int)num;
+            ret = 1;
+        }
+        break;
+    case BIO_CTRL_GET_INDENT:
+        ret = (long)ctx->indent;
+        break;
     default:
+        /* Commands that we intercept before passing them along */
+        switch (cmd) {
+        case BIO_C_FILE_SEEK:
+        case BIO_CTRL_RESET:
+            ctx->linestart = 1;
+            break;
+        }
         if (BIO_next(b) != NULL)
             ret = BIO_ctrl(BIO_next(b), cmd, num, ptr);
         break;
diff --git a/crypto/bio/build.info b/crypto/bio/build.info
index d1e7d73c55..8e3f530f88 100644
--- a/crypto/bio/build.info
+++ b/crypto/bio/build.info
@@ -1,8 +1,18 @@
 LIBS=../../libcrypto
+
+# Base library
 SOURCE[../../libcrypto]=\
         bio_lib.c bio_cb.c bio_err.c \
-        bss_mem.c bss_null.c bss_fd.c \
-        bss_file.c bss_sock.c bss_conn.c \
-        bf_null.c bf_buff.c b_print.c b_dump.c b_addr.c \
-        b_sock.c b_sock2.c bss_acpt.c bf_nbio.c bss_log.c bss_bio.c \
-        bss_dgram.c bio_meth.c bf_lbuf.c
+        b_print.c b_dump.c b_addr.c \
+        b_sock.c b_sock2.c \
+        bio_meth.c
+
+# Source / sink implementations
+SOURCE[../../libcrypto]=\
+        bss_null.c bss_mem.c bss_bio.c bss_fd.c bss_file.c \
+        bss_sock.c bss_conn.c bss_acpt.c bss_dgram.c \
+        bss_log.c
+
+# Filters
+SOURCE[../../libcrypto]=\
+        bf_null.c bf_buff.c bf_lbuf.c bf_nbio.c bf_prefix.c
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index 99d6063e3e..9999636cfd 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -657,6 +657,40 @@ static void EVP_PKEY_free_it(EVP_PKEY *x)
 #endif
 }
 
+static int print_reset_indent(BIO **out, int pop_f_prefix, long saved_indent)
+{
+    BIO_set_indent(*out, saved_indent);
+    if (pop_f_prefix) {
+        BIO *next = BIO_pop(*out);
+
+        BIO_free(*out);
+        *out = next;
+    }
+    return 1;
+}
+
+static int print_set_indent(BIO **out, int *pop_f_prefix, long *saved_indent,
+                            long indent)
+{
+    *pop_f_prefix = 0;
+    *saved_indent = 0;
+    if (indent > 0) {
+        long i = BIO_get_indent(*out);
+
+        *saved_indent =  (i < 0 ? 0 : i);
+        if (BIO_set_indent(*out, indent) <= 0) {
+            if ((*out = BIO_push(BIO_new(BIO_f_prefix()), *out)) == NULL)
+                return 0;
+            *pop_f_prefix = 1;
+        }
+        if (BIO_set_indent(*out, indent) <= 0) {
+            print_reset_indent(out, *pop_f_prefix, *saved_indent);
+            return 0;
+        }
+    }
+    return 1;
+}
+
 static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
                      const char *kstr)
 {
@@ -666,67 +700,61 @@ static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
     return 1;
 }
 
-int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
-                          int indent, ASN1_PCTX *pctx)
+static int print_pkey(const EVP_PKEY *pkey, BIO *out, int indent,
+                      const char *propquery /* For provided serialization */,
+                      int (*legacy_print)(BIO *out, const EVP_PKEY *pkey,
+                                          int indent, ASN1_PCTX *pctx),
+                      ASN1_PCTX *legacy_pctx /* For legacy print */)
 {
-    const char *pq = OSSL_SERIALIZER_PUBKEY_TO_TEXT_PQ;
-    OSSL_SERIALIZER_CTX *ctx = OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(pkey, pq);
-    int ret = -2;                /* mark as unsupported */
+    int pop_f_prefix;
+    long saved_indent;
+    OSSL_SERIALIZER_CTX *ctx = NULL;
+    int ret = -2;                /* default to unsupported */
+
+    if (!print_set_indent(&out, &pop_f_prefix, &saved_indent, indent))
+        return 0;
 
+    ctx = OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(pkey, propquery);
     if (OSSL_SERIALIZER_CTX_get_serializer(ctx) != NULL)
         ret = OSSL_SERIALIZER_to_bio(ctx, out);
     OSSL_SERIALIZER_CTX_free(ctx);
 
     if (ret != -2)
-        return ret;
+        goto end;
 
     /* legacy fallback */
-    if (pkey->ameth && pkey->ameth->pub_print)
-        return pkey->ameth->pub_print(out, pkey, indent, pctx);
+    if (legacy_print != NULL)
+        ret = legacy_print(out, pkey, 0, legacy_pctx);
+    else
+        ret = unsup_alg(out, pkey, 0, "Public Key");
 
-    return unsup_alg(out, pkey, indent, "Public Key");
+ end:
+    print_reset_indent(&out, pop_f_prefix, saved_indent);
+    return ret;
+}
+
+int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
+                          int indent, ASN1_PCTX *pctx)
+{
+    return print_pkey(pkey, out, indent, OSSL_SERIALIZER_PUBKEY_TO_TEXT_PQ,
+                      (pkey->ameth != NULL ? pkey->ameth->pub_print : NULL),
+                      pctx);
 }
 
 int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
                            int indent, ASN1_PCTX *pctx)
 {
-    const char *pq = OSSL_SERIALIZER_PrivateKey_TO_TEXT_PQ;
-    OSSL_SERIALIZER_CTX *ctx = OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(pkey, pq);
-    int ret = -2;                /* mark as unsupported */
-
-    if (OSSL_SERIALIZER_CTX_get_serializer(ctx) != NULL)
-        ret = OSSL_SERIALIZER_to_bio(ctx, out);
-    OSSL_SERIALIZER_CTX_free(ctx);
-
-    if (ret != -2)
-        return ret;
-
-    /* legacy fallback */
-    if (pkey->ameth && pkey->ameth->priv_print)
-        return pkey->ameth->priv_print(out, pkey, indent, pctx);
-
-    return unsup_alg(out, pkey, indent, "Private Key");
+    return print_pkey(pkey, out, indent, OSSL_SERIALIZER_PrivateKey_TO_TEXT_PQ,
+                      (pkey->ameth != NULL ? pkey->ameth->priv_print : NULL),
+                      pctx);
 }
 
 int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
                           int indent, ASN1_PCTX *pctx)
 {
-    const char *pq = OSSL_SERIALIZER_Parameters_TO_TEXT_PQ;
-    OSSL_SERIALIZER_CTX *ctx = OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(pkey, pq);
-    int ret = -2;                /* mark as unsupported */
-
-    if (OSSL_SERIALIZER_CTX_get_serializer(ctx) != NULL)
-        ret = OSSL_SERIALIZER_to_bio(ctx, out);
-    OSSL_SERIALIZER_CTX_free(ctx);
-
-    if (ret != -2)
-        return ret;
-
-    /* legacy fallback */
-    if (pkey->ameth && pkey->ameth->param_print)
-        return pkey->ameth->param_print(out, pkey, indent, pctx);
-
-    return unsup_alg(out, pkey, indent, "Parameters");
+    return print_pkey(pkey, out, indent, OSSL_SERIALIZER_Parameters_TO_TEXT_PQ,
+                      (pkey->ameth != NULL ? pkey->ameth->param_print : NULL),
+                      pctx);
 }
 
 static int evp_pkey_asn1_ctrl(EVP_PKEY *pkey, int op, int arg1, void *arg2)
diff --git a/doc/man3/BIO_f_prefix.pod b/doc/man3/BIO_f_prefix.pod
new file mode 100644
index 0000000000..b4d0298b2a
--- /dev/null
+++ b/doc/man3/BIO_f_prefix.pod
@@ -0,0 +1,70 @@
+=pod
+
+=head1 NAME
+
+BIO_f_prefix, BIO_set_prefix, BIO_set_indent, BIO_get_indent
+- prefix BIO filter
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+
+ const BIO_METHOD *BIO_f_prefix(void);
+ long BIO_set_prefix(BIO *b, const char *prefix);
+ long BIO_set_indent(BIO *b, long indent);
+ long BIO_get_indent(BIO *b);
+
+=head1 DESCRIPTION
+
+BIO_f_cipher() returns the prefix BIO method. This is a filter for
+text output, where each line gets automatically prefixed and indented
+according to user input.
+
+The prefix and the indentation are combined.  For each line of output
+going through this filter, the prefix is output first, then the amount
+of additional spaces indicated by the indentation, and then the line
+itself.
+
+By default, there is no prefix, and indentation is set to 0.
+
+BIO_set_prefix() sets the prefix to be used for future lines of
+text, using I<prefix>.  I<prefix> may be NULL, signifying that there
+should be no prefix.  If I<prefix> isn't NULL, this function makes a
+copy of it.
+
+BIO_set_indent() sets the indentation to be used for future lines of
+text, using I<indent>.  Negative values are not allowed.
+
+BIO_get_indent() gets the current indentation.
+
+=head1 NOTES
+
+BIO_set_prefix(), BIO_set_indent() and BIO_get_indent() are
+implemented as macros.
+
+=head1 RETURN VALUES
+
+BIO_f_prefix() returns the prefix BIO method.
+
+BIO_set_prefix() returns 1 if the prefix was correctly set, or 0 on
+failure.
+
+BIO_set_indent() returns 1 if the prefix was correctly set, or 0 on
+failure.
+
+BIO_get_indent() returns the current indentation.
+
+=head1 SEE ALSO
+
+L<bio(7)>
+
+=head1 COPYRIGHT
+
+Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/include/openssl/bio.h b/include/openssl/bio.h
index ed9ecc6cca..50ac82cc31 100644
--- a/include/openssl/bio.h
+++ b/include/openssl/bio.h
@@ -160,6 +160,11 @@ extern "C" {
 # define BIO_CTRL_DGRAM_SCTP_WAIT_FOR_DRY       77
 # define BIO_CTRL_DGRAM_SCTP_MSG_WAITING        78
 
+/* BIO_f_prefix controls */
+# define BIO_CTRL_SET_PREFIX                    79
+# define BIO_CTRL_SET_INDENT                    80
+# define BIO_CTRL_GET_INDENT                    81
+
 # ifndef OPENSSL_NO_KTLS
 #  define BIO_get_ktls_send(b)         \
      BIO_ctrl(b, BIO_CTRL_GET_KTLS_SEND, 0, NULL)
@@ -552,6 +557,11 @@ int BIO_ctrl_reset_read_request(BIO *b);
 # define BIO_dgram_get_mtu_overhead(b) \
          (unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU_OVERHEAD, 0, NULL)
 
+/* ctrl macros for BIO_f_prefix */
+# define BIO_set_prefix(b,p) BIO_ctrl((b), BIO_CTRL_SET_PREFIX, 0, (void *)(p))
+# define BIO_set_indent(b,i) BIO_ctrl((b), BIO_CTRL_SET_INDENT, (i), NULL)
+# define BIO_get_indent(b) BIO_ctrl((b), BIO_CTRL_GET_INDENT, 0, NULL)
+
 #define BIO_get_ex_new_index(l, p, newf, dupf, freef) \
     CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, l, p, newf, dupf, freef)
 int BIO_set_ex_data(BIO *bio, int idx, void *data);
@@ -630,6 +640,7 @@ const BIO_METHOD *BIO_f_null(void);
 const BIO_METHOD *BIO_f_buffer(void);
 const BIO_METHOD *BIO_f_linebuffer(void);
 const BIO_METHOD *BIO_f_nbio_test(void);
+const BIO_METHOD *BIO_f_prefix(void);
 # ifndef OPENSSL_NO_DGRAM
 const BIO_METHOD *BIO_s_datagram(void);
 int BIO_dgram_non_fatal_error(int error);
diff --git a/test/README b/test/README
index 9a0938146e..17dffa0e7f 100644
--- a/test/README
+++ b/test/README
@@ -27,7 +27,10 @@ The number {nn} is (somewhat loosely) grouped as follows:
 20-24  openssl commands (some otherwise not tested)
 25-29  certificate forms, generation and verification
 30-35  engine and evp
-60-79  APIs
+60-79  APIs:
+   60  X509 subsystem
+   61  BIO subsystem
+   65  CMP subsystem
    70  PACKET layer
 80-89  "larger" protocols (CA, CMS, OCSP, SSL, TSA)
 90-98  misc
diff --git a/test/bio_prefix_text.c b/test/bio_prefix_text.c
new file mode 100644
index 0000000000..4fc468a976
--- /dev/null
+++ b/test/bio_prefix_text.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <string.h>
+#include <stdarg.h>
+#include <openssl/bio.h>
+#include <openssl/safestack.h>
+#include "opt.h"
+
+static BIO *bio_in = NULL;
+static BIO *bio_out = NULL;
+static BIO *bio_err = NULL;
+
+/*-
+ * This program sets up a chain of BIO_f_filter() on top of bio_out, how
+ * many is governed by the user through -n.  It allows the user to set the
+ * indentation for each individual filter using -i and -p.  Then it reads
+ * text from bio_in and prints it out through the BIO chain.
+ *
+ * The filter index is counted from the source/sink, i.e. index 0 is closest
+ * to it.
+ *
+ * Example:
+ *
+ * $ echo foo | ./bio_prefix_text -n 2 -i 1:32 -p 1:FOO -i 0:3
+ *    FOO                                foo
+ * ^^^   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ *  |                   |
+ *  |                   +------ 32 spaces from filter 1
+ *  +-------------------------- 3 spaces from filter 0
+ */
+
+static size_t amount = 0;
+static BIO **chain = NULL;
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1,
+    OPT_EOF = 0,
+    OPT_AMOUNT,
+    OPT_INDENT,
+    OPT_PREFIX
+} OPTION_CHOICE;
+
+static const OPTIONS options[] = {
+    { "n", OPT_AMOUNT, 'p', "Amount of BIO_f_prefix() filters" },
+    /*
+     * idx is the index to the BIO_f_filter chain(), where 0 is closest
+     * to the source/sink BIO.  If idx isn't given, 0 is assumed
+     */
+    { "i", OPT_INDENT, 's', "Indentation in form '[idx:]indent'" },
+    { "p", OPT_PREFIX, 's', "Prefix in form '[idx:]prefix'" },
+    { NULL }
+};
+
+int opt_printf_stderr(const char *fmt, ...)
+{
+    va_list ap;
+    int ret;
+
+    va_start(ap, fmt);
+    ret = BIO_vprintf(bio_err, fmt, ap);
+    va_end(ap);
+    return ret;
+}
+
+static int run_pipe(void)
+{
+    char buf[4096];
+
+    while (!BIO_eof(bio_in)) {
+        size_t bytes_in;
+        size_t bytes_out;
+
+        if (!BIO_read_ex(bio_in, buf, sizeof(buf), &bytes_in))
+            return 0;
+        bytes_out = 0;
+        while (bytes_out < bytes_in) {
+            size_t bytes;
+
+            if (!BIO_write_ex(chain[amount - 1], buf, bytes_in, &bytes))
+                return 0;
+            bytes_out += bytes;
+        }
+    }
+    return 1;
+}
+
+static int setup_bio_chain(const char *progname)
+{
+    BIO *next = NULL;
+    size_t n = amount;
+
+    chain = OPENSSL_zalloc(sizeof(*chain) * n);
+
+    if (chain != NULL) {
+        size_t i;
+
+        next = bio_out;
+        BIO_up_ref(next);        /* Protection against freeing */
+
+        for (i = 0; n > 0; i++, n--) {
+            BIO *curr = BIO_new(BIO_f_prefix());
+
+            if (curr == NULL)
+                goto err;
+            chain[i] = BIO_push(curr, next);
+            if (chain[i] == NULL)
+                goto err;
+            next = chain[i];
+        }
+    }
+    return chain != NULL;
+ err:
+    /* Free the chain we built up */
+    BIO_free_all(next);
+    OPENSSL_free(chain);
+    return 0;
+}
+
+static void cleanup(void)
+{
+    if (chain != NULL) {
+        BIO_free_all(chain[amount - 1]);
+        OPENSSL_free(chain);
+    }
+
+    BIO_free_all(bio_in);
+    BIO_free_all(bio_out);
+    BIO_free_all(bio_err);
+}
+
+static int setup(void)
+{
+    OPTION_CHOICE o;
+    char *arg;
+    char *colon;
+    char *endptr;
+    size_t idx, indent;
+    const char *progname = opt_getprog();
+
+    bio_in = BIO_new_fp(stdin, BIO_NOCLOSE | BIO_FP_TEXT);
+    bio_out = BIO_new_fp(stdout, BIO_NOCLOSE | BIO_FP_TEXT);
+    bio_err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
+#ifdef __VMS
+    bio_out = BIO_push(BIO_new(BIO_f_linebuffer()), bio_out);
+    bio_err = BIO_push(BIO_new(BIO_f_linebuffer()), bio_err);
+#endif
+
+    OPENSSL_assert(bio_in != NULL);
+    OPENSSL_assert(bio_out != NULL);
+    OPENSSL_assert(bio_err != NULL);
+
+
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_AMOUNT:
+            arg = opt_arg();
+            amount = strtoul(arg, &endptr, 10);
+            if (endptr[0] != '\0') {
+                BIO_printf(bio_err,
+                           "%s: -n argument isn't a decimal number: %s",
+                           progname, arg);
+                return 0;
+            }
+            if (amount < 1) {
+                BIO_printf(bio_err, "%s: must set up at least one filter",
+                           progname);
+                return 0;
+            }
+            if (!setup_bio_chain(progname)) {
+                BIO_printf(bio_err, "%s: failed setting up filter chain",
+                           progname);
+                return 0;
+            }
+            break;
+        case OPT_INDENT:
+            if (chain == NULL) {
+                BIO_printf(bio_err, "%s: -i given before -n", progname);
+                return 0;
+            }
+            arg = opt_arg();
+            colon = strchr(arg, ':');
+            idx = 0;
+            if (colon != NULL) {
+                idx = strtoul(arg, &endptr, 10);
+                if (endptr[0] != ':') {
+                    BIO_printf(bio_err,
+                               "%s: -i index isn't a decimal number: %s",
+                               progname, arg);
+                    return 0;
+                }
+                colon++;
+            } else {
+                colon = arg;
+            }
+            indent = strtoul(colon, &endptr, 10);
+            if (endptr[0] != '\0') {
+                BIO_printf(bio_err,
+                           "%s: -i value isn't a decimal number: %s",
+                           progname, arg);
+                return 0;
+            }
+            if (idx >= amount) {
+                BIO_printf(bio_err, "%s: index (%zu) not within range 0..%zu",
+                           progname, idx, amount - 1);
+                return 0;
+            }
+            if (!BIO_set_indent(chain[idx], (long)indent)) {
+                BIO_printf(bio_err, "%s: failed setting indentation: %s",
+                           progname, arg);
+                return 0;
+            }
+            break;
+        case OPT_PREFIX:
+            if (chain == NULL) {
+                BIO_printf(bio_err, "%s: -p given before -n", progname);
+                return 0;
+            }
+            arg = opt_arg();
+            colon = strchr(arg, ':');
+            idx = 0;
+            if (colon != NULL) {
+                idx = strtoul(arg, &endptr, 10);
+                if (endptr[0] != ':') {
+                    BIO_printf(bio_err,
+                               "%s: -p index isn't a decimal number: %s",
+                               progname, arg);
+                    return 0;
+                }
+                colon++;
+            } else {
+                colon = arg;
+            }
+            if (idx >= amount) {
+                BIO_printf(bio_err, "%s: index (%zu) not within range 0..%zu",
+                           progname, idx, amount - 1);
+                return 0;
+            }
+            if (!BIO_set_prefix(chain[idx], colon)) {
+                BIO_printf(bio_err, "%s: failed setting prefix: %s",
+                           progname, arg);
+                return 0;
+            }
+            break;
+        default:
+        case OPT_ERR:
+            return 0;
+        }
+    }
+    return 1;
+}
+
+int main(int argc, char **argv)
+{
+    int rv = EXIT_SUCCESS;
+
+    opt_init(argc, argv, options);
+    rv = (setup() && run_pipe()) ? EXIT_SUCCESS : EXIT_FAILURE;
+    cleanup();
+    return rv;
+}
diff --git a/test/build.info b/test/build.info
index 0be3ee078c..2b429d304c 100644
--- a/test/build.info
+++ b/test/build.info
@@ -14,7 +14,7 @@ ENDIF
 IF[{- $config{target} =~ /^vms-/ -}]
   $AUXLIBAPPSSRC=../apps/lib/vms_term_sock.c ../apps/lib/vms_decc_argv.c
 ENDIF
-$LIBAPPSSRC=../apps/lib/opt.c ../apps/lib/bf_prefix.c $AUXLIBAPPSSRC
+$LIBAPPSSRC=../apps/lib/opt.c $AUXLIBAPPSSRC
 
 IF[{- !$disabled{tests} -}]
   LIBS{noinst,has_main}=libtestutil.a
@@ -706,6 +706,11 @@ IF[{- !$disabled{tests} -}]
   SOURCE[namemap_internal_test]=namemap_internal_test.c
   INCLUDE[namemap_internal_test]=.. ../include ../apps/include
   DEPEND[namemap_internal_test]=../libcrypto.a libtestutil.a
+
+  PROGRAMS{noinst}=bio_prefix_text
+  SOURCE[bio_prefix_text]=bio_prefix_text.c $LIBAPPSSRC
+  INCLUDE[bio_prefix_text]=.. ../include ../apps/include
+  DEPEND[bio_prefix_text]=../libcrypto
 ENDIF
 
   SOURCE[ssl_ctx_test]=ssl_ctx_test.c
diff --git a/test/recipes/61-test_bio_prefix.t b/test/recipes/61-test_bio_prefix.t
new file mode 100644
index 0000000000..c77bdbfa32
--- /dev/null
+++ b/test/recipes/61-test_bio_prefix.t
@@ -0,0 +1,55 @@
+#! /usr/bin/env perl
+# Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License").  You may not use
+# this file except in compliance with the License.  You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+use strict;
+use warnings;
+
+use OpenSSL::Test qw(:DEFAULT data_file);
+use File::Compare qw(compare_text);
+
+setup('test_bio_prefix');
+
+my %input_result = (
+    'in1.txt'  => [ 'args1.pl', 'out1.txt' ],
+    'in2.txt' => [ 'args2.pl', 'out2.txt' ],
+);
+
+plan tests => 2 * scalar(keys %input_result);
+
+foreach (sort keys %input_result) {
+  SKIP: {
+      my $input_path = data_file($_);
+      my $args_path = data_file($input_result{$_}->[0]);
+      my $expected_path = data_file($input_result{$_}->[1]);
+      my $result_path = "test_bio_prefix-$_-stdout";
+      my @args = do $args_path;
+
+      skip "Problem prefixing $_", 1
+          unless ok(run(test([ 'bio_prefix_text', @args ],
+                             stdin => $input_path, stdout => $result_path)),
+                    "prefixing $_ with args " . join(' ', @args));
+      is(compare_text($result_path, $expected_path, \&cmp_line), 0,
+         "comparing the dump of $_ with $expected_path");
+    }
+}
+
+sub cmp_line {
+    return 0 if scalar @_ == 0;
+
+    if (scalar @_ != 2) {
+        diag "Lines to compare less than 2: ", scalar @_;
+        return -1;
+    }
+
+    $_[0] =~ s|\R$||;
+    $_[1] =~ s|\R$||;
+    my $r = $_[0] cmp $_[1];
+
+    diag "Lines differ:\n<: $_[0]\n>: $_[1]\n" unless $r == 0;
+    return $r;
+}
diff --git a/test/recipes/61-test_bio_prefix_data/args1.pl b/test/recipes/61-test_bio_prefix_data/args1.pl
new file mode 100644
index 0000000000..e7038dc50d
--- /dev/null
+++ b/test/recipes/61-test_bio_prefix_data/args1.pl
@@ -0,0 +1,6 @@
+(
+ -n => 2,
+ -i => '1:32',
+ -p => '1:FOO',
+ -i => '0:3'
+);
diff --git a/test/recipes/61-test_bio_prefix_data/args2.pl b/test/recipes/61-test_bio_prefix_data/args2.pl
new file mode 100644
index 0000000000..2fe2b7bb63
--- /dev/null
+++ b/test/recipes/61-test_bio_prefix_data/args2.pl
@@ -0,0 +1,3 @@
+(
+ -n => 1,
+);
diff --git a/test/recipes/61-test_bio_prefix_data/in1.txt b/test/recipes/61-test_bio_prefix_data/in1.txt
new file mode 100644
index 0000000000..257cc5642c
--- /dev/null
+++ b/test/recipes/61-test_bio_prefix_data/in1.txt
@@ -0,0 +1 @@
+foo
diff --git a/test/recipes/61-test_bio_prefix_data/in2.txt b/test/recipes/61-test_bio_prefix_data/in2.txt
new file mode 100644
index 0000000000..5716ca5987
--- /dev/null
+++ b/test/recipes/61-test_bio_prefix_data/in2.txt
@@ -0,0 +1 @@
+bar
diff --git a/test/recipes/61-test_bio_prefix_data/out1.txt b/test/recipes/61-test_bio_prefix_data/out1.txt
new file mode 100644
index 0000000000..484e514ba4
--- /dev/null
+++ b/test/recipes/61-test_bio_prefix_data/out1.txt
@@ -0,0 +1 @@
+   FOO                                foo
diff --git a/test/recipes/61-test_bio_prefix_data/out2.txt b/test/recipes/61-test_bio_prefix_data/out2.txt
new file mode 100644
index 0000000000..5716ca5987
--- /dev/null
+++ b/test/recipes/61-test_bio_prefix_data/out2.txt
@@ -0,0 +1 @@
+bar
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 9c17fc5e25..963181eb37 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4911,3 +4911,4 @@ i2d_X509_PUBKEY_bio                     ?	3_0_0	EXIST::FUNCTION:
 RSA_get0_pss_params                     ?	3_0_0	EXIST::FUNCTION:RSA
 X509_cmp_timeframe                      ?	3_0_0	EXIST::FUNCTION:
 OSSL_CMP_MSG_get0_header                ?	3_0_0	EXIST::FUNCTION:CMP
+BIO_f_prefix                            ?	3_0_0	EXIST::FUNCTION:
diff --git a/util/other.syms b/util/other.syms
index 51b4dfa255..3a8d284e97 100644
--- a/util/other.syms
+++ b/util/other.syms
@@ -127,6 +127,7 @@ BIO_get_conn_port                       define
 BIO_get_conn_ip_family                  define
 BIO_get_fd                              define
 BIO_get_fp                              define
+BIO_get_indent                          define
 BIO_get_info_callback                   define
 BIO_get_md                              define
 BIO_get_md_ctx                          define
@@ -158,12 +159,14 @@ BIO_set_conn_port                       define
 BIO_set_conn_ip_family                  define
 BIO_set_fd                              define
 BIO_set_fp                              define
+BIO_set_indent                          define
 BIO_set_info_callback                   define
 BIO_set_md                              define
 BIO_set_mem_buf                         define
 BIO_set_mem_eof_return                  define
 BIO_set_nbio                            define
 BIO_set_nbio_accept                     define
+BIO_set_prefix                          define
 BIO_set_read_buffer_size                define
 BIO_set_ssl                             define
 BIO_set_ssl_mode                        define


More information about the openssl-commits mailing list