[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit

Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_bitstr.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_bitstr.c
new file mode 100644
index 0000000..f462dd1
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_bitstr.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright 1995-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <limits.h>
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include "asn1_local.h"
+
+int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
+{
+    return ASN1_STRING_set(x, d, len);
+}
+
+int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
+{
+    int ret, j, bits, len;
+    unsigned char *p, *d;
+
+    if (a == NULL)
+        return 0;
+
+    len = a->length;
+
+    if (len > 0) {
+        if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) {
+            bits = (int)a->flags & 0x07;
+        } else {
+            for (; len > 0; len--) {
+                if (a->data[len - 1])
+                    break;
+            }
+            j = a->data[len - 1];
+            if (j & 0x01)
+                bits = 0;
+            else if (j & 0x02)
+                bits = 1;
+            else if (j & 0x04)
+                bits = 2;
+            else if (j & 0x08)
+                bits = 3;
+            else if (j & 0x10)
+                bits = 4;
+            else if (j & 0x20)
+                bits = 5;
+            else if (j & 0x40)
+                bits = 6;
+            else if (j & 0x80)
+                bits = 7;
+            else
+                bits = 0;       /* should not happen */
+        }
+    } else
+        bits = 0;
+
+    ret = 1 + len;
+    if (pp == NULL)
+        return ret;
+
+    p = *pp;
+
+    *(p++) = (unsigned char)bits;
+    d = a->data;
+    if (len > 0) {
+        memcpy(p, d, len);
+        p += len;
+        p[-1] &= (0xff << bits);
+    }
+    *pp = p;
+    return ret;
+}
+
+ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
+                                     const unsigned char **pp, long len)
+{
+    ASN1_BIT_STRING *ret = NULL;
+    const unsigned char *p;
+    unsigned char *s;
+    int i;
+
+    if (len < 1) {
+        i = ASN1_R_STRING_TOO_SHORT;
+        goto err;
+    }
+
+    if (len > INT_MAX) {
+        i = ASN1_R_STRING_TOO_LONG;
+        goto err;
+    }
+
+    if ((a == NULL) || ((*a) == NULL)) {
+        if ((ret = ASN1_BIT_STRING_new()) == NULL)
+            return NULL;
+    } else
+        ret = (*a);
+
+    p = *pp;
+    i = *(p++);
+    if (i > 7) {
+        i = ASN1_R_INVALID_BIT_STRING_BITS_LEFT;
+        goto err;
+    }
+    /*
+     * We do this to preserve the settings.  If we modify the settings, via
+     * the _set_bit function, we will recalculate on output
+     */
+    ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */
+    ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | i); /* set */
+
+    if (len-- > 1) {            /* using one because of the bits left byte */
+        s = OPENSSL_malloc((int)len);
+        if (s == NULL) {
+            i = ERR_R_MALLOC_FAILURE;
+            goto err;
+        }
+        memcpy(s, p, (int)len);
+        s[len - 1] &= (0xff << i);
+        p += len;
+    } else
+        s = NULL;
+
+    ret->length = (int)len;
+    OPENSSL_free(ret->data);
+    ret->data = s;
+    ret->type = V_ASN1_BIT_STRING;
+    if (a != NULL)
+        (*a) = ret;
+    *pp = p;
+    return ret;
+ err:
+    ASN1err(ASN1_F_C2I_ASN1_BIT_STRING, i);
+    if ((a == NULL) || (*a != ret))
+        ASN1_BIT_STRING_free(ret);
+    return NULL;
+}
+
+/*
+ * These next 2 functions from Goetz Babin-Ebell.
+ */
+int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
+{
+    int w, v, iv;
+    unsigned char *c;
+
+    w = n / 8;
+    v = 1 << (7 - (n & 0x07));
+    iv = ~v;
+    if (!value)
+        v = 0;
+
+    if (a == NULL)
+        return 0;
+
+    a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */
+
+    if ((a->length < (w + 1)) || (a->data == NULL)) {
+        if (!value)
+            return 1;         /* Don't need to set */
+        c = OPENSSL_clear_realloc(a->data, a->length, w + 1);
+        if (c == NULL) {
+            ASN1err(ASN1_F_ASN1_BIT_STRING_SET_BIT, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        if (w + 1 - a->length > 0)
+            memset(c + a->length, 0, w + 1 - a->length);
+        a->data = c;
+        a->length = w + 1;
+    }
+    a->data[w] = ((a->data[w]) & iv) | v;
+    while ((a->length > 0) && (a->data[a->length - 1] == 0))
+        a->length--;
+    return 1;
+}
+
+int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n)
+{
+    int w, v;
+
+    w = n / 8;
+    v = 1 << (7 - (n & 0x07));
+    if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL))
+        return 0;
+    return ((a->data[w] & v) != 0);
+}
+
+/*
+ * Checks if the given bit string contains only bits specified by
+ * the flags vector. Returns 0 if there is at least one bit set in 'a'
+ * which is not specified in 'flags', 1 otherwise.
+ * 'len' is the length of 'flags'.
+ */
+int ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a,
+                          const unsigned char *flags, int flags_len)
+{
+    int i, ok;
+    /* Check if there is one bit set at all. */
+    if (!a || !a->data)
+        return 1;
+
+    /*
+     * Check each byte of the internal representation of the bit string.
+     */
+    ok = 1;
+    for (i = 0; i < a->length && ok; ++i) {
+        unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
+        /* We are done if there is an unneeded bit set. */
+        ok = (a->data[i] & mask) == 0;
+    }
+    return ok;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_d2i_fp.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_d2i_fp.c
new file mode 100644
index 0000000..a452b3d
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_d2i_fp.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright 1995-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <limits.h>
+#include "internal/cryptlib.h"
+#include "internal/numbers.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1.h>
+#include "crypto/asn1.h"
+
+#ifndef NO_OLD_ASN1
+# ifndef OPENSSL_NO_STDIO
+
+void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x)
+{
+    BIO *b;
+    void *ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        ASN1err(ASN1_F_ASN1_D2I_FP, ERR_R_BUF_LIB);
+        return NULL;
+    }
+    BIO_set_fp(b, in, BIO_NOCLOSE);
+    ret = ASN1_d2i_bio(xnew, d2i, b, x);
+    BIO_free(b);
+    return ret;
+}
+# endif
+
+void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x)
+{
+    BUF_MEM *b = NULL;
+    const unsigned char *p;
+    void *ret = NULL;
+    int len;
+
+    len = asn1_d2i_read_bio(in, &b);
+    if (len < 0)
+        goto err;
+
+    p = (unsigned char *)b->data;
+    ret = d2i(x, &p, len);
+ err:
+    BUF_MEM_free(b);
+    return ret;
+}
+
+#endif
+
+void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x)
+{
+    BUF_MEM *b = NULL;
+    const unsigned char *p;
+    void *ret = NULL;
+    int len;
+
+    len = asn1_d2i_read_bio(in, &b);
+    if (len < 0)
+        goto err;
+
+    p = (const unsigned char *)b->data;
+    ret = ASN1_item_d2i(x, &p, len, it);
+ err:
+    BUF_MEM_free(b);
+    return ret;
+}
+
+#ifndef OPENSSL_NO_STDIO
+void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
+{
+    BIO *b;
+    char *ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        ASN1err(ASN1_F_ASN1_ITEM_D2I_FP, ERR_R_BUF_LIB);
+        return NULL;
+    }
+    BIO_set_fp(b, in, BIO_NOCLOSE);
+    ret = ASN1_item_d2i_bio(it, b, x);
+    BIO_free(b);
+    return ret;
+}
+#endif
+
+#define HEADER_SIZE   8
+#define ASN1_CHUNK_INITIAL_SIZE (16 * 1024)
+int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
+{
+    BUF_MEM *b;
+    unsigned char *p;
+    int i;
+    size_t want = HEADER_SIZE;
+    uint32_t eos = 0;
+    size_t off = 0;
+    size_t len = 0;
+
+    const unsigned char *q;
+    long slen;
+    int inf, tag, xclass;
+
+    b = BUF_MEM_new();
+    if (b == NULL) {
+        ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
+        return -1;
+    }
+
+    ERR_clear_error();
+    for (;;) {
+        if (want >= (len - off)) {
+            want -= (len - off);
+
+            if (len + want < len || !BUF_MEM_grow_clean(b, len + want)) {
+                ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            i = BIO_read(in, &(b->data[len]), want);
+            if ((i < 0) && ((len - off) == 0)) {
+                ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_NOT_ENOUGH_DATA);
+                goto err;
+            }
+            if (i > 0) {
+                if (len + i < len) {
+                    ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
+                    goto err;
+                }
+                len += i;
+            }
+        }
+        /* else data already loaded */
+
+        p = (unsigned char *)&(b->data[off]);
+        q = p;
+        inf = ASN1_get_object(&q, &slen, &tag, &xclass, len - off);
+        if (inf & 0x80) {
+            unsigned long e;
+
+            e = ERR_GET_REASON(ERR_peek_error());
+            if (e != ASN1_R_TOO_LONG)
+                goto err;
+            else
+                ERR_clear_error(); /* clear error */
+        }
+        i = q - p;            /* header length */
+        off += i;               /* end of data */
+
+        if (inf & 1) {
+            /* no data body so go round again */
+            if (eos == UINT32_MAX) {
+                ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_HEADER_TOO_LONG);
+                goto err;
+            }
+            eos++;
+            want = HEADER_SIZE;
+        } else if (eos && (slen == 0) && (tag == V_ASN1_EOC)) {
+            /* eos value, so go back and read another header */
+            eos--;
+            if (eos == 0)
+                break;
+            else
+                want = HEADER_SIZE;
+        } else {
+            /* suck in slen bytes of data */
+            want = slen;
+            if (want > (len - off)) {
+                size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE;
+
+                want -= (len - off);
+                if (want > INT_MAX /* BIO_read takes an int length */  ||
+                    len + want < len) {
+                    ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
+                    goto err;
+                }
+                while (want > 0) {
+                    /*
+                     * Read content in chunks of increasing size
+                     * so we can return an error for EOF without
+                     * having to allocate the entire content length
+                     * in one go.
+                     */
+                    size_t chunk = want > chunk_max ? chunk_max : want;
+
+                    if (!BUF_MEM_grow_clean(b, len + chunk)) {
+                        ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
+                        goto err;
+                    }
+                    want -= chunk;
+                    while (chunk > 0) {
+                        i = BIO_read(in, &(b->data[len]), chunk);
+                        if (i <= 0) {
+                            ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
+                                    ASN1_R_NOT_ENOUGH_DATA);
+                            goto err;
+                        }
+                    /*
+                     * This can't overflow because |len+want| didn't
+                     * overflow.
+                     */
+                        len += i;
+                        chunk -= i;
+                    }
+                    if (chunk_max < INT_MAX/2)
+                        chunk_max *= 2;
+                }
+            }
+            if (off + slen < off) {
+                ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
+                goto err;
+            }
+            off += slen;
+            if (eos == 0) {
+                break;
+            } else
+                want = HEADER_SIZE;
+        }
+    }
+
+    if (off > INT_MAX) {
+        ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
+        goto err;
+    }
+
+    *pb = b;
+    return off;
+ err:
+    BUF_MEM_free(b);
+    return -1;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_digest.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_digest.c
new file mode 100644
index 0000000..cc3532e
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_digest.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright 1995-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <sys/types.h>
+
+#include "internal/cryptlib.h"
+
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/buffer.h>
+#include <openssl/x509.h>
+
+#ifndef NO_ASN1_OLD
+
+int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
+                unsigned char *md, unsigned int *len)
+{
+    int inl;
+    unsigned char *str, *p;
+
+    inl = i2d(data, NULL);
+    if (inl <= 0) {
+        ASN1err(ASN1_F_ASN1_DIGEST, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+    if ((str = OPENSSL_malloc(inl)) == NULL) {
+        ASN1err(ASN1_F_ASN1_DIGEST, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    p = str;
+    i2d(data, &p);
+
+    if (!EVP_Digest(str, inl, md, len, type, NULL)) {
+        OPENSSL_free(str);
+        return 0;
+    }
+    OPENSSL_free(str);
+    return 1;
+}
+
+#endif
+
+int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn,
+                     unsigned char *md, unsigned int *len)
+{
+    int i;
+    unsigned char *str = NULL;
+
+    i = ASN1_item_i2d(asn, &str, it);
+    if (!str)
+        return 0;
+
+    if (!EVP_Digest(str, i, md, len, type, NULL)) {
+        OPENSSL_free(str);
+        return 0;
+    }
+    OPENSSL_free(str);
+    return 1;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_dup.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_dup.c
new file mode 100644
index 0000000..50af6b0
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_dup.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright 1995-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+
+#ifndef NO_OLD_ASN1
+
+void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x)
+{
+    unsigned char *b, *p;
+    const unsigned char *p2;
+    int i;
+    char *ret;
+
+    if (x == NULL)
+        return NULL;
+
+    i = i2d(x, NULL);
+    b = OPENSSL_malloc(i + 10);
+    if (b == NULL) {
+        ASN1err(ASN1_F_ASN1_DUP, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    p = b;
+    i = i2d(x, &p);
+    p2 = b;
+    ret = d2i(NULL, &p2, i);
+    OPENSSL_free(b);
+    return ret;
+}
+
+#endif
+
+/*
+ * ASN1_ITEM version of dup: this follows the model above except we don't
+ * need to allocate the buffer. At some point this could be rewritten to
+ * directly dup the underlying structure instead of doing and encode and
+ * decode.
+ */
+
+void *ASN1_item_dup(const ASN1_ITEM *it, void *x)
+{
+    unsigned char *b = NULL;
+    const unsigned char *p;
+    long i;
+    void *ret;
+
+    if (x == NULL)
+        return NULL;
+
+    i = ASN1_item_i2d(x, &b, it);
+    if (b == NULL) {
+        ASN1err(ASN1_F_ASN1_ITEM_DUP, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    p = b;
+    ret = ASN1_item_d2i(NULL, &p, i, it);
+    OPENSSL_free(b);
+    return ret;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_gentm.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_gentm.c
new file mode 100644
index 0000000..133bbb1
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_gentm.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright 1995-2017 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * GENERALIZEDTIME implementation. Based on UTCTIME
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include "asn1_local.h"
+
+/* This is the primary function used to parse ASN1_GENERALIZEDTIME */
+int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d)
+{
+    /* wrapper around asn1_time_to_tm */
+    if (d->type != V_ASN1_GENERALIZEDTIME)
+        return 0;
+    return asn1_time_to_tm(tm, d);
+}
+
+int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *d)
+{
+    return asn1_generalizedtime_to_tm(NULL, d);
+}
+
+int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str)
+{
+    ASN1_GENERALIZEDTIME t;
+
+    t.type = V_ASN1_GENERALIZEDTIME;
+    t.length = strlen(str);
+    t.data = (unsigned char *)str;
+    t.flags = 0;
+
+    if (!ASN1_GENERALIZEDTIME_check(&t))
+        return 0;
+
+    if (s != NULL && !ASN1_STRING_copy(s, &t))
+        return 0;
+
+    return 1;
+}
+
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
+                                               time_t t)
+{
+    return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0);
+}
+
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
+                                               time_t t, int offset_day,
+                                               long offset_sec)
+{
+    struct tm *ts;
+    struct tm data;
+
+    ts = OPENSSL_gmtime(&t, &data);
+    if (ts == NULL)
+        return NULL;
+
+    if (offset_day || offset_sec) {
+        if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
+            return NULL;
+    }
+
+    return asn1_time_from_tm(s, ts, V_ASN1_GENERALIZEDTIME);
+}
+
+int ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm)
+{
+    if (tm->type != V_ASN1_GENERALIZEDTIME)
+        return 0;
+    return ASN1_TIME_print(bp, tm);
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_i2d_fp.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_i2d_fp.c
new file mode 100644
index 0000000..980c65a
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_i2d_fp.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright 1995-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1.h>
+
+#ifndef NO_OLD_ASN1
+
+# ifndef OPENSSL_NO_STDIO
+int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
+{
+    BIO *b;
+    int ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        ASN1err(ASN1_F_ASN1_I2D_FP, ERR_R_BUF_LIB);
+        return 0;
+    }
+    BIO_set_fp(b, out, BIO_NOCLOSE);
+    ret = ASN1_i2d_bio(i2d, b, x);
+    BIO_free(b);
+    return ret;
+}
+# endif
+
+int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x)
+{
+    char *b;
+    unsigned char *p;
+    int i, j = 0, n, ret = 1;
+
+    n = i2d(x, NULL);
+    if (n <= 0)
+        return 0;
+
+    b = OPENSSL_malloc(n);
+    if (b == NULL) {
+        ASN1err(ASN1_F_ASN1_I2D_BIO, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    p = (unsigned char *)b;
+    i2d(x, &p);
+
+    for (;;) {
+        i = BIO_write(out, &(b[j]), n);
+        if (i == n)
+            break;
+        if (i <= 0) {
+            ret = 0;
+            break;
+        }
+        j += i;
+        n -= i;
+    }
+    OPENSSL_free(b);
+    return ret;
+}
+
+#endif
+
+#ifndef OPENSSL_NO_STDIO
+int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x)
+{
+    BIO *b;
+    int ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        ASN1err(ASN1_F_ASN1_ITEM_I2D_FP, ERR_R_BUF_LIB);
+        return 0;
+    }
+    BIO_set_fp(b, out, BIO_NOCLOSE);
+    ret = ASN1_item_i2d_bio(it, b, x);
+    BIO_free(b);
+    return ret;
+}
+#endif
+
+int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x)
+{
+    unsigned char *b = NULL;
+    int i, j = 0, n, ret = 1;
+
+    n = ASN1_item_i2d(x, &b, it);
+    if (b == NULL) {
+        ASN1err(ASN1_F_ASN1_ITEM_I2D_BIO, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    for (;;) {
+        i = BIO_write(out, &(b[j]), n);
+        if (i == n)
+            break;
+        if (i <= 0) {
+            ret = 0;
+            break;
+        }
+        j += i;
+        n -= i;
+    }
+    OPENSSL_free(b);
+    return ret;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_int.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_int.c
new file mode 100644
index 0000000..9c1a9f5
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_int.c
@@ -0,0 +1,630 @@
+/*
+ * Copyright 1995-2017 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include "internal/numbers.h"
+#include <limits.h>
+#include <openssl/asn1.h>
+#include <openssl/bn.h>
+#include "asn1_local.h"
+
+ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x)
+{
+    return ASN1_STRING_dup(x);
+}
+
+int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
+{
+    int neg, ret;
+    /* Compare signs */
+    neg = x->type & V_ASN1_NEG;
+    if (neg != (y->type & V_ASN1_NEG)) {
+        if (neg)
+            return -1;
+        else
+            return 1;
+    }
+
+    ret = ASN1_STRING_cmp(x, y);
+
+    if (neg)
+        return -ret;
+    else
+        return ret;
+}
+
+/*-
+ * This converts a big endian buffer and sign into its content encoding.
+ * This is used for INTEGER and ENUMERATED types.
+ * The internal representation is an ASN1_STRING whose data is a big endian
+ * representation of the value, ignoring the sign. The sign is determined by
+ * the type: if type & V_ASN1_NEG is true it is negative, otherwise positive.
+ *
+ * Positive integers are no problem: they are almost the same as the DER
+ * encoding, except if the first byte is >= 0x80 we need to add a zero pad.
+ *
+ * Negative integers are a bit trickier...
+ * The DER representation of negative integers is in 2s complement form.
+ * The internal form is converted by complementing each octet and finally
+ * adding one to the result. This can be done less messily with a little trick.
+ * If the internal form has trailing zeroes then they will become FF by the
+ * complement and 0 by the add one (due to carry) so just copy as many trailing
+ * zeros to the destination as there are in the source. The carry will add one
+ * to the last none zero octet: so complement this octet and add one and finally
+ * complement any left over until you get to the start of the string.
+ *
+ * Padding is a little trickier too. If the first bytes is > 0x80 then we pad
+ * with 0xff. However if the first byte is 0x80 and one of the following bytes
+ * is non-zero we pad with 0xff. The reason for this distinction is that 0x80
+ * followed by optional zeros isn't padded.
+ */
+
+/*
+ * If |pad| is zero, the operation is effectively reduced to memcpy,
+ * and if |pad| is 0xff, then it performs two's complement, ~dst + 1.
+ * Note that in latter case sequence of zeros yields itself, and so
+ * does 0x80 followed by any number of zeros. These properties are
+ * used elsewhere below...
+ */
+static void twos_complement(unsigned char *dst, const unsigned char *src,
+                            size_t len, unsigned char pad)
+{
+    unsigned int carry = pad & 1;
+
+    /* Begin at the end of the encoding */
+    dst += len;
+    src += len;
+    /* two's complement value: ~value + 1 */
+    while (len-- != 0) {
+        *(--dst) = (unsigned char)(carry += *(--src) ^ pad);
+        carry >>= 8;
+    }
+}
+
+static size_t i2c_ibuf(const unsigned char *b, size_t blen, int neg,
+                       unsigned char **pp)
+{
+    unsigned int pad = 0;
+    size_t ret, i;
+    unsigned char *p, pb = 0;
+
+    if (b != NULL && blen) {
+        ret = blen;
+        i = b[0];
+        if (!neg && (i > 127)) {
+            pad = 1;
+            pb = 0;
+        } else if (neg) {
+            pb = 0xFF;
+            if (i > 128) {
+                pad = 1;
+            } else if (i == 128) {
+                /*
+                 * Special case [of minimal negative for given length]:
+                 * if any other bytes non zero we pad, otherwise we don't.
+                 */
+                for (pad = 0, i = 1; i < blen; i++)
+                    pad |= b[i];
+                pb = pad != 0 ? 0xffU : 0;
+                pad = pb & 1;
+            }
+        }
+        ret += pad;
+    } else {
+        ret = 1;
+        blen = 0;   /* reduce '(b == NULL || blen == 0)' to '(blen == 0)' */
+    }
+
+    if (pp == NULL || (p = *pp) == NULL)
+        return ret;
+
+    /*
+     * This magically handles all corner cases, such as '(b == NULL ||
+     * blen == 0)', non-negative value, "negative" zero, 0x80 followed
+     * by any number of zeros...
+     */
+    *p = pb;
+    p += pad;       /* yes, p[0] can be written twice, but it's little
+                     * price to pay for eliminated branches */
+    twos_complement(p, b, blen, pb);
+
+    *pp += ret;
+    return ret;
+}
+
+/*
+ * convert content octets into a big endian buffer. Returns the length
+ * of buffer or 0 on error: for malformed INTEGER. If output buffer is
+ * NULL just return length.
+ */
+
+static size_t c2i_ibuf(unsigned char *b, int *pneg,
+                       const unsigned char *p, size_t plen)
+{
+    int neg, pad;
+    /* Zero content length is illegal */
+    if (plen == 0) {
+        ASN1err(ASN1_F_C2I_IBUF, ASN1_R_ILLEGAL_ZERO_CONTENT);
+        return 0;
+    }
+    neg = p[0] & 0x80;
+    if (pneg)
+        *pneg = neg;
+    /* Handle common case where length is 1 octet separately */
+    if (plen == 1) {
+        if (b != NULL) {
+            if (neg)
+                b[0] = (p[0] ^ 0xFF) + 1;
+            else
+                b[0] = p[0];
+        }
+        return 1;
+    }
+
+    pad = 0;
+    if (p[0] == 0) {
+        pad = 1;
+    } else if (p[0] == 0xFF) {
+        size_t i;
+
+        /*
+         * Special case [of "one less minimal negative" for given length]:
+         * if any other bytes non zero it was padded, otherwise not.
+         */
+        for (pad = 0, i = 1; i < plen; i++)
+            pad |= p[i];
+        pad = pad != 0 ? 1 : 0;
+    }
+    /* reject illegal padding: first two octets MSB can't match */
+    if (pad && (neg == (p[1] & 0x80))) {
+        ASN1err(ASN1_F_C2I_IBUF, ASN1_R_ILLEGAL_PADDING);
+        return 0;
+    }
+
+    /* skip over pad */
+    p += pad;
+    plen -= pad;
+
+    if (b != NULL)
+        twos_complement(b, p, plen, neg ? 0xffU : 0);
+
+    return plen;
+}
+
+int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
+{
+    return i2c_ibuf(a->data, a->length, a->type & V_ASN1_NEG, pp);
+}
+
+/* Convert big endian buffer into uint64_t, return 0 on error */
+static int asn1_get_uint64(uint64_t *pr, const unsigned char *b, size_t blen)
+{
+    size_t i;
+    uint64_t r;
+
+    if (blen > sizeof(*pr)) {
+        ASN1err(ASN1_F_ASN1_GET_UINT64, ASN1_R_TOO_LARGE);
+        return 0;
+    }
+    if (b == NULL)
+        return 0;
+    for (r = 0, i = 0; i < blen; i++) {
+        r <<= 8;
+        r |= b[i];
+    }
+    *pr = r;
+    return 1;
+}
+
+/*
+ * Write uint64_t to big endian buffer and return offset to first
+ * written octet. In other words it returns offset in range from 0
+ * to 7, with 0 denoting 8 written octets and 7 - one.
+ */
+static size_t asn1_put_uint64(unsigned char b[sizeof(uint64_t)], uint64_t r)
+{
+    size_t off = sizeof(uint64_t);
+
+    do {
+        b[--off] = (unsigned char)r;
+    } while (r >>= 8);
+
+    return off;
+}
+
+/*
+ * Absolute value of INT64_MIN: we can't just use -INT64_MIN as gcc produces
+ * overflow warnings.
+ */
+#define ABS_INT64_MIN ((uint64_t)INT64_MAX + (-(INT64_MIN + INT64_MAX)))
+
+/* signed version of asn1_get_uint64 */
+static int asn1_get_int64(int64_t *pr, const unsigned char *b, size_t blen,
+                          int neg)
+{
+    uint64_t r;
+    if (asn1_get_uint64(&r, b, blen) == 0)
+        return 0;
+    if (neg) {
+        if (r <= INT64_MAX) {
+            /* Most significant bit is guaranteed to be clear, negation
+             * is guaranteed to be meaningful in platform-neutral sense. */
+            *pr = -(int64_t)r;
+        } else if (r == ABS_INT64_MIN) {
+            /* This never happens if INT64_MAX == ABS_INT64_MIN, e.g.
+             * on ones'-complement system. */
+            *pr = (int64_t)(0 - r);
+        } else {
+            ASN1err(ASN1_F_ASN1_GET_INT64, ASN1_R_TOO_SMALL);
+            return 0;
+        }
+    } else {
+        if (r <= INT64_MAX) {
+            *pr = (int64_t)r;
+        } else {
+            ASN1err(ASN1_F_ASN1_GET_INT64, ASN1_R_TOO_LARGE);
+            return 0;
+        }
+    }
+    return 1;
+}
+
+/* Convert ASN1 INTEGER content octets to ASN1_INTEGER structure */
+ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
+                               long len)
+{
+    ASN1_INTEGER *ret = NULL;
+    size_t r;
+    int neg;
+
+    r = c2i_ibuf(NULL, NULL, *pp, len);
+
+    if (r == 0)
+        return NULL;
+
+    if ((a == NULL) || ((*a) == NULL)) {
+        ret = ASN1_INTEGER_new();
+        if (ret == NULL)
+            return NULL;
+        ret->type = V_ASN1_INTEGER;
+    } else
+        ret = *a;
+
+    if (ASN1_STRING_set(ret, NULL, r) == 0)
+        goto err;
+
+    c2i_ibuf(ret->data, &neg, *pp, len);
+
+    if (neg)
+        ret->type |= V_ASN1_NEG;
+
+    *pp += len;
+    if (a != NULL)
+        (*a) = ret;
+    return ret;
+ err:
+    ASN1err(ASN1_F_C2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
+    if ((a == NULL) || (*a != ret))
+        ASN1_INTEGER_free(ret);
+    return NULL;
+}
+
+static int asn1_string_get_int64(int64_t *pr, const ASN1_STRING *a, int itype)
+{
+    if (a == NULL) {
+        ASN1err(ASN1_F_ASN1_STRING_GET_INT64, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    if ((a->type & ~V_ASN1_NEG) != itype) {
+        ASN1err(ASN1_F_ASN1_STRING_GET_INT64, ASN1_R_WRONG_INTEGER_TYPE);
+        return 0;
+    }
+    return asn1_get_int64(pr, a->data, a->length, a->type & V_ASN1_NEG);
+}
+
+static int asn1_string_set_int64(ASN1_STRING *a, int64_t r, int itype)
+{
+    unsigned char tbuf[sizeof(r)];
+    size_t off;
+
+    a->type = itype;
+    if (r < 0) {
+        /* Most obvious '-r' triggers undefined behaviour for most
+         * common INT64_MIN. Even though below '0 - (uint64_t)r' can
+         * appear two's-complement centric, it does produce correct/
+         * expected result even on one's-complement. This is because
+         * cast to unsigned has to change bit pattern... */
+        off = asn1_put_uint64(tbuf, 0 - (uint64_t)r);
+        a->type |= V_ASN1_NEG;
+    } else {
+        off = asn1_put_uint64(tbuf, r);
+        a->type &= ~V_ASN1_NEG;
+    }
+    return ASN1_STRING_set(a, tbuf + off, sizeof(tbuf) - off);
+}
+
+static int asn1_string_get_uint64(uint64_t *pr, const ASN1_STRING *a,
+                                  int itype)
+{
+    if (a == NULL) {
+        ASN1err(ASN1_F_ASN1_STRING_GET_UINT64, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    if ((a->type & ~V_ASN1_NEG) != itype) {
+        ASN1err(ASN1_F_ASN1_STRING_GET_UINT64, ASN1_R_WRONG_INTEGER_TYPE);
+        return 0;
+    }
+    if (a->type & V_ASN1_NEG) {
+        ASN1err(ASN1_F_ASN1_STRING_GET_UINT64, ASN1_R_ILLEGAL_NEGATIVE_VALUE);
+        return 0;
+    }
+    return asn1_get_uint64(pr, a->data, a->length);
+}
+
+static int asn1_string_set_uint64(ASN1_STRING *a, uint64_t r, int itype)
+{
+    unsigned char tbuf[sizeof(r)];
+    size_t off;
+
+    a->type = itype;
+    off = asn1_put_uint64(tbuf, r);
+    return ASN1_STRING_set(a, tbuf + off, sizeof(tbuf) - off);
+}
+
+/*
+ * This is a version of d2i_ASN1_INTEGER that ignores the sign bit of ASN1
+ * integers: some broken software can encode a positive INTEGER with its MSB
+ * set as negative (it doesn't add a padding zero).
+ */
+
+ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
+                                long length)
+{
+    ASN1_INTEGER *ret = NULL;
+    const unsigned char *p;
+    unsigned char *s;
+    long len;
+    int inf, tag, xclass;
+    int i;
+
+    if ((a == NULL) || ((*a) == NULL)) {
+        if ((ret = ASN1_INTEGER_new()) == NULL)
+            return NULL;
+        ret->type = V_ASN1_INTEGER;
+    } else
+        ret = (*a);
+
+    p = *pp;
+    inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+    if (inf & 0x80) {
+        i = ASN1_R_BAD_OBJECT_HEADER;
+        goto err;
+    }
+
+    if (tag != V_ASN1_INTEGER) {
+        i = ASN1_R_EXPECTING_AN_INTEGER;
+        goto err;
+    }
+
+    /*
+     * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies
+     * a missing NULL parameter.
+     */
+    s = OPENSSL_malloc((int)len + 1);
+    if (s == NULL) {
+        i = ERR_R_MALLOC_FAILURE;
+        goto err;
+    }
+    ret->type = V_ASN1_INTEGER;
+    if (len) {
+        if ((*p == 0) && (len != 1)) {
+            p++;
+            len--;
+        }
+        memcpy(s, p, (int)len);
+        p += len;
+    }
+
+    OPENSSL_free(ret->data);
+    ret->data = s;
+    ret->length = (int)len;
+    if (a != NULL)
+        (*a) = ret;
+    *pp = p;
+    return ret;
+ err:
+    ASN1err(ASN1_F_D2I_ASN1_UINTEGER, i);
+    if ((a == NULL) || (*a != ret))
+        ASN1_INTEGER_free(ret);
+    return NULL;
+}
+
+static ASN1_STRING *bn_to_asn1_string(const BIGNUM *bn, ASN1_STRING *ai,
+                                      int atype)
+{
+    ASN1_INTEGER *ret;
+    int len;
+
+    if (ai == NULL) {
+        ret = ASN1_STRING_type_new(atype);
+    } else {
+        ret = ai;
+        ret->type = atype;
+    }
+
+    if (ret == NULL) {
+        ASN1err(ASN1_F_BN_TO_ASN1_STRING, ERR_R_NESTED_ASN1_ERROR);
+        goto err;
+    }
+
+    if (BN_is_negative(bn) && !BN_is_zero(bn))
+        ret->type |= V_ASN1_NEG_INTEGER;
+
+    len = BN_num_bytes(bn);
+
+    if (len == 0)
+        len = 1;
+
+    if (ASN1_STRING_set(ret, NULL, len) == 0) {
+        ASN1err(ASN1_F_BN_TO_ASN1_STRING, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    /* Correct zero case */
+    if (BN_is_zero(bn))
+        ret->data[0] = 0;
+    else
+        len = BN_bn2bin(bn, ret->data);
+    ret->length = len;
+    return ret;
+ err:
+    if (ret != ai)
+        ASN1_INTEGER_free(ret);
+    return NULL;
+}
+
+static BIGNUM *asn1_string_to_bn(const ASN1_INTEGER *ai, BIGNUM *bn,
+                                 int itype)
+{
+    BIGNUM *ret;
+
+    if ((ai->type & ~V_ASN1_NEG) != itype) {
+        ASN1err(ASN1_F_ASN1_STRING_TO_BN, ASN1_R_WRONG_INTEGER_TYPE);
+        return NULL;
+    }
+
+    ret = BN_bin2bn(ai->data, ai->length, bn);
+    if (ret == NULL) {
+        ASN1err(ASN1_F_ASN1_STRING_TO_BN, ASN1_R_BN_LIB);
+        return NULL;
+    }
+    if (ai->type & V_ASN1_NEG)
+        BN_set_negative(ret, 1);
+    return ret;
+}
+
+int ASN1_INTEGER_get_int64(int64_t *pr, const ASN1_INTEGER *a)
+{
+    return asn1_string_get_int64(pr, a, V_ASN1_INTEGER);
+}
+
+int ASN1_INTEGER_set_int64(ASN1_INTEGER *a, int64_t r)
+{
+    return asn1_string_set_int64(a, r, V_ASN1_INTEGER);
+}
+
+int ASN1_INTEGER_get_uint64(uint64_t *pr, const ASN1_INTEGER *a)
+{
+    return asn1_string_get_uint64(pr, a, V_ASN1_INTEGER);
+}
+
+int ASN1_INTEGER_set_uint64(ASN1_INTEGER *a, uint64_t r)
+{
+    return asn1_string_set_uint64(a, r, V_ASN1_INTEGER);
+}
+
+int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
+{
+    return ASN1_INTEGER_set_int64(a, v);
+}
+
+long ASN1_INTEGER_get(const ASN1_INTEGER *a)
+{
+    int i;
+    int64_t r;
+    if (a == NULL)
+        return 0;
+    i = ASN1_INTEGER_get_int64(&r, a);
+    if (i == 0)
+        return -1;
+    if (r > LONG_MAX || r < LONG_MIN)
+        return -1;
+    return (long)r;
+}
+
+ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
+{
+    return bn_to_asn1_string(bn, ai, V_ASN1_INTEGER);
+}
+
+BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
+{
+    return asn1_string_to_bn(ai, bn, V_ASN1_INTEGER);
+}
+
+int ASN1_ENUMERATED_get_int64(int64_t *pr, const ASN1_ENUMERATED *a)
+{
+    return asn1_string_get_int64(pr, a, V_ASN1_ENUMERATED);
+}
+
+int ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED *a, int64_t r)
+{
+    return asn1_string_set_int64(a, r, V_ASN1_ENUMERATED);
+}
+
+int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
+{
+    return ASN1_ENUMERATED_set_int64(a, v);
+}
+
+long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a)
+{
+    int i;
+    int64_t r;
+    if (a == NULL)
+        return 0;
+    if ((a->type & ~V_ASN1_NEG) != V_ASN1_ENUMERATED)
+        return -1;
+    if (a->length > (int)sizeof(long))
+        return 0xffffffffL;
+    i = ASN1_ENUMERATED_get_int64(&r, a);
+    if (i == 0)
+        return -1;
+    if (r > LONG_MAX || r < LONG_MIN)
+        return -1;
+    return (long)r;
+}
+
+ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai)
+{
+    return bn_to_asn1_string(bn, ai, V_ASN1_ENUMERATED);
+}
+
+BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn)
+{
+    return asn1_string_to_bn(ai, bn, V_ASN1_ENUMERATED);
+}
+
+/* Internal functions used by x_int64.c */
+int c2i_uint64_int(uint64_t *ret, int *neg, const unsigned char **pp, long len)
+{
+    unsigned char buf[sizeof(uint64_t)];
+    size_t buflen;
+
+    buflen = c2i_ibuf(NULL, NULL, *pp, len);
+    if (buflen == 0)
+        return 0;
+    if (buflen > sizeof(uint64_t)) {
+        ASN1err(ASN1_F_C2I_UINT64_INT, ASN1_R_TOO_LARGE);
+        return 0;
+    }
+    (void)c2i_ibuf(buf, neg, *pp, len);
+    return asn1_get_uint64(ret, buf, buflen);
+}
+
+int i2c_uint64_int(unsigned char *p, uint64_t r, int neg)
+{
+    unsigned char buf[sizeof(uint64_t)];
+    size_t off;
+
+    off = asn1_put_uint64(buf, r);
+    return i2c_ibuf(buf + off, sizeof(buf) - off, neg, &p);
+}
+
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_mbstr.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_mbstr.c
new file mode 100644
index 0000000..bdb697a
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_mbstr.c
@@ -0,0 +1,343 @@
+/*
+ * Copyright 1999-2017 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "crypto/ctype.h"
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+
+static int traverse_string(const unsigned char *p, int len, int inform,
+                           int (*rfunc) (unsigned long value, void *in),
+                           void *arg);
+static int in_utf8(unsigned long value, void *arg);
+static int out_utf8(unsigned long value, void *arg);
+static int type_str(unsigned long value, void *arg);
+static int cpy_asc(unsigned long value, void *arg);
+static int cpy_bmp(unsigned long value, void *arg);
+static int cpy_univ(unsigned long value, void *arg);
+static int cpy_utf8(unsigned long value, void *arg);
+
+/*
+ * These functions take a string in UTF8, ASCII or multibyte form and a mask
+ * of permissible ASN1 string types. It then works out the minimal type
+ * (using the order Numeric < Printable < IA5 < T61 < BMP < Universal < UTF8)
+ * and creates a string of the correct type with the supplied data. Yes this is
+ * horrible: it has to be :-( The 'ncopy' form checks minimum and maximum
+ * size limits too.
+ */
+
+int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
+                       int inform, unsigned long mask)
+{
+    return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);
+}
+
+int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
+                        int inform, unsigned long mask,
+                        long minsize, long maxsize)
+{
+    int str_type;
+    int ret;
+    char free_out;
+    int outform, outlen = 0;
+    ASN1_STRING *dest;
+    unsigned char *p;
+    int nchar;
+    char strbuf[32];
+    int (*cpyfunc) (unsigned long, void *) = NULL;
+    if (len == -1)
+        len = strlen((const char *)in);
+    if (!mask)
+        mask = DIRSTRING_TYPE;
+
+    /* First do a string check and work out the number of characters */
+    switch (inform) {
+
+    case MBSTRING_BMP:
+        if (len & 1) {
+            ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
+                    ASN1_R_INVALID_BMPSTRING_LENGTH);
+            return -1;
+        }
+        nchar = len >> 1;
+        break;
+
+    case MBSTRING_UNIV:
+        if (len & 3) {
+            ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
+                    ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
+            return -1;
+        }
+        nchar = len >> 2;
+        break;
+
+    case MBSTRING_UTF8:
+        nchar = 0;
+        /* This counts the characters and does utf8 syntax checking */
+        ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
+        if (ret < 0) {
+            ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_INVALID_UTF8STRING);
+            return -1;
+        }
+        break;
+
+    case MBSTRING_ASC:
+        nchar = len;
+        break;
+
+    default:
+        ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_UNKNOWN_FORMAT);
+        return -1;
+    }
+
+    if ((minsize > 0) && (nchar < minsize)) {
+        ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_SHORT);
+        BIO_snprintf(strbuf, sizeof(strbuf), "%ld", minsize);
+        ERR_add_error_data(2, "minsize=", strbuf);
+        return -1;
+    }
+
+    if ((maxsize > 0) && (nchar > maxsize)) {
+        ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_LONG);
+        BIO_snprintf(strbuf, sizeof(strbuf), "%ld", maxsize);
+        ERR_add_error_data(2, "maxsize=", strbuf);
+        return -1;
+    }
+
+    /* Now work out minimal type (if any) */
+    if (traverse_string(in, len, inform, type_str, &mask) < 0) {
+        ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_ILLEGAL_CHARACTERS);
+        return -1;
+    }
+
+    /* Now work out output format and string type */
+    outform = MBSTRING_ASC;
+    if (mask & B_ASN1_NUMERICSTRING)
+        str_type = V_ASN1_NUMERICSTRING;
+    else if (mask & B_ASN1_PRINTABLESTRING)
+        str_type = V_ASN1_PRINTABLESTRING;
+    else if (mask & B_ASN1_IA5STRING)
+        str_type = V_ASN1_IA5STRING;
+    else if (mask & B_ASN1_T61STRING)
+        str_type = V_ASN1_T61STRING;
+    else if (mask & B_ASN1_BMPSTRING) {
+        str_type = V_ASN1_BMPSTRING;
+        outform = MBSTRING_BMP;
+    } else if (mask & B_ASN1_UNIVERSALSTRING) {
+        str_type = V_ASN1_UNIVERSALSTRING;
+        outform = MBSTRING_UNIV;
+    } else {
+        str_type = V_ASN1_UTF8STRING;
+        outform = MBSTRING_UTF8;
+    }
+    if (!out)
+        return str_type;
+    if (*out) {
+        free_out = 0;
+        dest = *out;
+        OPENSSL_free(dest->data);
+        dest->data = NULL;
+        dest->length = 0;
+        dest->type = str_type;
+    } else {
+        free_out = 1;
+        dest = ASN1_STRING_type_new(str_type);
+        if (dest == NULL) {
+            ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE);
+            return -1;
+        }
+        *out = dest;
+    }
+    /* If both the same type just copy across */
+    if (inform == outform) {
+        if (!ASN1_STRING_set(dest, in, len)) {
+            ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE);
+            return -1;
+        }
+        return str_type;
+    }
+
+    /* Work out how much space the destination will need */
+    switch (outform) {
+    case MBSTRING_ASC:
+        outlen = nchar;
+        cpyfunc = cpy_asc;
+        break;
+
+    case MBSTRING_BMP:
+        outlen = nchar << 1;
+        cpyfunc = cpy_bmp;
+        break;
+
+    case MBSTRING_UNIV:
+        outlen = nchar << 2;
+        cpyfunc = cpy_univ;
+        break;
+
+    case MBSTRING_UTF8:
+        outlen = 0;
+        traverse_string(in, len, inform, out_utf8, &outlen);
+        cpyfunc = cpy_utf8;
+        break;
+    }
+    if ((p = OPENSSL_malloc(outlen + 1)) == NULL) {
+        if (free_out)
+            ASN1_STRING_free(dest);
+        ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE);
+        return -1;
+    }
+    dest->length = outlen;
+    dest->data = p;
+    p[outlen] = 0;
+    traverse_string(in, len, inform, cpyfunc, &p);
+    return str_type;
+}
+
+/*
+ * This function traverses a string and passes the value of each character to
+ * an optional function along with a void * argument.
+ */
+
+static int traverse_string(const unsigned char *p, int len, int inform,
+                           int (*rfunc) (unsigned long value, void *in),
+                           void *arg)
+{
+    unsigned long value;
+    int ret;
+    while (len) {
+        if (inform == MBSTRING_ASC) {
+            value = *p++;
+            len--;
+        } else if (inform == MBSTRING_BMP) {
+            value = *p++ << 8;
+            value |= *p++;
+            len -= 2;
+        } else if (inform == MBSTRING_UNIV) {
+            value = ((unsigned long)*p++) << 24;
+            value |= ((unsigned long)*p++) << 16;
+            value |= *p++ << 8;
+            value |= *p++;
+            len -= 4;
+        } else {
+            ret = UTF8_getc(p, len, &value);
+            if (ret < 0)
+                return -1;
+            len -= ret;
+            p += ret;
+        }
+        if (rfunc) {
+            ret = rfunc(value, arg);
+            if (ret <= 0)
+                return ret;
+        }
+    }
+    return 1;
+}
+
+/* Various utility functions for traverse_string */
+
+/* Just count number of characters */
+
+static int in_utf8(unsigned long value, void *arg)
+{
+    int *nchar;
+    nchar = arg;
+    (*nchar)++;
+    return 1;
+}
+
+/* Determine size of output as a UTF8 String */
+
+static int out_utf8(unsigned long value, void *arg)
+{
+    int *outlen;
+    outlen = arg;
+    *outlen += UTF8_putc(NULL, -1, value);
+    return 1;
+}
+
+/*
+ * Determine the "type" of a string: check each character against a supplied
+ * "mask".
+ */
+
+static int type_str(unsigned long value, void *arg)
+{
+    unsigned long types = *((unsigned long *)arg);
+    const int native = value > INT_MAX ? INT_MAX : ossl_fromascii(value);
+
+    if ((types & B_ASN1_NUMERICSTRING) && !(ossl_isdigit(native)
+                                            || native == ' '))
+        types &= ~B_ASN1_NUMERICSTRING;
+    if ((types & B_ASN1_PRINTABLESTRING) && !ossl_isasn1print(native))
+        types &= ~B_ASN1_PRINTABLESTRING;
+    if ((types & B_ASN1_IA5STRING) && !ossl_isascii(native))
+        types &= ~B_ASN1_IA5STRING;
+    if ((types & B_ASN1_T61STRING) && (value > 0xff))
+        types &= ~B_ASN1_T61STRING;
+    if ((types & B_ASN1_BMPSTRING) && (value > 0xffff))
+        types &= ~B_ASN1_BMPSTRING;
+    if (!types)
+        return -1;
+    *((unsigned long *)arg) = types;
+    return 1;
+}
+
+/* Copy one byte per character ASCII like strings */
+
+static int cpy_asc(unsigned long value, void *arg)
+{
+    unsigned char **p, *q;
+    p = arg;
+    q = *p;
+    *q = (unsigned char)value;
+    (*p)++;
+    return 1;
+}
+
+/* Copy two byte per character BMPStrings */
+
+static int cpy_bmp(unsigned long value, void *arg)
+{
+    unsigned char **p, *q;
+    p = arg;
+    q = *p;
+    *q++ = (unsigned char)((value >> 8) & 0xff);
+    *q = (unsigned char)(value & 0xff);
+    *p += 2;
+    return 1;
+}
+
+/* Copy four byte per character UniversalStrings */
+
+static int cpy_univ(unsigned long value, void *arg)
+{
+    unsigned char **p, *q;
+    p = arg;
+    q = *p;
+    *q++ = (unsigned char)((value >> 24) & 0xff);
+    *q++ = (unsigned char)((value >> 16) & 0xff);
+    *q++ = (unsigned char)((value >> 8) & 0xff);
+    *q = (unsigned char)(value & 0xff);
+    *p += 4;
+    return 1;
+}
+
+/* Copy to a UTF8String */
+
+static int cpy_utf8(unsigned long value, void *arg)
+{
+    unsigned char **p;
+    int ret;
+    p = arg;
+    /* We already know there is enough room so pass 0xff as the length */
+    ret = UTF8_putc(*p, 0xff, value);
+    *p += ret;
+    return 1;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_object.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_object.c
new file mode 100644
index 0000000..8ade9e5
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_object.c
@@ -0,0 +1,386 @@
+/*
+ * Copyright 1995-2021 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <limits.h>
+#include "crypto/ctype.h"
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/bn.h>
+#include "crypto/asn1.h"
+#include "asn1_local.h"
+
+int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp)
+{
+    unsigned char *p, *allocated = NULL;
+    int objsize;
+
+    if ((a == NULL) || (a->data == NULL))
+        return 0;
+
+    objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT);
+    if (pp == NULL || objsize == -1)
+        return objsize;
+
+    if (*pp == NULL) {
+        if ((p = allocated = OPENSSL_malloc(objsize)) == NULL) {
+            ASN1err(ASN1_F_I2D_ASN1_OBJECT, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+    } else {
+        p = *pp;
+    }
+
+    ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
+    memcpy(p, a->data, a->length);
+
+    /*
+     * If a new buffer was allocated, just return it back.
+     * If not, return the incremented buffer pointer.
+     */
+    *pp = allocated != NULL ? allocated : p + a->length;
+    return objsize;
+}
+
+int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
+{
+    int i, first, len = 0, c, use_bn;
+    char ftmp[24], *tmp = ftmp;
+    int tmpsize = sizeof(ftmp);
+    const char *p;
+    unsigned long l;
+    BIGNUM *bl = NULL;
+
+    if (num == 0)
+        return 0;
+    else if (num == -1)
+        num = strlen(buf);
+
+    p = buf;
+    c = *(p++);
+    num--;
+    if ((c >= '0') && (c <= '2')) {
+        first = c - '0';
+    } else {
+        ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_FIRST_NUM_TOO_LARGE);
+        goto err;
+    }
+
+    if (num <= 0) {
+        ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_MISSING_SECOND_NUMBER);
+        goto err;
+    }
+    c = *(p++);
+    num--;
+    for (;;) {
+        if (num <= 0)
+            break;
+        if ((c != '.') && (c != ' ')) {
+            ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_SEPARATOR);
+            goto err;
+        }
+        l = 0;
+        use_bn = 0;
+        for (;;) {
+            if (num <= 0)
+                break;
+            num--;
+            c = *(p++);
+            if ((c == ' ') || (c == '.'))
+                break;
+            if (!ossl_isdigit(c)) {
+                ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_DIGIT);
+                goto err;
+            }
+            if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) {
+                use_bn = 1;
+                if (bl == NULL)
+                    bl = BN_new();
+                if (bl == NULL || !BN_set_word(bl, l))
+                    goto err;
+            }
+            if (use_bn) {
+                if (!BN_mul_word(bl, 10L)
+                    || !BN_add_word(bl, c - '0'))
+                    goto err;
+            } else
+                l = l * 10L + (long)(c - '0');
+        }
+        if (len == 0) {
+            if ((first < 2) && (l >= 40)) {
+                ASN1err(ASN1_F_A2D_ASN1_OBJECT,
+                        ASN1_R_SECOND_NUMBER_TOO_LARGE);
+                goto err;
+            }
+            if (use_bn) {
+                if (!BN_add_word(bl, first * 40))
+                    goto err;
+            } else
+                l += (long)first *40;
+        }
+        i = 0;
+        if (use_bn) {
+            int blsize;
+            blsize = BN_num_bits(bl);
+            blsize = (blsize + 6) / 7;
+            if (blsize > tmpsize) {
+                if (tmp != ftmp)
+                    OPENSSL_free(tmp);
+                tmpsize = blsize + 32;
+                tmp = OPENSSL_malloc(tmpsize);
+                if (tmp == NULL)
+                    goto err;
+            }
+            while (blsize--) {
+                BN_ULONG t = BN_div_word(bl, 0x80L);
+                if (t == (BN_ULONG)-1)
+                    goto err;
+                tmp[i++] = (unsigned char)t;
+            }
+        } else {
+
+            for (;;) {
+                tmp[i++] = (unsigned char)l & 0x7f;
+                l >>= 7L;
+                if (l == 0L)
+                    break;
+            }
+
+        }
+        if (out != NULL) {
+            if (len + i > olen) {
+                ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_BUFFER_TOO_SMALL);
+                goto err;
+            }
+            while (--i > 0)
+                out[len++] = tmp[i] | 0x80;
+            out[len++] = tmp[0];
+        } else
+            len += i;
+    }
+    if (tmp != ftmp)
+        OPENSSL_free(tmp);
+    BN_free(bl);
+    return len;
+ err:
+    if (tmp != ftmp)
+        OPENSSL_free(tmp);
+    BN_free(bl);
+    return 0;
+}
+
+int i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a)
+{
+    return OBJ_obj2txt(buf, buf_len, a, 0);
+}
+
+int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a)
+{
+    char buf[80], *p = buf;
+    int i;
+
+    if ((a == NULL) || (a->data == NULL))
+        return BIO_write(bp, "NULL", 4);
+    i = i2t_ASN1_OBJECT(buf, sizeof(buf), a);
+    if (i > (int)(sizeof(buf) - 1)) {
+        if ((p = OPENSSL_malloc(i + 1)) == NULL) {
+            ASN1err(ASN1_F_I2A_ASN1_OBJECT, ERR_R_MALLOC_FAILURE);
+            return -1;
+        }
+        i2t_ASN1_OBJECT(p, i + 1, a);
+    }
+    if (i <= 0) {
+        i = BIO_write(bp, "<INVALID>", 9);
+        i += BIO_dump(bp, (const char *)a->data, a->length);
+        return i;
+    }
+    BIO_write(bp, p, i);
+    if (p != buf)
+        OPENSSL_free(p);
+    return i;
+}
+
+ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
+                             long length)
+{
+    const unsigned char *p;
+    long len;
+    int tag, xclass;
+    int inf, i;
+    ASN1_OBJECT *ret = NULL;
+    p = *pp;
+    inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+    if (inf & 0x80) {
+        i = ASN1_R_BAD_OBJECT_HEADER;
+        goto err;
+    }
+
+    if (tag != V_ASN1_OBJECT) {
+        i = ASN1_R_EXPECTING_AN_OBJECT;
+        goto err;
+    }
+    ret = c2i_ASN1_OBJECT(a, &p, len);
+    if (ret)
+        *pp = p;
+    return ret;
+ err:
+    ASN1err(ASN1_F_D2I_ASN1_OBJECT, i);
+    return NULL;
+}
+
+ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
+                             long len)
+{
+    ASN1_OBJECT *ret = NULL, tobj;
+    const unsigned char *p;
+    unsigned char *data;
+    int i, length;
+
+    /*
+     * Sanity check OID encoding. Need at least one content octet. MSB must
+     * be clear in the last octet. can't have leading 0x80 in subidentifiers,
+     * see: X.690 8.19.2
+     */
+    if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
+        p[len - 1] & 0x80) {
+        ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
+        return NULL;
+    }
+    /* Now 0 < len <= INT_MAX, so the cast is safe. */
+    length = (int)len;
+    /*
+     * Try to lookup OID in table: these are all valid encodings so if we get
+     * a match we know the OID is valid.
+     */
+    tobj.nid = NID_undef;
+    tobj.data = p;
+    tobj.length = length;
+    tobj.flags = 0;
+    i = OBJ_obj2nid(&tobj);
+    if (i != NID_undef) {
+        /*
+         * Return shared registered OID object: this improves efficiency
+         * because we don't have to return a dynamically allocated OID
+         * and NID lookups can use the cached value.
+         */
+        ret = OBJ_nid2obj(i);
+        if (a) {
+            ASN1_OBJECT_free(*a);
+            *a = ret;
+        }
+        *pp += len;
+        return ret;
+    }
+    for (i = 0; i < length; i++, p++) {
+        if (*p == 0x80 && (!i || !(p[-1] & 0x80))) {
+            ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
+            return NULL;
+        }
+    }
+
+    if ((a == NULL) || ((*a) == NULL) ||
+        !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
+        if ((ret = ASN1_OBJECT_new()) == NULL)
+            return NULL;
+    } else {
+        ret = (*a);
+    }
+
+    p = *pp;
+    /* detach data from object */
+    data = (unsigned char *)ret->data;
+    ret->data = NULL;
+    /* once detached we can change it */
+    if ((data == NULL) || (ret->length < length)) {
+        ret->length = 0;
+        OPENSSL_free(data);
+        data = OPENSSL_malloc(length);
+        if (data == NULL) {
+            i = ERR_R_MALLOC_FAILURE;
+            goto err;
+        }
+        ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
+    }
+    memcpy(data, p, length);
+    /* If there are dynamic strings, free them here, and clear the flag */
+    if ((ret->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) != 0) {
+        OPENSSL_free((char *)ret->sn);
+        OPENSSL_free((char *)ret->ln);
+        ret->flags &= ~ASN1_OBJECT_FLAG_DYNAMIC_STRINGS;
+    }
+    /* reattach data to object, after which it remains const */
+    ret->data = data;
+    ret->length = length;
+    ret->sn = NULL;
+    ret->ln = NULL;
+    /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
+    p += length;
+
+    if (a != NULL)
+        (*a) = ret;
+    *pp = p;
+    return ret;
+ err:
+    ASN1err(ASN1_F_C2I_ASN1_OBJECT, i);
+    if ((a == NULL) || (*a != ret))
+        ASN1_OBJECT_free(ret);
+    return NULL;
+}
+
+ASN1_OBJECT *ASN1_OBJECT_new(void)
+{
+    ASN1_OBJECT *ret;
+
+    ret = OPENSSL_zalloc(sizeof(*ret));
+    if (ret == NULL) {
+        ASN1err(ASN1_F_ASN1_OBJECT_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    ret->flags = ASN1_OBJECT_FLAG_DYNAMIC;
+    return ret;
+}
+
+void ASN1_OBJECT_free(ASN1_OBJECT *a)
+{
+    if (a == NULL)
+        return;
+    if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) {
+#ifndef CONST_STRICT            /* disable purely for compile-time strict
+                                 * const checking. Doing this on a "real"
+                                 * compile will cause memory leaks */
+        OPENSSL_free((void*)a->sn);
+        OPENSSL_free((void*)a->ln);
+#endif
+        a->sn = a->ln = NULL;
+    }
+    if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) {
+        OPENSSL_free((void*)a->data);
+        a->data = NULL;
+        a->length = 0;
+    }
+    if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
+        OPENSSL_free(a);
+}
+
+ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
+                                const char *sn, const char *ln)
+{
+    ASN1_OBJECT o;
+
+    o.sn = sn;
+    o.ln = ln;
+    o.data = data;
+    o.nid = nid;
+    o.length = len;
+    o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
+        ASN1_OBJECT_FLAG_DYNAMIC_DATA;
+    return OBJ_dup(&o);
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_octet.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_octet.c
new file mode 100644
index 0000000..2e1205c
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_octet.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright 1995-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+
+ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x)
+{
+    return ASN1_STRING_dup(x);
+}
+
+int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a,
+                          const ASN1_OCTET_STRING *b)
+{
+    return ASN1_STRING_cmp(a, b);
+}
+
+int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d,
+                          int len)
+{
+    return ASN1_STRING_set(x, d, len);
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_print.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_print.c
new file mode 100644
index 0000000..3790e82
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_print.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright 1995-2021 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "crypto/ctype.h"
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+
+int ASN1_PRINTABLE_type(const unsigned char *s, int len)
+{
+    int c;
+    int ia5 = 0;
+    int t61 = 0;
+
+    if (s == NULL)
+        return V_ASN1_PRINTABLESTRING;
+
+    if (len < 0)
+        len = strlen((const char *)s);
+
+    while (len-- > 0) {
+        c = *(s++);
+        if (!ossl_isasn1print(c))
+            ia5 = 1;
+        if (!ossl_isascii(c))
+            t61 = 1;
+    }
+    if (t61)
+        return V_ASN1_T61STRING;
+    if (ia5)
+        return V_ASN1_IA5STRING;
+    return V_ASN1_PRINTABLESTRING;
+}
+
+int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s)
+{
+    int i;
+    unsigned char *p;
+
+    if (s->type != V_ASN1_UNIVERSALSTRING)
+        return 0;
+    if ((s->length % 4) != 0)
+        return 0;
+    p = s->data;
+    for (i = 0; i < s->length; i += 4) {
+        if ((p[0] != '\0') || (p[1] != '\0') || (p[2] != '\0'))
+            break;
+        else
+            p += 4;
+    }
+    if (i < s->length)
+        return 0;
+    p = s->data;
+    for (i = 3; i < s->length; i += 4) {
+        *(p++) = s->data[i];
+    }
+    *(p) = '\0';
+    s->length /= 4;
+    s->type = ASN1_PRINTABLE_type(s->data, s->length);
+    return 1;
+}
+
+int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v)
+{
+    int i, n;
+    char buf[80];
+    const char *p;
+
+    if (v == NULL)
+        return 0;
+    n = 0;
+    p = (const char *)v->data;
+    for (i = 0; i < v->length; i++) {
+        if ((p[i] > '~') || ((p[i] < ' ') &&
+                             (p[i] != '\n') && (p[i] != '\r')))
+            buf[n] = '.';
+        else
+            buf[n] = p[i];
+        n++;
+        if (n >= 80) {
+            if (BIO_write(bp, buf, n) <= 0)
+                return 0;
+            n = 0;
+        }
+    }
+    if (n > 0)
+        if (BIO_write(bp, buf, n) <= 0)
+            return 0;
+    return 1;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_sign.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_sign.c
new file mode 100644
index 0000000..72381b6
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_sign.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright 1995-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <sys/types.h>
+
+#include "internal/cryptlib.h"
+
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include "crypto/asn1.h"
+#include "crypto/evp.h"
+
+#ifndef NO_ASN1_OLD
+
+int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
+              ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey,
+              const EVP_MD *type)
+{
+    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+    unsigned char *p, *buf_in = NULL, *buf_out = NULL;
+    int i, inl = 0, outl = 0;
+    size_t inll = 0, outll = 0;
+    X509_ALGOR *a;
+
+    if (ctx == NULL) {
+        ASN1err(ASN1_F_ASN1_SIGN, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    for (i = 0; i < 2; i++) {
+        if (i == 0)
+            a = algor1;
+        else
+            a = algor2;
+        if (a == NULL)
+            continue;
+        if (type->pkey_type == NID_dsaWithSHA1) {
+            /*
+             * special case: RFC 2459 tells us to omit 'parameters' with
+             * id-dsa-with-sha1
+             */
+            ASN1_TYPE_free(a->parameter);
+            a->parameter = NULL;
+        } else if ((a->parameter == NULL) ||
+                   (a->parameter->type != V_ASN1_NULL)) {
+            ASN1_TYPE_free(a->parameter);
+            if ((a->parameter = ASN1_TYPE_new()) == NULL)
+                goto err;
+            a->parameter->type = V_ASN1_NULL;
+        }
+        ASN1_OBJECT_free(a->algorithm);
+        a->algorithm = OBJ_nid2obj(type->pkey_type);
+        if (a->algorithm == NULL) {
+            ASN1err(ASN1_F_ASN1_SIGN, ASN1_R_UNKNOWN_OBJECT_TYPE);
+            goto err;
+        }
+        if (a->algorithm->length == 0) {
+            ASN1err(ASN1_F_ASN1_SIGN,
+                    ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
+            goto err;
+        }
+    }
+    inl = i2d(data, NULL);
+    if (inl <= 0) {
+        ASN1err(ASN1_F_ASN1_SIGN, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+    inll = (size_t)inl;
+    buf_in = OPENSSL_malloc(inll);
+    outll = outl = EVP_PKEY_size(pkey);
+    buf_out = OPENSSL_malloc(outll);
+    if (buf_in == NULL || buf_out == NULL) {
+        outl = 0;
+        ASN1err(ASN1_F_ASN1_SIGN, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    p = buf_in;
+
+    i2d(data, &p);
+    if (!EVP_SignInit_ex(ctx, type, NULL)
+        || !EVP_SignUpdate(ctx, (unsigned char *)buf_in, inl)
+        || !EVP_SignFinal(ctx, (unsigned char *)buf_out,
+                          (unsigned int *)&outl, pkey)) {
+        outl = 0;
+        ASN1err(ASN1_F_ASN1_SIGN, ERR_R_EVP_LIB);
+        goto err;
+    }
+    OPENSSL_free(signature->data);
+    signature->data = buf_out;
+    buf_out = NULL;
+    signature->length = outl;
+    /*
+     * In the interests of compatibility, I'll make sure that the bit string
+     * has a 'not-used bits' value of 0
+     */
+    signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+    signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+ err:
+    EVP_MD_CTX_free(ctx);
+    OPENSSL_clear_free((char *)buf_in, inll);
+    OPENSSL_clear_free((char *)buf_out, outll);
+    return outl;
+}
+
+#endif
+
+int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1,
+                   X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn,
+                   EVP_PKEY *pkey, const EVP_MD *type)
+{
+    int rv;
+    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+
+    if (ctx == NULL) {
+        ASN1err(ASN1_F_ASN1_ITEM_SIGN, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    if (!EVP_DigestSignInit(ctx, NULL, type, NULL, pkey)) {
+        EVP_MD_CTX_free(ctx);
+        return 0;
+    }
+
+    rv = ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, ctx);
+
+    EVP_MD_CTX_free(ctx);
+    return rv;
+}
+
+int ASN1_item_sign_ctx(const ASN1_ITEM *it,
+                       X509_ALGOR *algor1, X509_ALGOR *algor2,
+                       ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx)
+{
+    const EVP_MD *type;
+    EVP_PKEY *pkey;
+    unsigned char *buf_in = NULL, *buf_out = NULL;
+    size_t inl = 0, outl = 0, outll = 0;
+    int signid, paramtype, buf_len = 0;
+    int rv;
+
+    type = EVP_MD_CTX_md(ctx);
+    pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx));
+
+    if (pkey == NULL) {
+        ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED);
+        goto err;
+    }
+
+    if (pkey->ameth == NULL) {
+        ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
+        goto err;
+    }
+
+    if (pkey->ameth->item_sign) {
+        rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2, signature);
+        if (rv == 1)
+            outl = signature->length;
+        /*-
+         * Return value meanings:
+         * <=0: error.
+         *   1: method does everything.
+         *   2: carry on as normal.
+         *   3: ASN1 method sets algorithm identifiers: just sign.
+         */
+        if (rv <= 0)
+            ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
+        if (rv <= 1)
+            goto err;
+    } else {
+        rv = 2;
+    }
+
+    if (rv == 2) {
+        if (type == NULL) {
+            ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED);
+            goto err;
+        }
+        if (!OBJ_find_sigid_by_algs(&signid,
+                                    EVP_MD_nid(type),
+                                    pkey->ameth->pkey_id)) {
+            ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,
+                    ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
+            goto err;
+        }
+
+        if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL)
+            paramtype = V_ASN1_NULL;
+        else
+            paramtype = V_ASN1_UNDEF;
+
+        if (algor1)
+            X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL);
+        if (algor2)
+            X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL);
+
+    }
+
+    buf_len = ASN1_item_i2d(asn, &buf_in, it);
+    if (buf_len <= 0) {
+        outl = 0;
+        ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+    inl = buf_len;
+    outll = outl = EVP_PKEY_size(pkey);
+    buf_out = OPENSSL_malloc(outll);
+    if (buf_in == NULL || buf_out == NULL) {
+        outl = 0;
+        ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (!EVP_DigestSign(ctx, buf_out, &outl, buf_in, inl)) {
+        outl = 0;
+        ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
+        goto err;
+    }
+    OPENSSL_free(signature->data);
+    signature->data = buf_out;
+    buf_out = NULL;
+    signature->length = outl;
+    /*
+     * In the interests of compatibility, I'll make sure that the bit string
+     * has a 'not-used bits' value of 0
+     */
+    signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+    signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+ err:
+    OPENSSL_clear_free((char *)buf_in, inl);
+    OPENSSL_clear_free((char *)buf_out, outll);
+    return outl;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_strex.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_strex.c
new file mode 100644
index 0000000..284dde2
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_strex.c
@@ -0,0 +1,628 @@
+/*
+ * Copyright 2000-2021 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "internal/cryptlib.h"
+#include "crypto/asn1.h"
+#include <openssl/crypto.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+
+#include "charmap.h"
+
+/*
+ * ASN1_STRING_print_ex() and X509_NAME_print_ex(). Enhanced string and name
+ * printing routines handling multibyte characters, RFC2253 and a host of
+ * other options.
+ */
+
+#define CHARTYPE_BS_ESC         (ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253)
+
+#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \
+                  ASN1_STRFLGS_ESC_2254 | \
+                  ASN1_STRFLGS_ESC_QUOTE | \
+                  ASN1_STRFLGS_ESC_CTRL | \
+                  ASN1_STRFLGS_ESC_MSB)
+
+/*
+ * Three IO functions for sending data to memory, a BIO and and a FILE
+ * pointer.
+ */
+static int send_bio_chars(void *arg, const void *buf, int len)
+{
+    if (!arg)
+        return 1;
+    if (BIO_write(arg, buf, len) != len)
+        return 0;
+    return 1;
+}
+
+#ifndef OPENSSL_NO_STDIO
+static int send_fp_chars(void *arg, const void *buf, int len)
+{
+    if (!arg)
+        return 1;
+    if (fwrite(buf, 1, len, arg) != (unsigned int)len)
+        return 0;
+    return 1;
+}
+#endif
+
+typedef int char_io (void *arg, const void *buf, int len);
+
+/*
+ * This function handles display of strings, one character at a time. It is
+ * passed an unsigned long for each character because it could come from 2 or
+ * even 4 byte forms.
+ */
+
+static int do_esc_char(unsigned long c, unsigned short flags, char *do_quotes,
+                       char_io *io_ch, void *arg)
+{
+    unsigned short chflgs;
+    unsigned char chtmp;
+    char tmphex[HEX_SIZE(long) + 3];
+
+    if (c > 0xffffffffL)
+        return -1;
+    if (c > 0xffff) {
+        BIO_snprintf(tmphex, sizeof(tmphex), "\\W%08lX", c);
+        if (!io_ch(arg, tmphex, 10))
+            return -1;
+        return 10;
+    }
+    if (c > 0xff) {
+        BIO_snprintf(tmphex, sizeof(tmphex), "\\U%04lX", c);
+        if (!io_ch(arg, tmphex, 6))
+            return -1;
+        return 6;
+    }
+    chtmp = (unsigned char)c;
+    if (chtmp > 0x7f)
+        chflgs = flags & ASN1_STRFLGS_ESC_MSB;
+    else
+        chflgs = char_type[chtmp] & flags;
+    if (chflgs & CHARTYPE_BS_ESC) {
+        /* If we don't escape with quotes, signal we need quotes */
+        if (chflgs & ASN1_STRFLGS_ESC_QUOTE) {
+            if (do_quotes)
+                *do_quotes = 1;
+            if (!io_ch(arg, &chtmp, 1))
+                return -1;
+            return 1;
+        }
+        if (!io_ch(arg, "\\", 1))
+            return -1;
+        if (!io_ch(arg, &chtmp, 1))
+            return -1;
+        return 2;
+    }
+    if (chflgs & (ASN1_STRFLGS_ESC_CTRL
+                  | ASN1_STRFLGS_ESC_MSB
+                  | ASN1_STRFLGS_ESC_2254)) {
+        BIO_snprintf(tmphex, 11, "\\%02X", chtmp);
+        if (!io_ch(arg, tmphex, 3))
+            return -1;
+        return 3;
+    }
+    /*
+     * If we get this far and do any escaping at all must escape the escape
+     * character itself: backslash.
+     */
+    if (chtmp == '\\' && (flags & ESC_FLAGS)) {
+        if (!io_ch(arg, "\\\\", 2))
+            return -1;
+        return 2;
+    }
+    if (!io_ch(arg, &chtmp, 1))
+        return -1;
+    return 1;
+}
+
+#define BUF_TYPE_WIDTH_MASK     0x7
+#define BUF_TYPE_CONVUTF8       0x8
+
+/*
+ * This function sends each character in a buffer to do_esc_char(). It
+ * interprets the content formats and converts to or from UTF8 as
+ * appropriate.
+ */
+
+static int do_buf(unsigned char *buf, int buflen,
+                  int type, unsigned short flags, char *quotes, char_io *io_ch,
+                  void *arg)
+{
+    int i, outlen, len, charwidth;
+    unsigned short orflags;
+    unsigned char *p, *q;
+    unsigned long c;
+
+    p = buf;
+    q = buf + buflen;
+    outlen = 0;
+    charwidth = type & BUF_TYPE_WIDTH_MASK;
+
+    switch (charwidth) {
+    case 4:
+        if (buflen & 3) {
+            ASN1err(ASN1_F_DO_BUF, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
+            return -1;
+        }
+        break;
+    case 2:
+        if (buflen & 1) {
+            ASN1err(ASN1_F_DO_BUF, ASN1_R_INVALID_BMPSTRING_LENGTH);
+            return -1;
+        }
+        break;
+    default:
+        break;
+    }
+
+    while (p != q) {
+        if (p == buf && flags & ASN1_STRFLGS_ESC_2253)
+            orflags = CHARTYPE_FIRST_ESC_2253;
+        else
+            orflags = 0;
+
+        switch (charwidth) {
+        case 4:
+            c = ((unsigned long)*p++) << 24;
+            c |= ((unsigned long)*p++) << 16;
+            c |= ((unsigned long)*p++) << 8;
+            c |= *p++;
+            break;
+
+        case 2:
+            c = ((unsigned long)*p++) << 8;
+            c |= *p++;
+            break;
+
+        case 1:
+            c = *p++;
+            break;
+
+        case 0:
+            i = UTF8_getc(p, buflen, &c);
+            if (i < 0)
+                return -1;      /* Invalid UTF8String */
+            buflen -= i;
+            p += i;
+            break;
+        default:
+            return -1;          /* invalid width */
+        }
+        if (p == q && flags & ASN1_STRFLGS_ESC_2253)
+            orflags = CHARTYPE_LAST_ESC_2253;
+        if (type & BUF_TYPE_CONVUTF8) {
+            unsigned char utfbuf[6];
+            int utflen;
+            utflen = UTF8_putc(utfbuf, sizeof(utfbuf), c);
+            for (i = 0; i < utflen; i++) {
+                /*
+                 * We don't need to worry about setting orflags correctly
+                 * because if utflen==1 its value will be correct anyway
+                 * otherwise each character will be > 0x7f and so the
+                 * character will never be escaped on first and last.
+                 */
+                len = do_esc_char(utfbuf[i], flags | orflags, quotes,
+                                  io_ch, arg);
+                if (len < 0)
+                    return -1;
+                outlen += len;
+            }
+        } else {
+            len = do_esc_char(c, flags | orflags, quotes,
+                              io_ch, arg);
+            if (len < 0)
+                return -1;
+            outlen += len;
+        }
+    }
+    return outlen;
+}
+
+/* This function hex dumps a buffer of characters */
+
+static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf,
+                       int buflen)
+{
+    static const char hexdig[] = "0123456789ABCDEF";
+    unsigned char *p, *q;
+    char hextmp[2];
+    if (arg) {
+        p = buf;
+        q = buf + buflen;
+        while (p != q) {
+            hextmp[0] = hexdig[*p >> 4];
+            hextmp[1] = hexdig[*p & 0xf];
+            if (!io_ch(arg, hextmp, 2))
+                return -1;
+            p++;
+        }
+    }
+    return buflen << 1;
+}
+
+/*
+ * "dump" a string. This is done when the type is unknown, or the flags
+ * request it. We can either dump the content octets or the entire DER
+ * encoding. This uses the RFC2253 #01234 format.
+ */
+
+static int do_dump(unsigned long lflags, char_io *io_ch, void *arg,
+                   const ASN1_STRING *str)
+{
+    /*
+     * Placing the ASN1_STRING in a temp ASN1_TYPE allows the DER encoding to
+     * readily obtained
+     */
+    ASN1_TYPE t;
+    unsigned char *der_buf, *p;
+    int outlen, der_len;
+
+    if (!io_ch(arg, "#", 1))
+        return -1;
+    /* If we don't dump DER encoding just dump content octets */
+    if (!(lflags & ASN1_STRFLGS_DUMP_DER)) {
+        outlen = do_hex_dump(io_ch, arg, str->data, str->length);
+        if (outlen < 0)
+            return -1;
+        return outlen + 1;
+    }
+    t.type = str->type;
+    t.value.ptr = (char *)str;
+    der_len = i2d_ASN1_TYPE(&t, NULL);
+    if (der_len <= 0)
+        return -1;
+    if ((der_buf = OPENSSL_malloc(der_len)) == NULL) {
+        ASN1err(ASN1_F_DO_DUMP, ERR_R_MALLOC_FAILURE);
+        return -1;
+    }
+    p = der_buf;
+    i2d_ASN1_TYPE(&t, &p);
+    outlen = do_hex_dump(io_ch, arg, der_buf, der_len);
+    OPENSSL_free(der_buf);
+    if (outlen < 0)
+        return -1;
+    return outlen + 1;
+}
+
+/*
+ * Lookup table to convert tags to character widths, 0 = UTF8 encoded, -1 is
+ * used for non string types otherwise it is the number of bytes per
+ * character
+ */
+
+static const signed char tag2nbyte[] = {
+    -1, -1, -1, -1, -1,         /* 0-4 */
+    -1, -1, -1, -1, -1,         /* 5-9 */
+    -1, -1,                     /* 10-11 */
+     0,                         /* 12 V_ASN1_UTF8STRING */
+    -1, -1, -1, -1, -1,         /* 13-17 */
+     1,                         /* 18 V_ASN1_NUMERICSTRING */
+     1,                         /* 19 V_ASN1_PRINTABLESTRING */
+     1,                         /* 20 V_ASN1_T61STRING */
+    -1,                         /* 21 */
+     1,                         /* 22 V_ASN1_IA5STRING */
+     1,                         /* 23 V_ASN1_UTCTIME */
+     1,                         /* 24 V_ASN1_GENERALIZEDTIME */
+    -1,                         /* 25 */
+     1,                         /* 26 V_ASN1_ISO64STRING */
+    -1,                         /* 27 */
+     4,                         /* 28 V_ASN1_UNIVERSALSTRING */
+    -1,                         /* 29 */
+     2                          /* 30 V_ASN1_BMPSTRING */
+};
+
+/*
+ * This is the main function, print out an ASN1_STRING taking note of various
+ * escape and display options. Returns number of characters written or -1 if
+ * an error occurred.
+ */
+
+static int do_print_ex(char_io *io_ch, void *arg, unsigned long lflags,
+                       const ASN1_STRING *str)
+{
+    int outlen, len;
+    int type;
+    char quotes;
+    unsigned short flags;
+    quotes = 0;
+    /* Keep a copy of escape flags */
+    flags = (unsigned short)(lflags & ESC_FLAGS);
+
+    type = str->type;
+
+    outlen = 0;
+
+    if (lflags & ASN1_STRFLGS_SHOW_TYPE) {
+        const char *tagname;
+        tagname = ASN1_tag2str(type);
+        outlen += strlen(tagname);
+        if (!io_ch(arg, tagname, outlen) || !io_ch(arg, ":", 1))
+            return -1;
+        outlen++;
+    }
+
+    /* Decide what to do with type, either dump content or display it */
+
+    /* Dump everything */
+    if (lflags & ASN1_STRFLGS_DUMP_ALL)
+        type = -1;
+    /* Ignore the string type */
+    else if (lflags & ASN1_STRFLGS_IGNORE_TYPE)
+        type = 1;
+    else {
+        /* Else determine width based on type */
+        if ((type > 0) && (type < 31))
+            type = tag2nbyte[type];
+        else
+            type = -1;
+        if ((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN))
+            type = 1;
+    }
+
+    if (type == -1) {
+        len = do_dump(lflags, io_ch, arg, str);
+        if (len < 0)
+            return -1;
+        outlen += len;
+        return outlen;
+    }
+
+    if (lflags & ASN1_STRFLGS_UTF8_CONVERT) {
+        /*
+         * Note: if string is UTF8 and we want to convert to UTF8 then we
+         * just interpret it as 1 byte per character to avoid converting
+         * twice.
+         */
+        if (!type)
+            type = 1;
+        else
+            type |= BUF_TYPE_CONVUTF8;
+    }
+
+    len = do_buf(str->data, str->length, type, flags, &quotes, io_ch, NULL);
+    if (len < 0)
+        return -1;
+    outlen += len;
+    if (quotes)
+        outlen += 2;
+    if (!arg)
+        return outlen;
+    if (quotes && !io_ch(arg, "\"", 1))
+        return -1;
+    if (do_buf(str->data, str->length, type, flags, NULL, io_ch, arg) < 0)
+        return -1;
+    if (quotes && !io_ch(arg, "\"", 1))
+        return -1;
+    return outlen;
+}
+
+/* Used for line indenting: print 'indent' spaces */
+
+static int do_indent(char_io *io_ch, void *arg, int indent)
+{
+    int i;
+    for (i = 0; i < indent; i++)
+        if (!io_ch(arg, " ", 1))
+            return 0;
+    return 1;
+}
+
+#define FN_WIDTH_LN     25
+#define FN_WIDTH_SN     10
+
+static int do_name_ex(char_io *io_ch, void *arg, const X509_NAME *n,
+                      int indent, unsigned long flags)
+{
+    int i, prev = -1, orflags, cnt;
+    int fn_opt, fn_nid;
+    ASN1_OBJECT *fn;
+    const ASN1_STRING *val;
+    const X509_NAME_ENTRY *ent;
+    char objtmp[80];
+    const char *objbuf;
+    int outlen, len;
+    char *sep_dn, *sep_mv, *sep_eq;
+    int sep_dn_len, sep_mv_len, sep_eq_len;
+    if (indent < 0)
+        indent = 0;
+    outlen = indent;
+    if (!do_indent(io_ch, arg, indent))
+        return -1;
+    switch (flags & XN_FLAG_SEP_MASK) {
+    case XN_FLAG_SEP_MULTILINE:
+        sep_dn = "\n";
+        sep_dn_len = 1;
+        sep_mv = " + ";
+        sep_mv_len = 3;
+        break;
+
+    case XN_FLAG_SEP_COMMA_PLUS:
+        sep_dn = ",";
+        sep_dn_len = 1;
+        sep_mv = "+";
+        sep_mv_len = 1;
+        indent = 0;
+        break;
+
+    case XN_FLAG_SEP_CPLUS_SPC:
+        sep_dn = ", ";
+        sep_dn_len = 2;
+        sep_mv = " + ";
+        sep_mv_len = 3;
+        indent = 0;
+        break;
+
+    case XN_FLAG_SEP_SPLUS_SPC:
+        sep_dn = "; ";
+        sep_dn_len = 2;
+        sep_mv = " + ";
+        sep_mv_len = 3;
+        indent = 0;
+        break;
+
+    default:
+        return -1;
+    }
+
+    if (flags & XN_FLAG_SPC_EQ) {
+        sep_eq = " = ";
+        sep_eq_len = 3;
+    } else {
+        sep_eq = "=";
+        sep_eq_len = 1;
+    }
+
+    fn_opt = flags & XN_FLAG_FN_MASK;
+
+    cnt = X509_NAME_entry_count(n);
+    for (i = 0; i < cnt; i++) {
+        if (flags & XN_FLAG_DN_REV)
+            ent = X509_NAME_get_entry(n, cnt - i - 1);
+        else
+            ent = X509_NAME_get_entry(n, i);
+        if (prev != -1) {
+            if (prev == X509_NAME_ENTRY_set(ent)) {
+                if (!io_ch(arg, sep_mv, sep_mv_len))
+                    return -1;
+                outlen += sep_mv_len;
+            } else {
+                if (!io_ch(arg, sep_dn, sep_dn_len))
+                    return -1;
+                outlen += sep_dn_len;
+                if (!do_indent(io_ch, arg, indent))
+                    return -1;
+                outlen += indent;
+            }
+        }
+        prev = X509_NAME_ENTRY_set(ent);
+        fn = X509_NAME_ENTRY_get_object(ent);
+        val = X509_NAME_ENTRY_get_data(ent);
+        fn_nid = OBJ_obj2nid(fn);
+        if (fn_opt != XN_FLAG_FN_NONE) {
+            int objlen, fld_len;
+            if ((fn_opt == XN_FLAG_FN_OID) || (fn_nid == NID_undef)) {
+                OBJ_obj2txt(objtmp, sizeof(objtmp), fn, 1);
+                fld_len = 0;    /* XXX: what should this be? */
+                objbuf = objtmp;
+            } else {
+                if (fn_opt == XN_FLAG_FN_SN) {
+                    fld_len = FN_WIDTH_SN;
+                    objbuf = OBJ_nid2sn(fn_nid);
+                } else if (fn_opt == XN_FLAG_FN_LN) {
+                    fld_len = FN_WIDTH_LN;
+                    objbuf = OBJ_nid2ln(fn_nid);
+                } else {
+                    fld_len = 0; /* XXX: what should this be? */
+                    objbuf = "";
+                }
+            }
+            objlen = strlen(objbuf);
+            if (!io_ch(arg, objbuf, objlen))
+                return -1;
+            if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) {
+                if (!do_indent(io_ch, arg, fld_len - objlen))
+                    return -1;
+                outlen += fld_len - objlen;
+            }
+            if (!io_ch(arg, sep_eq, sep_eq_len))
+                return -1;
+            outlen += objlen + sep_eq_len;
+        }
+        /*
+         * If the field name is unknown then fix up the DER dump flag. We
+         * might want to limit this further so it will DER dump on anything
+         * other than a few 'standard' fields.
+         */
+        if ((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS))
+            orflags = ASN1_STRFLGS_DUMP_ALL;
+        else
+            orflags = 0;
+
+        len = do_print_ex(io_ch, arg, flags | orflags, val);
+        if (len < 0)
+            return -1;
+        outlen += len;
+    }
+    return outlen;
+}
+
+/* Wrappers round the main functions */
+
+int X509_NAME_print_ex(BIO *out, const X509_NAME *nm, int indent,
+                       unsigned long flags)
+{
+    if (flags == XN_FLAG_COMPAT)
+        return X509_NAME_print(out, nm, indent);
+    return do_name_ex(send_bio_chars, out, nm, indent, flags);
+}
+
+#ifndef OPENSSL_NO_STDIO
+int X509_NAME_print_ex_fp(FILE *fp, const X509_NAME *nm, int indent,
+                          unsigned long flags)
+{
+    if (flags == XN_FLAG_COMPAT) {
+        BIO *btmp;
+        int ret;
+        btmp = BIO_new_fp(fp, BIO_NOCLOSE);
+        if (!btmp)
+            return -1;
+        ret = X509_NAME_print(btmp, nm, indent);
+        BIO_free(btmp);
+        return ret;
+    }
+    return do_name_ex(send_fp_chars, fp, nm, indent, flags);
+}
+#endif
+
+int ASN1_STRING_print_ex(BIO *out, const ASN1_STRING *str, unsigned long flags)
+{
+    return do_print_ex(send_bio_chars, out, flags, str);
+}
+
+#ifndef OPENSSL_NO_STDIO
+int ASN1_STRING_print_ex_fp(FILE *fp, const ASN1_STRING *str, unsigned long flags)
+{
+    return do_print_ex(send_fp_chars, fp, flags, str);
+}
+#endif
+
+/*
+ * Utility function: convert any string type to UTF8, returns number of bytes
+ * in output string or a negative error code
+ */
+
+int ASN1_STRING_to_UTF8(unsigned char **out, const ASN1_STRING *in)
+{
+    ASN1_STRING stmp, *str = &stmp;
+    int mbflag, type, ret;
+    if (!in)
+        return -1;
+    type = in->type;
+    if ((type < 0) || (type > 30))
+        return -1;
+    mbflag = tag2nbyte[type];
+    if (mbflag == -1)
+        return -1;
+    mbflag |= MBSTRING_FLAG;
+    stmp.data = NULL;
+    stmp.length = 0;
+    stmp.flags = 0;
+    ret =
+        ASN1_mbstring_copy(&str, in->data, in->length, mbflag,
+                           B_ASN1_UTF8STRING);
+    if (ret < 0)
+        return ret;
+    *out = stmp.data;
+    return stmp.length;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_strnid.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_strnid.c
new file mode 100644
index 0000000..f19a9de
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_strnid.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright 1999-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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+
+static STACK_OF(ASN1_STRING_TABLE) *stable = NULL;
+static void st_free(ASN1_STRING_TABLE *tbl);
+static int sk_table_cmp(const ASN1_STRING_TABLE *const *a,
+                        const ASN1_STRING_TABLE *const *b);
+
+/*
+ * This is the global mask for the mbstring functions: this is use to mask
+ * out certain types (such as BMPString and UTF8String) because certain
+ * software (e.g. Netscape) has problems with them.
+ */
+
+static unsigned long global_mask = B_ASN1_UTF8STRING;
+
+void ASN1_STRING_set_default_mask(unsigned long mask)
+{
+    global_mask = mask;
+}
+
+unsigned long ASN1_STRING_get_default_mask(void)
+{
+    return global_mask;
+}
+
+/*-
+ * This function sets the default to various "flavours" of configuration.
+ * based on an ASCII string. Currently this is:
+ * MASK:XXXX : a numerical mask value.
+ * nobmp : Don't use BMPStrings (just Printable, T61).
+ * pkix : PKIX recommendation in RFC2459.
+ * utf8only : only use UTF8Strings (RFC2459 recommendation for 2004).
+ * default:   the default value, Printable, T61, BMP.
+ */
+
+int ASN1_STRING_set_default_mask_asc(const char *p)
+{
+    unsigned long mask;
+    char *end;
+
+    if (strncmp(p, "MASK:", 5) == 0) {
+        if (!p[5])
+            return 0;
+        mask = strtoul(p + 5, &end, 0);
+        if (*end)
+            return 0;
+    } else if (strcmp(p, "nombstr") == 0)
+        mask = ~((unsigned long)(B_ASN1_BMPSTRING | B_ASN1_UTF8STRING));
+    else if (strcmp(p, "pkix") == 0)
+        mask = ~((unsigned long)B_ASN1_T61STRING);
+    else if (strcmp(p, "utf8only") == 0)
+        mask = B_ASN1_UTF8STRING;
+    else if (strcmp(p, "default") == 0)
+        mask = 0xFFFFFFFFL;
+    else
+        return 0;
+    ASN1_STRING_set_default_mask(mask);
+    return 1;
+}
+
+/*
+ * The following function generates an ASN1_STRING based on limits in a
+ * table. Frequently the types and length of an ASN1_STRING are restricted by
+ * a corresponding OID. For example certificates and certificate requests.
+ */
+
+ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out,
+                                    const unsigned char *in, int inlen,
+                                    int inform, int nid)
+{
+    ASN1_STRING_TABLE *tbl;
+    ASN1_STRING *str = NULL;
+    unsigned long mask;
+    int ret;
+
+    if (out == NULL)
+        out = &str;
+    tbl = ASN1_STRING_TABLE_get(nid);
+    if (tbl != NULL) {
+        mask = tbl->mask;
+        if (!(tbl->flags & STABLE_NO_MASK))
+            mask &= global_mask;
+        ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
+                                  tbl->minsize, tbl->maxsize);
+    } else {
+        ret = ASN1_mbstring_copy(out, in, inlen, inform,
+                                 DIRSTRING_TYPE & global_mask);
+    }
+    if (ret <= 0)
+        return NULL;
+    return *out;
+}
+
+/*
+ * Now the tables and helper functions for the string table:
+ */
+
+#include "tbl_standard.h"
+
+static int sk_table_cmp(const ASN1_STRING_TABLE *const *a,
+                        const ASN1_STRING_TABLE *const *b)
+{
+    return (*a)->nid - (*b)->nid;
+}
+
+DECLARE_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
+
+static int table_cmp(const ASN1_STRING_TABLE *a, const ASN1_STRING_TABLE *b)
+{
+    return a->nid - b->nid;
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
+
+ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid)
+{
+    int idx;
+    ASN1_STRING_TABLE fnd;
+
+    fnd.nid = nid;
+    if (stable) {
+        idx = sk_ASN1_STRING_TABLE_find(stable, &fnd);
+        if (idx >= 0)
+            return sk_ASN1_STRING_TABLE_value(stable, idx);
+    }
+    return OBJ_bsearch_table(&fnd, tbl_standard, OSSL_NELEM(tbl_standard));
+}
+
+/*
+ * Return a string table pointer which can be modified: either directly from
+ * table or a copy of an internal value added to the table.
+ */
+
+static ASN1_STRING_TABLE *stable_get(int nid)
+{
+    ASN1_STRING_TABLE *tmp, *rv;
+
+    /* Always need a string table so allocate one if NULL */
+    if (stable == NULL) {
+        stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
+        if (stable == NULL)
+            return NULL;
+    }
+    tmp = ASN1_STRING_TABLE_get(nid);
+    if (tmp != NULL && tmp->flags & STABLE_FLAGS_MALLOC)
+        return tmp;
+    if ((rv = OPENSSL_zalloc(sizeof(*rv))) == NULL) {
+        ASN1err(ASN1_F_STABLE_GET, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    if (!sk_ASN1_STRING_TABLE_push(stable, rv)) {
+        OPENSSL_free(rv);
+        return NULL;
+    }
+    if (tmp != NULL) {
+        rv->nid = tmp->nid;
+        rv->minsize = tmp->minsize;
+        rv->maxsize = tmp->maxsize;
+        rv->mask = tmp->mask;
+        rv->flags = tmp->flags | STABLE_FLAGS_MALLOC;
+    } else {
+        rv->nid = nid;
+        rv->minsize = -1;
+        rv->maxsize = -1;
+        rv->flags = STABLE_FLAGS_MALLOC;
+    }
+    return rv;
+}
+
+int ASN1_STRING_TABLE_add(int nid,
+                          long minsize, long maxsize, unsigned long mask,
+                          unsigned long flags)
+{
+    ASN1_STRING_TABLE *tmp;
+
+    tmp = stable_get(nid);
+    if (tmp == NULL) {
+        ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    if (minsize >= 0)
+        tmp->minsize = minsize;
+    if (maxsize >= 0)
+        tmp->maxsize = maxsize;
+    if (mask)
+        tmp->mask = mask;
+    if (flags)
+        tmp->flags = STABLE_FLAGS_MALLOC | flags;
+    return 1;
+}
+
+void ASN1_STRING_TABLE_cleanup(void)
+{
+    STACK_OF(ASN1_STRING_TABLE) *tmp;
+
+    tmp = stable;
+    if (tmp == NULL)
+        return;
+    stable = NULL;
+    sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);
+}
+
+static void st_free(ASN1_STRING_TABLE *tbl)
+{
+    if (tbl->flags & STABLE_FLAGS_MALLOC)
+        OPENSSL_free(tbl);
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_time.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_time.c
new file mode 100644
index 0000000..54e0de1
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_time.c
@@ -0,0 +1,558 @@
+/*
+ * Copyright 1999-2019 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*-
+ * This is an implementation of the ASN1 Time structure which is:
+ *    Time ::= CHOICE {
+ *      utcTime        UTCTime,
+ *      generalTime    GeneralizedTime }
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "crypto/ctype.h"
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include "asn1_local.h"
+
+IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME)
+
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_TIME)
+
+static int is_utc(const int year)
+{
+    if (50 <= year && year <= 149)
+        return 1;
+    return 0;
+}
+
+static int leap_year(const int year)
+{
+    if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))
+        return 1;
+    return 0;
+}
+
+/*
+ * Compute the day of the week and the day of the year from the year, month
+ * and day.  The day of the year is straightforward, the day of the week uses
+ * a form of Zeller's congruence.  For this months start with March and are
+ * numbered 4 through 15.
+ */
+static void determine_days(struct tm *tm)
+{
+    static const int ydays[12] = {
+        0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
+    };
+    int y = tm->tm_year + 1900;
+    int m = tm->tm_mon;
+    int d = tm->tm_mday;
+    int c;
+
+    tm->tm_yday = ydays[m] + d - 1;
+    if (m >= 2) {
+        /* March and onwards can be one day further into the year */
+        tm->tm_yday += leap_year(y);
+        m += 2;
+    } else {
+        /* Treat January and February as part of the previous year */
+        m += 14;
+        y--;
+    }
+    c = y / 100;
+    y %= 100;
+    /* Zeller's congruence */
+    tm->tm_wday = (d + (13 * m) / 5 + y + y / 4 + c / 4 + 5 * c + 6) % 7;
+}
+
+int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d)
+{
+    static const int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 };
+    static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 };
+    static const int mdays[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+    char *a;
+    int n, i, i2, l, o, min_l = 11, strict = 0, end = 6, btz = 5, md;
+    struct tm tmp;
+#if defined(CHARSET_EBCDIC)
+    const char upper_z = 0x5A, num_zero = 0x30, period = 0x2E, minus = 0x2D, plus = 0x2B;
+#else
+    const char upper_z = 'Z', num_zero = '0', period = '.', minus = '-', plus = '+';
+#endif
+    /*
+     * ASN1_STRING_FLAG_X509_TIME is used to enforce RFC 5280
+     * time string format, in which:
+     *
+     * 1. "seconds" is a 'MUST'
+     * 2. "Zulu" timezone is a 'MUST'
+     * 3. "+|-" is not allowed to indicate a time zone
+     */
+    if (d->type == V_ASN1_UTCTIME) {
+        if (d->flags & ASN1_STRING_FLAG_X509_TIME) {
+            min_l = 13;
+            strict = 1;
+        }
+    } else if (d->type == V_ASN1_GENERALIZEDTIME) {
+        end = 7;
+        btz = 6;
+        if (d->flags & ASN1_STRING_FLAG_X509_TIME) {
+            min_l = 15;
+            strict = 1;
+        } else {
+            min_l = 13;
+        }
+    } else {
+        return 0;
+    }
+
+    l = d->length;
+    a = (char *)d->data;
+    o = 0;
+    memset(&tmp, 0, sizeof(tmp));
+
+    /*
+     * GENERALIZEDTIME is similar to UTCTIME except the year is represented
+     * as YYYY. This stuff treats everything as a two digit field so make
+     * first two fields 00 to 99
+     */
+
+    if (l < min_l)
+        goto err;
+    for (i = 0; i < end; i++) {
+        if (!strict && (i == btz) && ((a[o] == upper_z) || (a[o] == plus) || (a[o] == minus))) {
+            i++;
+            break;
+        }
+        if (!ascii_isdigit(a[o]))
+            goto err;
+        n = a[o] - num_zero;
+        /* incomplete 2-digital number */
+        if (++o == l)
+            goto err;
+
+        if (!ascii_isdigit(a[o]))
+            goto err;
+        n = (n * 10) + a[o] - num_zero;
+        /* no more bytes to read, but we haven't seen time-zone yet */
+        if (++o == l)
+            goto err;
+
+        i2 = (d->type == V_ASN1_UTCTIME) ? i + 1 : i;
+
+        if ((n < min[i2]) || (n > max[i2]))
+            goto err;
+        switch (i2) {
+        case 0:
+            /* UTC will never be here */
+            tmp.tm_year = n * 100 - 1900;
+            break;
+        case 1:
+            if (d->type == V_ASN1_UTCTIME)
+                tmp.tm_year = n < 50 ? n + 100 : n;
+            else
+                tmp.tm_year += n;
+            break;
+        case 2:
+            tmp.tm_mon = n - 1;
+            break;
+        case 3:
+            /* check if tm_mday is valid in tm_mon */
+            if (tmp.tm_mon == 1) {
+                /* it's February */
+                md = mdays[1] + leap_year(tmp.tm_year + 1900);
+            } else {
+                md = mdays[tmp.tm_mon];
+            }
+            if (n > md)
+                goto err;
+            tmp.tm_mday = n;
+            determine_days(&tmp);
+            break;
+        case 4:
+            tmp.tm_hour = n;
+            break;
+        case 5:
+            tmp.tm_min = n;
+            break;
+        case 6:
+            tmp.tm_sec = n;
+            break;
+        }
+    }
+
+    /*
+     * Optional fractional seconds: decimal point followed by one or more
+     * digits.
+     */
+    if (d->type == V_ASN1_GENERALIZEDTIME && a[o] == period) {
+        if (strict)
+            /* RFC 5280 forbids fractional seconds */
+            goto err;
+        if (++o == l)
+            goto err;
+        i = o;
+        while ((o < l) && ascii_isdigit(a[o]))
+            o++;
+        /* Must have at least one digit after decimal point */
+        if (i == o)
+            goto err;
+        /* no more bytes to read, but we haven't seen time-zone yet */
+        if (o == l)
+            goto err;
+    }
+
+    /*
+     * 'o' will never point to '\0' at this point, the only chance
+     * 'o' can point to '\0' is either the subsequent if or the first
+     * else if is true.
+     */
+    if (a[o] == upper_z) {
+        o++;
+    } else if (!strict && ((a[o] == plus) || (a[o] == minus))) {
+        int offsign = a[o] == minus ? 1 : -1;
+        int offset = 0;
+
+        o++;
+        /*
+         * if not equal, no need to do subsequent checks
+         * since the following for-loop will add 'o' by 4
+         * and the final return statement will check if 'l'
+         * and 'o' are equal.
+         */
+        if (o + 4 != l)
+            goto err;
+        for (i = end; i < end + 2; i++) {
+            if (!ascii_isdigit(a[o]))
+                goto err;
+            n = a[o] - num_zero;
+            o++;
+            if (!ascii_isdigit(a[o]))
+                goto err;
+            n = (n * 10) + a[o] - num_zero;
+            i2 = (d->type == V_ASN1_UTCTIME) ? i + 1 : i;
+            if ((n < min[i2]) || (n > max[i2]))
+                goto err;
+            /* if tm is NULL, no need to adjust */
+            if (tm != NULL) {
+                if (i == end)
+                    offset = n * 3600;
+                else if (i == end + 1)
+                    offset += n * 60;
+            }
+            o++;
+        }
+        if (offset && !OPENSSL_gmtime_adj(&tmp, 0, offset * offsign))
+            goto err;
+    } else {
+        /* not Z, or not +/- in non-strict mode */
+        goto err;
+    }
+    if (o == l) {
+        /* success, check if tm should be filled */
+        if (tm != NULL)
+            *tm = tmp;
+        return 1;
+    }
+ err:
+    return 0;
+}
+
+ASN1_TIME *asn1_time_from_tm(ASN1_TIME *s, struct tm *ts, int type)
+{
+    char* p;
+    ASN1_TIME *tmps = NULL;
+    const size_t len = 20;
+
+    if (type == V_ASN1_UNDEF) {
+        if (is_utc(ts->tm_year))
+            type = V_ASN1_UTCTIME;
+        else
+            type = V_ASN1_GENERALIZEDTIME;
+    } else if (type == V_ASN1_UTCTIME) {
+        if (!is_utc(ts->tm_year))
+            goto err;
+    } else if (type != V_ASN1_GENERALIZEDTIME) {
+        goto err;
+    }
+
+    if (s == NULL)
+        tmps = ASN1_STRING_new();
+    else
+        tmps = s;
+    if (tmps == NULL)
+        return NULL;
+
+    if (!ASN1_STRING_set(tmps, NULL, len))
+        goto err;
+
+    tmps->type = type;
+    p = (char*)tmps->data;
+
+    if (type == V_ASN1_GENERALIZEDTIME)
+        tmps->length = BIO_snprintf(p, len, "%04d%02d%02d%02d%02d%02dZ",
+                                    ts->tm_year + 1900, ts->tm_mon + 1,
+                                    ts->tm_mday, ts->tm_hour, ts->tm_min,
+                                    ts->tm_sec);
+    else
+        tmps->length = BIO_snprintf(p, len, "%02d%02d%02d%02d%02d%02dZ",
+                                    ts->tm_year % 100, ts->tm_mon + 1,
+                                    ts->tm_mday, ts->tm_hour, ts->tm_min,
+                                    ts->tm_sec);
+
+#ifdef CHARSET_EBCDIC
+    ebcdic2ascii(tmps->data, tmps->data, tmps->length);
+#endif
+    return tmps;
+ err:
+    if (tmps != s)
+        ASN1_STRING_free(tmps);
+    return NULL;
+}
+
+ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t)
+{
+    return ASN1_TIME_adj(s, t, 0, 0);
+}
+
+ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
+                         int offset_day, long offset_sec)
+{
+    struct tm *ts;
+    struct tm data;
+
+    ts = OPENSSL_gmtime(&t, &data);
+    if (ts == NULL) {
+        ASN1err(ASN1_F_ASN1_TIME_ADJ, ASN1_R_ERROR_GETTING_TIME);
+        return NULL;
+    }
+    if (offset_day || offset_sec) {
+        if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
+            return NULL;
+    }
+    return asn1_time_from_tm(s, ts, V_ASN1_UNDEF);
+}
+
+int ASN1_TIME_check(const ASN1_TIME *t)
+{
+    if (t->type == V_ASN1_GENERALIZEDTIME)
+        return ASN1_GENERALIZEDTIME_check(t);
+    else if (t->type == V_ASN1_UTCTIME)
+        return ASN1_UTCTIME_check(t);
+    return 0;
+}
+
+/* Convert an ASN1_TIME structure to GeneralizedTime */
+ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(const ASN1_TIME *t,
+                                                   ASN1_GENERALIZEDTIME **out)
+{
+    ASN1_GENERALIZEDTIME *ret = NULL;
+    struct tm tm;
+
+    if (!ASN1_TIME_to_tm(t, &tm))
+        return NULL;
+
+    if (out != NULL)
+        ret = *out;
+
+    ret = asn1_time_from_tm(ret, &tm, V_ASN1_GENERALIZEDTIME);
+
+    if (out != NULL && ret != NULL)
+        *out = ret;
+
+    return ret;
+}
+
+int ASN1_TIME_set_string(ASN1_TIME *s, const char *str)
+{
+    /* Try UTC, if that fails, try GENERALIZED */
+    if (ASN1_UTCTIME_set_string(s, str))
+        return 1;
+    return ASN1_GENERALIZEDTIME_set_string(s, str);
+}
+
+int ASN1_TIME_set_string_X509(ASN1_TIME *s, const char *str)
+{
+    ASN1_TIME t;
+    struct tm tm;
+    int rv = 0;
+
+    t.length = strlen(str);
+    t.data = (unsigned char *)str;
+    t.flags = ASN1_STRING_FLAG_X509_TIME;
+
+    t.type = V_ASN1_UTCTIME;
+
+    if (!ASN1_TIME_check(&t)) {
+        t.type = V_ASN1_GENERALIZEDTIME;
+        if (!ASN1_TIME_check(&t))
+            goto out;
+    }
+
+    /*
+     * Per RFC 5280 (section 4.1.2.5.), the valid input time
+     * strings should be encoded with the following rules:
+     *
+     * 1. UTC: YYMMDDHHMMSSZ, if YY < 50 (20YY) --> UTC: YYMMDDHHMMSSZ
+     * 2. UTC: YYMMDDHHMMSSZ, if YY >= 50 (19YY) --> UTC: YYMMDDHHMMSSZ
+     * 3. G'd: YYYYMMDDHHMMSSZ, if YYYY >= 2050 --> G'd: YYYYMMDDHHMMSSZ
+     * 4. G'd: YYYYMMDDHHMMSSZ, if YYYY < 2050 --> UTC: YYMMDDHHMMSSZ
+     *
+     * Only strings of the 4th rule should be reformatted, but since a
+     * UTC can only present [1950, 2050), so if the given time string
+     * is less than 1950 (e.g. 19230419000000Z), we do nothing...
+     */
+
+    if (s != NULL && t.type == V_ASN1_GENERALIZEDTIME) {
+        if (!asn1_time_to_tm(&tm, &t))
+            goto out;
+        if (is_utc(tm.tm_year)) {
+            t.length -= 2;
+            /*
+             * it's OK to let original t.data go since that's assigned
+             * to a piece of memory allocated outside of this function.
+             * new t.data would be freed after ASN1_STRING_copy is done.
+             */
+            t.data = OPENSSL_zalloc(t.length + 1);
+            if (t.data == NULL)
+                goto out;
+            memcpy(t.data, str + 2, t.length);
+            t.type = V_ASN1_UTCTIME;
+        }
+    }
+
+    if (s == NULL || ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t))
+        rv = 1;
+
+    if (t.data != (unsigned char *)str)
+        OPENSSL_free(t.data);
+out:
+    return rv;
+}
+
+int ASN1_TIME_to_tm(const ASN1_TIME *s, struct tm *tm)
+{
+    if (s == NULL) {
+        time_t now_t;
+
+        time(&now_t);
+        memset(tm, 0, sizeof(*tm));
+        if (OPENSSL_gmtime(&now_t, tm) != NULL)
+            return 1;
+        return 0;
+    }
+
+    return asn1_time_to_tm(tm, s);
+}
+
+int ASN1_TIME_diff(int *pday, int *psec,
+                   const ASN1_TIME *from, const ASN1_TIME *to)
+{
+    struct tm tm_from, tm_to;
+
+    if (!ASN1_TIME_to_tm(from, &tm_from))
+        return 0;
+    if (!ASN1_TIME_to_tm(to, &tm_to))
+        return 0;
+    return OPENSSL_gmtime_diff(pday, psec, &tm_from, &tm_to);
+}
+
+static const char _asn1_mon[12][4] = {
+    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm)
+{
+    char *v;
+    int gmt = 0, l;
+    struct tm stm;
+    const char upper_z = 0x5A, period = 0x2E;
+
+    if (!asn1_time_to_tm(&stm, tm)) {
+        /* asn1_time_to_tm will check the time type */
+        goto err;
+    }
+
+    l = tm->length;
+    v = (char *)tm->data;
+    if (v[l - 1] == upper_z)
+        gmt = 1;
+
+    if (tm->type == V_ASN1_GENERALIZEDTIME) {
+        char *f = NULL;
+        int f_len = 0;
+
+        /*
+         * Try to parse fractional seconds. '14' is the place of
+         * 'fraction point' in a GeneralizedTime string.
+         */
+        if (tm->length > 15 && v[14] == period) {
+            f = &v[14];
+            f_len = 1;
+            while (14 + f_len < l && ascii_isdigit(f[f_len]))
+                ++f_len;
+        }
+
+        return BIO_printf(bp, "%s %2d %02d:%02d:%02d%.*s %d%s",
+                          _asn1_mon[stm.tm_mon], stm.tm_mday, stm.tm_hour,
+                          stm.tm_min, stm.tm_sec, f_len, f, stm.tm_year + 1900,
+                          (gmt ? " GMT" : "")) > 0;
+    } else {
+        return BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s",
+                          _asn1_mon[stm.tm_mon], stm.tm_mday, stm.tm_hour,
+                          stm.tm_min, stm.tm_sec, stm.tm_year + 1900,
+                          (gmt ? " GMT" : "")) > 0;
+    }
+ err:
+    BIO_write(bp, "Bad time value", 14);
+    return 0;
+}
+
+int ASN1_TIME_cmp_time_t(const ASN1_TIME *s, time_t t)
+{
+    struct tm stm, ttm;
+    int day, sec;
+
+    if (!ASN1_TIME_to_tm(s, &stm))
+        return -2;
+
+    if (!OPENSSL_gmtime(&t, &ttm))
+        return -2;
+
+    if (!OPENSSL_gmtime_diff(&day, &sec, &ttm, &stm))
+        return -2;
+
+    if (day > 0 || sec > 0)
+        return 1;
+    if (day < 0 || sec < 0)
+        return -1;
+    return 0;
+}
+
+int ASN1_TIME_normalize(ASN1_TIME *t)
+{
+    struct tm tm;
+
+    if (!ASN1_TIME_to_tm(t, &tm))
+        return 0;
+
+    return asn1_time_from_tm(t, &tm, V_ASN1_UNDEF) != NULL;
+}
+
+int ASN1_TIME_compare(const ASN1_TIME *a, const ASN1_TIME *b)
+{
+    int day, sec;
+
+    if (!ASN1_TIME_diff(&day, &sec, b, a))
+        return -2;
+    if (day > 0 || sec > 0)
+        return 1;
+    if (day < 0 || sec < 0)
+        return -1;
+    return 0;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_type.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_type.c
new file mode 100644
index 0000000..4a96315
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_type.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright 1995-2019 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+#include "asn1_local.h"
+
+int ASN1_TYPE_get(const ASN1_TYPE *a)
+{
+    if (a->type == V_ASN1_BOOLEAN
+            || a->type == V_ASN1_NULL
+            || a->value.ptr != NULL)
+        return a->type;
+    else
+        return 0;
+}
+
+void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value)
+{
+    if (a->type != V_ASN1_BOOLEAN
+            && a->type != V_ASN1_NULL
+            && a->value.ptr != NULL) {
+        ASN1_TYPE **tmp_a = &a;
+        asn1_primitive_free((ASN1_VALUE **)tmp_a, NULL, 0);
+    }
+    a->type = type;
+    if (type == V_ASN1_BOOLEAN)
+        a->value.boolean = value ? 0xff : 0;
+    else
+        a->value.ptr = value;
+}
+
+int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
+{
+    if (!value || (type == V_ASN1_BOOLEAN)) {
+        void *p = (void *)value;
+        ASN1_TYPE_set(a, type, p);
+    } else if (type == V_ASN1_OBJECT) {
+        ASN1_OBJECT *odup;
+        odup = OBJ_dup(value);
+        if (!odup)
+            return 0;
+        ASN1_TYPE_set(a, type, odup);
+    } else {
+        ASN1_STRING *sdup;
+        sdup = ASN1_STRING_dup(value);
+        if (!sdup)
+            return 0;
+        ASN1_TYPE_set(a, type, sdup);
+    }
+    return 1;
+}
+
+/* Returns 0 if they are equal, != 0 otherwise. */
+int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
+{
+    int result = -1;
+
+    if (!a || !b || a->type != b->type)
+        return -1;
+
+    switch (a->type) {
+    case V_ASN1_OBJECT:
+        result = OBJ_cmp(a->value.object, b->value.object);
+        break;
+    case V_ASN1_BOOLEAN:
+        result = a->value.boolean - b->value.boolean;
+        break;
+    case V_ASN1_NULL:
+        result = 0;             /* They do not have content. */
+        break;
+    case V_ASN1_INTEGER:
+    case V_ASN1_ENUMERATED:
+    case V_ASN1_BIT_STRING:
+    case V_ASN1_OCTET_STRING:
+    case V_ASN1_SEQUENCE:
+    case V_ASN1_SET:
+    case V_ASN1_NUMERICSTRING:
+    case V_ASN1_PRINTABLESTRING:
+    case V_ASN1_T61STRING:
+    case V_ASN1_VIDEOTEXSTRING:
+    case V_ASN1_IA5STRING:
+    case V_ASN1_UTCTIME:
+    case V_ASN1_GENERALIZEDTIME:
+    case V_ASN1_GRAPHICSTRING:
+    case V_ASN1_VISIBLESTRING:
+    case V_ASN1_GENERALSTRING:
+    case V_ASN1_UNIVERSALSTRING:
+    case V_ASN1_BMPSTRING:
+    case V_ASN1_UTF8STRING:
+    case V_ASN1_OTHER:
+    default:
+        result = ASN1_STRING_cmp((ASN1_STRING *)a->value.ptr,
+                                 (ASN1_STRING *)b->value.ptr);
+        break;
+    }
+
+    return result;
+}
+
+ASN1_TYPE *ASN1_TYPE_pack_sequence(const ASN1_ITEM *it, void *s, ASN1_TYPE **t)
+{
+    ASN1_OCTET_STRING *oct;
+    ASN1_TYPE *rt;
+
+    oct = ASN1_item_pack(s, it, NULL);
+    if (oct == NULL)
+        return NULL;
+
+    if (t && *t) {
+        rt = *t;
+    } else {
+        rt = ASN1_TYPE_new();
+        if (rt == NULL) {
+            ASN1_OCTET_STRING_free(oct);
+            return NULL;
+        }
+        if (t)
+            *t = rt;
+    }
+    ASN1_TYPE_set(rt, V_ASN1_SEQUENCE, oct);
+    return rt;
+}
+
+void *ASN1_TYPE_unpack_sequence(const ASN1_ITEM *it, const ASN1_TYPE *t)
+{
+    if (t == NULL || t->type != V_ASN1_SEQUENCE || t->value.sequence == NULL)
+        return NULL;
+    return ASN1_item_unpack(t->value.sequence, it);
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_utctm.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_utctm.c
new file mode 100644
index 0000000..0ff37b1
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_utctm.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright 1995-2017 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include "asn1_local.h"
+
+/* This is the primary function used to parse ASN1_UTCTIME */
+int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d)
+{
+    /* wrapper around ans1_time_to_tm */
+    if (d->type != V_ASN1_UTCTIME)
+        return 0;
+    return asn1_time_to_tm(tm, d);
+}
+
+int ASN1_UTCTIME_check(const ASN1_UTCTIME *d)
+{
+    return asn1_utctime_to_tm(NULL, d);
+}
+
+/* Sets the string via simple copy without cleaning it up */
+int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str)
+{
+    ASN1_UTCTIME t;
+
+    t.type = V_ASN1_UTCTIME;
+    t.length = strlen(str);
+    t.data = (unsigned char *)str;
+    t.flags = 0;
+
+    if (!ASN1_UTCTIME_check(&t))
+        return 0;
+
+    if (s != NULL && !ASN1_STRING_copy(s, &t))
+        return 0;
+
+    return 1;
+}
+
+ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t)
+{
+    return ASN1_UTCTIME_adj(s, t, 0, 0);
+}
+
+ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
+                               int offset_day, long offset_sec)
+{
+    struct tm *ts;
+    struct tm data;
+
+    ts = OPENSSL_gmtime(&t, &data);
+    if (ts == NULL)
+        return NULL;
+
+    if (offset_day || offset_sec) {
+        if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
+            return NULL;
+    }
+
+    return asn1_time_from_tm(s, ts, V_ASN1_UTCTIME);
+}
+
+int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t)
+{
+    struct tm stm, ttm;
+    int day, sec;
+
+    if (!asn1_utctime_to_tm(&stm, s))
+        return -2;
+
+    if (OPENSSL_gmtime(&t, &ttm) == NULL)
+        return -2;
+
+    if (!OPENSSL_gmtime_diff(&day, &sec, &ttm, &stm))
+        return -2;
+
+    if (day > 0 || sec > 0)
+        return 1;
+    if (day < 0 || sec < 0)
+        return -1;
+    return 0;
+}
+
+int ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm)
+{
+    if (tm->type != V_ASN1_UTCTIME)
+        return 0;
+    return ASN1_TIME_print(bp, tm);
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_utf8.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_utf8.c
new file mode 100644
index 0000000..e2dc09f
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_utf8.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright 1995-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+
+/* UTF8 utilities */
+
+/*-
+ * This parses a UTF8 string one character at a time. It is passed a pointer
+ * to the string and the length of the string. It sets 'value' to the value of
+ * the current character. It returns the number of characters read or a
+ * negative error code:
+ * -1 = string too short
+ * -2 = illegal character
+ * -3 = subsequent characters not of the form 10xxxxxx
+ * -4 = character encoded incorrectly (not minimal length).
+ */
+
+int UTF8_getc(const unsigned char *str, int len, unsigned long *val)
+{
+    const unsigned char *p;
+    unsigned long value;
+    int ret;
+    if (len <= 0)
+        return 0;
+    p = str;
+
+    /* Check syntax and work out the encoded value (if correct) */
+    if ((*p & 0x80) == 0) {
+        value = *p++ & 0x7f;
+        ret = 1;
+    } else if ((*p & 0xe0) == 0xc0) {
+        if (len < 2)
+            return -1;
+        if ((p[1] & 0xc0) != 0x80)
+            return -3;
+        value = (*p++ & 0x1f) << 6;
+        value |= *p++ & 0x3f;
+        if (value < 0x80)
+            return -4;
+        ret = 2;
+    } else if ((*p & 0xf0) == 0xe0) {
+        if (len < 3)
+            return -1;
+        if (((p[1] & 0xc0) != 0x80)
+            || ((p[2] & 0xc0) != 0x80))
+            return -3;
+        value = (*p++ & 0xf) << 12;
+        value |= (*p++ & 0x3f) << 6;
+        value |= *p++ & 0x3f;
+        if (value < 0x800)
+            return -4;
+        ret = 3;
+    } else if ((*p & 0xf8) == 0xf0) {
+        if (len < 4)
+            return -1;
+        if (((p[1] & 0xc0) != 0x80)
+            || ((p[2] & 0xc0) != 0x80)
+            || ((p[3] & 0xc0) != 0x80))
+            return -3;
+        value = ((unsigned long)(*p++ & 0x7)) << 18;
+        value |= (*p++ & 0x3f) << 12;
+        value |= (*p++ & 0x3f) << 6;
+        value |= *p++ & 0x3f;
+        if (value < 0x10000)
+            return -4;
+        ret = 4;
+    } else if ((*p & 0xfc) == 0xf8) {
+        if (len < 5)
+            return -1;
+        if (((p[1] & 0xc0) != 0x80)
+            || ((p[2] & 0xc0) != 0x80)
+            || ((p[3] & 0xc0) != 0x80)
+            || ((p[4] & 0xc0) != 0x80))
+            return -3;
+        value = ((unsigned long)(*p++ & 0x3)) << 24;
+        value |= ((unsigned long)(*p++ & 0x3f)) << 18;
+        value |= ((unsigned long)(*p++ & 0x3f)) << 12;
+        value |= (*p++ & 0x3f) << 6;
+        value |= *p++ & 0x3f;
+        if (value < 0x200000)
+            return -4;
+        ret = 5;
+    } else if ((*p & 0xfe) == 0xfc) {
+        if (len < 6)
+            return -1;
+        if (((p[1] & 0xc0) != 0x80)
+            || ((p[2] & 0xc0) != 0x80)
+            || ((p[3] & 0xc0) != 0x80)
+            || ((p[4] & 0xc0) != 0x80)
+            || ((p[5] & 0xc0) != 0x80))
+            return -3;
+        value = ((unsigned long)(*p++ & 0x1)) << 30;
+        value |= ((unsigned long)(*p++ & 0x3f)) << 24;
+        value |= ((unsigned long)(*p++ & 0x3f)) << 18;
+        value |= ((unsigned long)(*p++ & 0x3f)) << 12;
+        value |= (*p++ & 0x3f) << 6;
+        value |= *p++ & 0x3f;
+        if (value < 0x4000000)
+            return -4;
+        ret = 6;
+    } else
+        return -2;
+    *val = value;
+    return ret;
+}
+
+/*
+ * This takes a character 'value' and writes the UTF8 encoded value in 'str'
+ * where 'str' is a buffer containing 'len' characters. Returns the number of
+ * characters written or -1 if 'len' is too small. 'str' can be set to NULL
+ * in which case it just returns the number of characters. It will need at
+ * most 6 characters.
+ */
+
+int UTF8_putc(unsigned char *str, int len, unsigned long value)
+{
+    if (!str)
+        len = 6;                /* Maximum we will need */
+    else if (len <= 0)
+        return -1;
+    if (value < 0x80) {
+        if (str)
+            *str = (unsigned char)value;
+        return 1;
+    }
+    if (value < 0x800) {
+        if (len < 2)
+            return -1;
+        if (str) {
+            *str++ = (unsigned char)(((value >> 6) & 0x1f) | 0xc0);
+            *str = (unsigned char)((value & 0x3f) | 0x80);
+        }
+        return 2;
+    }
+    if (value < 0x10000) {
+        if (len < 3)
+            return -1;
+        if (str) {
+            *str++ = (unsigned char)(((value >> 12) & 0xf) | 0xe0);
+            *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+            *str = (unsigned char)((value & 0x3f) | 0x80);
+        }
+        return 3;
+    }
+    if (value < 0x200000) {
+        if (len < 4)
+            return -1;
+        if (str) {
+            *str++ = (unsigned char)(((value >> 18) & 0x7) | 0xf0);
+            *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
+            *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+            *str = (unsigned char)((value & 0x3f) | 0x80);
+        }
+        return 4;
+    }
+    if (value < 0x4000000) {
+        if (len < 5)
+            return -1;
+        if (str) {
+            *str++ = (unsigned char)(((value >> 24) & 0x3) | 0xf8);
+            *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
+            *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
+            *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+            *str = (unsigned char)((value & 0x3f) | 0x80);
+        }
+        return 5;
+    }
+    if (len < 6)
+        return -1;
+    if (str) {
+        *str++ = (unsigned char)(((value >> 30) & 0x1) | 0xfc);
+        *str++ = (unsigned char)(((value >> 24) & 0x3f) | 0x80);
+        *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
+        *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
+        *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+        *str = (unsigned char)((value & 0x3f) | 0x80);
+    }
+    return 6;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_verify.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_verify.c
new file mode 100644
index 0000000..4b5f542
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/a_verify.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright 1995-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <sys/types.h>
+
+#include "internal/cryptlib.h"
+
+#include <openssl/bn.h>
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+#include "crypto/asn1.h"
+#include "crypto/evp.h"
+
+#ifndef NO_ASN1_OLD
+
+int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
+                char *data, EVP_PKEY *pkey)
+{
+    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+    const EVP_MD *type;
+    unsigned char *p, *buf_in = NULL;
+    int ret = -1, i, inl;
+
+    if (ctx == NULL) {
+        ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    i = OBJ_obj2nid(a->algorithm);
+    type = EVP_get_digestbyname(OBJ_nid2sn(i));
+    if (type == NULL) {
+        ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+        goto err;
+    }
+
+    if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) {
+        ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
+        goto err;
+    }
+
+    inl = i2d(data, NULL);
+    if (inl <= 0) {
+        ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+    buf_in = OPENSSL_malloc((unsigned int)inl);
+    if (buf_in == NULL) {
+        ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    p = buf_in;
+
+    i2d(data, &p);
+    ret = EVP_VerifyInit_ex(ctx, type, NULL)
+        && EVP_VerifyUpdate(ctx, (unsigned char *)buf_in, inl);
+
+    OPENSSL_clear_free(buf_in, (unsigned int)inl);
+
+    if (!ret) {
+        ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB);
+        goto err;
+    }
+    ret = -1;
+
+    if (EVP_VerifyFinal(ctx, (unsigned char *)signature->data,
+                        (unsigned int)signature->length, pkey) <= 0) {
+        ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB);
+        ret = 0;
+        goto err;
+    }
+    ret = 1;
+ err:
+    EVP_MD_CTX_free(ctx);
+    return ret;
+}
+
+#endif
+
+int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
+                     ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey)
+{
+    EVP_MD_CTX *ctx = NULL;
+    unsigned char *buf_in = NULL;
+    int ret = -1, inl = 0;
+    int mdnid, pknid;
+    size_t inll = 0;
+
+    if (!pkey) {
+        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
+        return -1;
+    }
+
+    if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) {
+        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
+        return -1;
+    }
+
+    ctx = EVP_MD_CTX_new();
+    if (ctx == NULL) {
+        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    /* Convert signature OID into digest and public key OIDs */
+    if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) {
+        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
+        goto err;
+    }
+    if (mdnid == NID_undef) {
+        if (!pkey->ameth || !pkey->ameth->item_verify) {
+            ASN1err(ASN1_F_ASN1_ITEM_VERIFY,
+                    ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
+            goto err;
+        }
+        ret = pkey->ameth->item_verify(ctx, it, asn, a, signature, pkey);
+        /*
+         * Return value of 2 means carry on, anything else means we exit
+         * straight away: either a fatal error of the underlying verification
+         * routine handles all verification.
+         */
+        if (ret != 2)
+            goto err;
+        ret = -1;
+    } else {
+        const EVP_MD *type = EVP_get_digestbynid(mdnid);
+
+        if (type == NULL) {
+            ASN1err(ASN1_F_ASN1_ITEM_VERIFY,
+                    ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+            goto err;
+        }
+
+        /* Check public key OID matches public key type */
+        if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) {
+            ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_WRONG_PUBLIC_KEY_TYPE);
+            goto err;
+        }
+
+        if (!EVP_DigestVerifyInit(ctx, NULL, type, NULL, pkey)) {
+            ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
+            ret = 0;
+            goto err;
+        }
+
+    }
+
+    inl = ASN1_item_i2d(asn, &buf_in, it);
+    if (inl <= 0) {
+        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+    if (buf_in == NULL) {
+        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    inll = inl;
+
+    ret = EVP_DigestVerify(ctx, signature->data, (size_t)signature->length,
+                           buf_in, inl);
+    if (ret <= 0) {
+        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
+        goto err;
+    }
+    ret = 1;
+ err:
+    OPENSSL_clear_free(buf_in, inll);
+    EVP_MD_CTX_free(ctx);
+    return ret;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/ameth_lib.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/ameth_lib.c
new file mode 100644
index 0000000..5e8c3ed
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/ameth_lib.c
@@ -0,0 +1,451 @@
+/*
+ * Copyright 2006-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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "e_os.h"               /* for strncasecmp */
+#include "internal/cryptlib.h"
+#include <stdio.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/engine.h>
+#include "crypto/asn1.h"
+#include "crypto/evp.h"
+
+#include "standard_methods.h"
+
+typedef int sk_cmp_fn_type(const char *const *a, const char *const *b);
+static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL;
+
+DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
+                           const EVP_PKEY_ASN1_METHOD *, ameth);
+
+static int ameth_cmp(const EVP_PKEY_ASN1_METHOD *const *a,
+                     const EVP_PKEY_ASN1_METHOD *const *b)
+{
+    return ((*a)->pkey_id - (*b)->pkey_id);
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
+                             const EVP_PKEY_ASN1_METHOD *, ameth);
+
+int EVP_PKEY_asn1_get_count(void)
+{
+    int num = OSSL_NELEM(standard_methods);
+    if (app_methods)
+        num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods);
+    return num;
+}
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx)
+{
+    int num = OSSL_NELEM(standard_methods);
+    if (idx < 0)
+        return NULL;
+    if (idx < num)
+        return standard_methods[idx];
+    idx -= num;
+    return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
+}
+
+static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type)
+{
+    EVP_PKEY_ASN1_METHOD tmp;
+    const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret;
+    tmp.pkey_id = type;
+    if (app_methods) {
+        int idx;
+        idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp);
+        if (idx >= 0)
+            return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
+    }
+    ret = OBJ_bsearch_ameth(&t, standard_methods, OSSL_NELEM(standard_methods));
+    if (!ret || !*ret)
+        return NULL;
+    return *ret;
+}
+
+/*
+ * Find an implementation of an ASN1 algorithm. If 'pe' is not NULL also
+ * search through engines and set *pe to a functional reference to the engine
+ * implementing 'type' or NULL if no engine implements it.
+ */
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type)
+{
+    const EVP_PKEY_ASN1_METHOD *t;
+
+    for (;;) {
+        t = pkey_asn1_find(type);
+        if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS))
+            break;
+        type = t->pkey_base_id;
+    }
+    if (pe) {
+#ifndef OPENSSL_NO_ENGINE
+        ENGINE *e;
+        /* type will contain the final unaliased type */
+        e = ENGINE_get_pkey_asn1_meth_engine(type);
+        if (e) {
+            *pe = e;
+            return ENGINE_get_pkey_asn1_meth(e, type);
+        }
+#endif
+        *pe = NULL;
+    }
+    return t;
+}
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
+                                                   const char *str, int len)
+{
+    int i;
+    const EVP_PKEY_ASN1_METHOD *ameth = NULL;
+
+    if (len == -1)
+        len = strlen(str);
+    if (pe) {
+#ifndef OPENSSL_NO_ENGINE
+        ENGINE *e;
+        ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
+        if (ameth) {
+            /*
+             * Convert structural into functional reference
+             */
+            if (!ENGINE_init(e))
+                ameth = NULL;
+            ENGINE_free(e);
+            *pe = e;
+            return ameth;
+        }
+#endif
+        *pe = NULL;
+    }
+    for (i = EVP_PKEY_asn1_get_count(); i-- > 0; ) {
+        ameth = EVP_PKEY_asn1_get0(i);
+        if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
+            continue;
+        if ((int)strlen(ameth->pem_str) == len
+            && strncasecmp(ameth->pem_str, str, len) == 0)
+            return ameth;
+    }
+    return NULL;
+}
+
+int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
+{
+    EVP_PKEY_ASN1_METHOD tmp = { 0, };
+
+    /*
+     * One of the following must be true:
+     *
+     * pem_str == NULL AND ASN1_PKEY_ALIAS is set
+     * pem_str != NULL AND ASN1_PKEY_ALIAS is clear
+     *
+     * Anything else is an error and may lead to a corrupt ASN1 method table
+     */
+    if (!((ameth->pem_str == NULL
+           && (ameth->pkey_flags & ASN1_PKEY_ALIAS) != 0)
+          || (ameth->pem_str != NULL
+              && (ameth->pkey_flags & ASN1_PKEY_ALIAS) == 0))) {
+        EVPerr(EVP_F_EVP_PKEY_ASN1_ADD0, ERR_R_PASSED_INVALID_ARGUMENT);
+        return 0;
+    }
+
+    if (app_methods == NULL) {
+        app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
+        if (app_methods == NULL)
+            return 0;
+    }
+
+    tmp.pkey_id = ameth->pkey_id;
+    if (sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp) >= 0) {
+        EVPerr(EVP_F_EVP_PKEY_ASN1_ADD0,
+               EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED);
+        return 0;
+    }
+
+    if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth))
+        return 0;
+    sk_EVP_PKEY_ASN1_METHOD_sort(app_methods);
+    return 1;
+}
+
+int EVP_PKEY_asn1_add_alias(int to, int from)
+{
+    EVP_PKEY_ASN1_METHOD *ameth;
+    ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL);
+    if (ameth == NULL)
+        return 0;
+    ameth->pkey_base_id = to;
+    if (!EVP_PKEY_asn1_add0(ameth)) {
+        EVP_PKEY_asn1_free(ameth);
+        return 0;
+    }
+    return 1;
+}
+
+int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id,
+                            int *ppkey_flags, const char **pinfo,
+                            const char **ppem_str,
+                            const EVP_PKEY_ASN1_METHOD *ameth)
+{
+    if (!ameth)
+        return 0;
+    if (ppkey_id)
+        *ppkey_id = ameth->pkey_id;
+    if (ppkey_base_id)
+        *ppkey_base_id = ameth->pkey_base_id;
+    if (ppkey_flags)
+        *ppkey_flags = ameth->pkey_flags;
+    if (pinfo)
+        *pinfo = ameth->info;
+    if (ppem_str)
+        *ppem_str = ameth->pem_str;
+    return 1;
+}
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(const EVP_PKEY *pkey)
+{
+    return pkey->ameth;
+}
+
+EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags,
+                                        const char *pem_str, const char *info)
+{
+    EVP_PKEY_ASN1_METHOD *ameth = OPENSSL_zalloc(sizeof(*ameth));
+
+    if (ameth == NULL)
+        return NULL;
+
+    ameth->pkey_id = id;
+    ameth->pkey_base_id = id;
+    ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC;
+
+    if (info) {
+        ameth->info = OPENSSL_strdup(info);
+        if (!ameth->info)
+            goto err;
+    }
+
+    if (pem_str) {
+        ameth->pem_str = OPENSSL_strdup(pem_str);
+        if (!ameth->pem_str)
+            goto err;
+    }
+
+    return ameth;
+
+ err:
+    EVP_PKEY_asn1_free(ameth);
+    return NULL;
+
+}
+
+void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst,
+                        const EVP_PKEY_ASN1_METHOD *src)
+{
+
+    dst->pub_decode = src->pub_decode;
+    dst->pub_encode = src->pub_encode;
+    dst->pub_cmp = src->pub_cmp;
+    dst->pub_print = src->pub_print;
+
+    dst->priv_decode = src->priv_decode;
+    dst->priv_encode = src->priv_encode;
+    dst->priv_print = src->priv_print;
+
+    dst->old_priv_encode = src->old_priv_encode;
+    dst->old_priv_decode = src->old_priv_decode;
+
+    dst->pkey_size = src->pkey_size;
+    dst->pkey_bits = src->pkey_bits;
+
+    dst->param_decode = src->param_decode;
+    dst->param_encode = src->param_encode;
+    dst->param_missing = src->param_missing;
+    dst->param_copy = src->param_copy;
+    dst->param_cmp = src->param_cmp;
+    dst->param_print = src->param_print;
+
+    dst->pkey_free = src->pkey_free;
+    dst->pkey_ctrl = src->pkey_ctrl;
+
+    dst->item_sign = src->item_sign;
+    dst->item_verify = src->item_verify;
+
+    dst->siginf_set = src->siginf_set;
+
+    dst->pkey_check = src->pkey_check;
+
+}
+
+void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
+{
+    if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC)) {
+        OPENSSL_free(ameth->pem_str);
+        OPENSSL_free(ameth->info);
+        OPENSSL_free(ameth);
+    }
+}
+
+void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
+                              int (*pub_decode) (EVP_PKEY *pk,
+                                                 X509_PUBKEY *pub),
+                              int (*pub_encode) (X509_PUBKEY *pub,
+                                                 const EVP_PKEY *pk),
+                              int (*pub_cmp) (const EVP_PKEY *a,
+                                              const EVP_PKEY *b),
+                              int (*pub_print) (BIO *out,
+                                                const EVP_PKEY *pkey,
+                                                int indent, ASN1_PCTX *pctx),
+                              int (*pkey_size) (const EVP_PKEY *pk),
+                              int (*pkey_bits) (const EVP_PKEY *pk))
+{
+    ameth->pub_decode = pub_decode;
+    ameth->pub_encode = pub_encode;
+    ameth->pub_cmp = pub_cmp;
+    ameth->pub_print = pub_print;
+    ameth->pkey_size = pkey_size;
+    ameth->pkey_bits = pkey_bits;
+}
+
+void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
+                               int (*priv_decode) (EVP_PKEY *pk,
+                                                   const PKCS8_PRIV_KEY_INFO
+                                                   *p8inf),
+                               int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8,
+                                                   const EVP_PKEY *pk),
+                               int (*priv_print) (BIO *out,
+                                                  const EVP_PKEY *pkey,
+                                                  int indent,
+                                                  ASN1_PCTX *pctx))
+{
+    ameth->priv_decode = priv_decode;
+    ameth->priv_encode = priv_encode;
+    ameth->priv_print = priv_print;
+}
+
+void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
+                             int (*param_decode) (EVP_PKEY *pkey,
+                                                  const unsigned char **pder,
+                                                  int derlen),
+                             int (*param_encode) (const EVP_PKEY *pkey,
+                                                  unsigned char **pder),
+                             int (*param_missing) (const EVP_PKEY *pk),
+                             int (*param_copy) (EVP_PKEY *to,
+                                                const EVP_PKEY *from),
+                             int (*param_cmp) (const EVP_PKEY *a,
+                                               const EVP_PKEY *b),
+                             int (*param_print) (BIO *out,
+                                                 const EVP_PKEY *pkey,
+                                                 int indent, ASN1_PCTX *pctx))
+{
+    ameth->param_decode = param_decode;
+    ameth->param_encode = param_encode;
+    ameth->param_missing = param_missing;
+    ameth->param_copy = param_copy;
+    ameth->param_cmp = param_cmp;
+    ameth->param_print = param_print;
+}
+
+void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
+                            void (*pkey_free) (EVP_PKEY *pkey))
+{
+    ameth->pkey_free = pkey_free;
+}
+
+void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
+                            int (*pkey_ctrl) (EVP_PKEY *pkey, int op,
+                                              long arg1, void *arg2))
+{
+    ameth->pkey_ctrl = pkey_ctrl;
+}
+
+void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth,
+                                     int (*pkey_security_bits) (const EVP_PKEY
+                                                                *pk))
+{
+    ameth->pkey_security_bits = pkey_security_bits;
+}
+
+void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth,
+                            int (*item_verify) (EVP_MD_CTX *ctx,
+                                                const ASN1_ITEM *it,
+                                                void *asn,
+                                                X509_ALGOR *a,
+                                                ASN1_BIT_STRING *sig,
+                                                EVP_PKEY *pkey),
+                            int (*item_sign) (EVP_MD_CTX *ctx,
+                                              const ASN1_ITEM *it,
+                                              void *asn,
+                                              X509_ALGOR *alg1,
+                                              X509_ALGOR *alg2,
+                                              ASN1_BIT_STRING *sig))
+{
+    ameth->item_sign = item_sign;
+    ameth->item_verify = item_verify;
+}
+
+void EVP_PKEY_asn1_set_siginf(EVP_PKEY_ASN1_METHOD *ameth,
+                              int (*siginf_set) (X509_SIG_INFO *siginf,
+                                                 const X509_ALGOR *alg,
+                                                 const ASN1_STRING *sig))
+{
+    ameth->siginf_set = siginf_set;
+}
+
+void EVP_PKEY_asn1_set_check(EVP_PKEY_ASN1_METHOD *ameth,
+                             int (*pkey_check) (const EVP_PKEY *pk))
+{
+    ameth->pkey_check = pkey_check;
+}
+
+void EVP_PKEY_asn1_set_public_check(EVP_PKEY_ASN1_METHOD *ameth,
+                                    int (*pkey_pub_check) (const EVP_PKEY *pk))
+{
+    ameth->pkey_public_check = pkey_pub_check;
+}
+
+void EVP_PKEY_asn1_set_param_check(EVP_PKEY_ASN1_METHOD *ameth,
+                                   int (*pkey_param_check) (const EVP_PKEY *pk))
+{
+    ameth->pkey_param_check = pkey_param_check;
+}
+
+void EVP_PKEY_asn1_set_set_priv_key(EVP_PKEY_ASN1_METHOD *ameth,
+                                    int (*set_priv_key) (EVP_PKEY *pk,
+                                                         const unsigned char
+                                                            *priv,
+                                                         size_t len))
+{
+    ameth->set_priv_key = set_priv_key;
+}
+
+void EVP_PKEY_asn1_set_set_pub_key(EVP_PKEY_ASN1_METHOD *ameth,
+                                   int (*set_pub_key) (EVP_PKEY *pk,
+                                                       const unsigned char *pub,
+                                                       size_t len))
+{
+    ameth->set_pub_key = set_pub_key;
+}
+
+void EVP_PKEY_asn1_set_get_priv_key(EVP_PKEY_ASN1_METHOD *ameth,
+                                    int (*get_priv_key) (const EVP_PKEY *pk,
+                                                         unsigned char *priv,
+                                                         size_t *len))
+{
+    ameth->get_priv_key = get_priv_key;
+}
+
+void EVP_PKEY_asn1_set_get_pub_key(EVP_PKEY_ASN1_METHOD *ameth,
+                                   int (*get_pub_key) (const EVP_PKEY *pk,
+                                                       unsigned char *pub,
+                                                       size_t *len))
+{
+    ameth->get_pub_key = get_pub_key;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn1_err.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn1_err.c
new file mode 100644
index 0000000..cc0a59c
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn1_err.c
@@ -0,0 +1,352 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-2020 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/err.h>
+#include <openssl/asn1err.h>
+
+#ifndef OPENSSL_NO_ERR
+
+static const ERR_STRING_DATA ASN1_str_functs[] = {
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_A2D_ASN1_OBJECT, 0), "a2d_ASN1_OBJECT"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_A2I_ASN1_INTEGER, 0), "a2i_ASN1_INTEGER"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_A2I_ASN1_STRING, 0), "a2i_ASN1_STRING"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_APPEND_EXP, 0), "append_exp"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_BIO_INIT, 0), "asn1_bio_init"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_BIT_STRING_SET_BIT, 0),
+     "ASN1_BIT_STRING_set_bit"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_CB, 0), "asn1_cb"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_CHECK_TLEN, 0), "asn1_check_tlen"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_COLLECT, 0), "asn1_collect"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_D2I_EX_PRIMITIVE, 0),
+     "asn1_d2i_ex_primitive"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_D2I_FP, 0), "ASN1_d2i_fp"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_D2I_READ_BIO, 0), "asn1_d2i_read_bio"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_DIGEST, 0), "ASN1_digest"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_DO_ADB, 0), "asn1_do_adb"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_DO_LOCK, 0), "asn1_do_lock"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_DUP, 0), "ASN1_dup"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ENC_SAVE, 0), "asn1_enc_save"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_EX_C2I, 0), "asn1_ex_c2i"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_FIND_END, 0), "asn1_find_end"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GENERALIZEDTIME_ADJ, 0),
+     "ASN1_GENERALIZEDTIME_adj"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GENERATE_V3, 0), "ASN1_generate_v3"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GET_INT64, 0), "asn1_get_int64"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GET_OBJECT, 0), "ASN1_get_object"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GET_UINT64, 0), "asn1_get_uint64"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_I2D_BIO, 0), "ASN1_i2d_bio"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_I2D_FP, 0), "ASN1_i2d_fp"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_D2I_FP, 0), "ASN1_item_d2i_fp"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_DUP, 0), "ASN1_item_dup"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_EMBED_D2I, 0),
+     "asn1_item_embed_d2i"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_EMBED_NEW, 0),
+     "asn1_item_embed_new"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_EX_I2D, 0), "ASN1_item_ex_i2d"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_FLAGS_I2D, 0),
+     "asn1_item_flags_i2d"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_I2D_BIO, 0), "ASN1_item_i2d_bio"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_I2D_FP, 0), "ASN1_item_i2d_fp"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_PACK, 0), "ASN1_item_pack"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_SIGN, 0), "ASN1_item_sign"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_SIGN_CTX, 0),
+     "ASN1_item_sign_ctx"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_UNPACK, 0), "ASN1_item_unpack"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_VERIFY, 0), "ASN1_item_verify"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_MBSTRING_NCOPY, 0),
+     "ASN1_mbstring_ncopy"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_OBJECT_NEW, 0), "ASN1_OBJECT_new"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_OUTPUT_DATA, 0), "asn1_output_data"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_PCTX_NEW, 0), "ASN1_PCTX_new"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_PRIMITIVE_NEW, 0),
+     "asn1_primitive_new"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_SCTX_NEW, 0), "ASN1_SCTX_new"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_SIGN, 0), "ASN1_sign"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STR2TYPE, 0), "asn1_str2type"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STRING_GET_INT64, 0),
+     "asn1_string_get_int64"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STRING_GET_UINT64, 0),
+     "asn1_string_get_uint64"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STRING_SET, 0), "ASN1_STRING_set"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STRING_TABLE_ADD, 0),
+     "ASN1_STRING_TABLE_add"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STRING_TO_BN, 0), "asn1_string_to_bn"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STRING_TYPE_NEW, 0),
+     "ASN1_STRING_type_new"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_TEMPLATE_EX_D2I, 0),
+     "asn1_template_ex_d2i"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_TEMPLATE_NEW, 0), "asn1_template_new"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, 0),
+     "asn1_template_noexp_d2i"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_TIME_ADJ, 0), "ASN1_TIME_adj"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING, 0),
+     "ASN1_TYPE_get_int_octetstring"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_TYPE_GET_OCTETSTRING, 0),
+     "ASN1_TYPE_get_octetstring"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_UTCTIME_ADJ, 0), "ASN1_UTCTIME_adj"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_VERIFY, 0), "ASN1_verify"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_B64_READ_ASN1, 0), "b64_read_asn1"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_B64_WRITE_ASN1, 0), "B64_write_ASN1"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_BIO_NEW_NDEF, 0), "BIO_new_NDEF"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_BITSTR_CB, 0), "bitstr_cb"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_BN_TO_ASN1_STRING, 0), "bn_to_asn1_string"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_C2I_ASN1_BIT_STRING, 0),
+     "c2i_ASN1_BIT_STRING"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_C2I_ASN1_INTEGER, 0), "c2i_ASN1_INTEGER"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_C2I_ASN1_OBJECT, 0), "c2i_ASN1_OBJECT"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_C2I_IBUF, 0), "c2i_ibuf"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_C2I_UINT64_INT, 0), "c2i_uint64_int"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_COLLECT_DATA, 0), "collect_data"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_D2I_ASN1_OBJECT, 0), "d2i_ASN1_OBJECT"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_D2I_ASN1_UINTEGER, 0), "d2i_ASN1_UINTEGER"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_D2I_AUTOPRIVATEKEY, 0),
+     "d2i_AutoPrivateKey"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_D2I_PRIVATEKEY, 0), "d2i_PrivateKey"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_D2I_PUBLICKEY, 0), "d2i_PublicKey"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_DO_BUF, 0), "do_buf"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_DO_CREATE, 0), "do_create"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_DO_DUMP, 0), "do_dump"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_DO_TCREATE, 0), "do_tcreate"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2A_ASN1_OBJECT, 0), "i2a_ASN1_OBJECT"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2D_ASN1_BIO_STREAM, 0),
+     "i2d_ASN1_bio_stream"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2D_ASN1_OBJECT, 0), "i2d_ASN1_OBJECT"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2D_DSA_PUBKEY, 0), "i2d_DSA_PUBKEY"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2D_EC_PUBKEY, 0), "i2d_EC_PUBKEY"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2D_PRIVATEKEY, 0), "i2d_PrivateKey"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2D_PUBLICKEY, 0), "i2d_PublicKey"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2D_RSA_PUBKEY, 0), "i2d_RSA_PUBKEY"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_LONG_C2I, 0), "long_c2i"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_NDEF_PREFIX, 0), "ndef_prefix"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_NDEF_SUFFIX, 0), "ndef_suffix"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_OID_MODULE_INIT, 0), "oid_module_init"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_PARSE_TAGGING, 0), "parse_tagging"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_PKCS5_PBE2_SET_IV, 0), "PKCS5_pbe2_set_iv"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_PKCS5_PBE2_SET_SCRYPT, 0),
+     "PKCS5_pbe2_set_scrypt"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_PKCS5_PBE_SET, 0), "PKCS5_pbe_set"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_PKCS5_PBE_SET0_ALGOR, 0),
+     "PKCS5_pbe_set0_algor"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_PKCS5_PBKDF2_SET, 0), "PKCS5_pbkdf2_set"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_PKCS5_SCRYPT_SET, 0), "pkcs5_scrypt_set"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_SMIME_READ_ASN1, 0), "SMIME_read_ASN1"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_SMIME_TEXT, 0), "SMIME_text"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_STABLE_GET, 0), "stable_get"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_STBL_MODULE_INIT, 0), "stbl_module_init"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_UINT32_C2I, 0), "uint32_c2i"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_UINT32_NEW, 0), "uint32_new"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_UINT64_C2I, 0), "uint64_c2i"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_UINT64_NEW, 0), "uint64_new"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_X509_CRL_ADD0_REVOKED, 0),
+     "X509_CRL_add0_revoked"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_X509_INFO_NEW, 0), "X509_INFO_new"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_X509_NAME_ENCODE, 0), "x509_name_encode"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_X509_NAME_EX_D2I, 0), "x509_name_ex_d2i"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_X509_NAME_EX_NEW, 0), "x509_name_ex_new"},
+    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_X509_PKEY_NEW, 0), "X509_PKEY_new"},
+    {0, NULL}
+};
+
+static const ERR_STRING_DATA ASN1_str_reasons[] = {
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ADDING_OBJECT), "adding object"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ASN1_PARSE_ERROR), "asn1 parse error"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ASN1_SIG_PARSE_ERROR),
+    "asn1 sig parse error"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_AUX_ERROR), "aux error"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BAD_OBJECT_HEADER), "bad object header"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BAD_TEMPLATE), "bad template"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BMPSTRING_IS_WRONG_LENGTH),
+    "bmpstring is wrong length"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BN_LIB), "bn lib"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BOOLEAN_IS_WRONG_LENGTH),
+    "boolean is wrong length"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BUFFER_TOO_SMALL), "buffer too small"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),
+    "cipher has no object identifier"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_CONTEXT_NOT_INITIALISED),
+    "context not initialised"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_DATA_IS_WRONG), "data is wrong"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_DECODE_ERROR), "decode error"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_DEPTH_EXCEEDED), "depth exceeded"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED),
+    "digest and key type not supported"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ENCODE_ERROR), "encode error"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ERROR_GETTING_TIME),
+    "error getting time"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ERROR_LOADING_SECTION),
+    "error loading section"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ERROR_SETTING_CIPHER_PARAMS),
+    "error setting cipher params"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_EXPECTING_AN_INTEGER),
+    "expecting an integer"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_EXPECTING_AN_OBJECT),
+    "expecting an object"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_EXPLICIT_LENGTH_MISMATCH),
+    "explicit length mismatch"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED),
+    "explicit tag not constructed"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_FIELD_MISSING), "field missing"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_FIRST_NUM_TOO_LARGE),
+    "first num too large"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_HEADER_TOO_LONG), "header too long"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_BITSTRING_FORMAT),
+    "illegal bitstring format"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_BOOLEAN), "illegal boolean"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_CHARACTERS),
+    "illegal characters"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_FORMAT), "illegal format"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_HEX), "illegal hex"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_IMPLICIT_TAG),
+    "illegal implicit tag"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_INTEGER), "illegal integer"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_NEGATIVE_VALUE),
+    "illegal negative value"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_NESTED_TAGGING),
+    "illegal nested tagging"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_NULL), "illegal null"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_NULL_VALUE),
+    "illegal null value"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_OBJECT), "illegal object"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_OPTIONAL_ANY),
+    "illegal optional any"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE),
+    "illegal options on item template"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_PADDING), "illegal padding"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_TAGGED_ANY),
+    "illegal tagged any"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_TIME_VALUE),
+    "illegal time value"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_ZERO_CONTENT),
+    "illegal zero content"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INTEGER_NOT_ASCII_FORMAT),
+    "integer not ascii format"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG),
+    "integer too large for long"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_BIT_STRING_BITS_LEFT),
+    "invalid bit string bits left"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_BMPSTRING_LENGTH),
+    "invalid bmpstring length"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_DIGIT), "invalid digit"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_MIME_TYPE), "invalid mime type"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_MODIFIER), "invalid modifier"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_NUMBER), "invalid number"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_OBJECT_ENCODING),
+    "invalid object encoding"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_SCRYPT_PARAMETERS),
+    "invalid scrypt parameters"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_SEPARATOR), "invalid separator"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_STRING_TABLE_VALUE),
+    "invalid string table value"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH),
+    "invalid universalstring length"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_UTF8STRING),
+    "invalid utf8string"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_VALUE), "invalid value"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_LIST_ERROR), "list error"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MIME_NO_CONTENT_TYPE),
+    "mime no content type"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MIME_PARSE_ERROR), "mime parse error"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MIME_SIG_PARSE_ERROR),
+    "mime sig parse error"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MISSING_EOC), "missing eoc"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MISSING_SECOND_NUMBER),
+    "missing second number"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MISSING_VALUE), "missing value"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MSTRING_NOT_UNIVERSAL),
+    "mstring not universal"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MSTRING_WRONG_TAG), "mstring wrong tag"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NESTED_ASN1_STRING),
+    "nested asn1 string"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NESTED_TOO_DEEP), "nested too deep"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NON_HEX_CHARACTERS),
+    "non hex characters"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NOT_ASCII_FORMAT), "not ascii format"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NOT_ENOUGH_DATA), "not enough data"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NO_CONTENT_TYPE), "no content type"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NO_MATCHING_CHOICE_TYPE),
+    "no matching choice type"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NO_MULTIPART_BODY_FAILURE),
+    "no multipart body failure"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NO_MULTIPART_BOUNDARY),
+    "no multipart boundary"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NO_SIG_CONTENT_TYPE),
+    "no sig content type"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NULL_IS_WRONG_LENGTH),
+    "null is wrong length"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_OBJECT_NOT_ASCII_FORMAT),
+    "object not ascii format"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ODD_NUMBER_OF_CHARS),
+    "odd number of chars"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_SECOND_NUMBER_TOO_LARGE),
+    "second number too large"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_SEQUENCE_LENGTH_MISMATCH),
+    "sequence length mismatch"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_SEQUENCE_NOT_CONSTRUCTED),
+    "sequence not constructed"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG),
+    "sequence or set needs config"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_SHORT_LINE), "short line"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_SIG_INVALID_MIME_TYPE),
+    "sig invalid mime type"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_STREAMING_NOT_SUPPORTED),
+    "streaming not supported"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_STRING_TOO_LONG), "string too long"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_STRING_TOO_SHORT), "string too short"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),
+    "the asn1 object identifier is not known for this md"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_TIME_NOT_ASCII_FORMAT),
+    "time not ascii format"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_TOO_LARGE), "too large"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_TOO_LONG), "too long"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_TOO_SMALL), "too small"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_TYPE_NOT_CONSTRUCTED),
+    "type not constructed"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_TYPE_NOT_PRIMITIVE),
+    "type not primitive"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNEXPECTED_EOC), "unexpected eoc"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH),
+    "universalstring is wrong length"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_FORMAT), "unknown format"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM),
+    "unknown message digest algorithm"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_OBJECT_TYPE),
+    "unknown object type"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE),
+    "unknown public key type"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM),
+    "unknown signature algorithm"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_TAG), "unknown tag"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE),
+    "unsupported any defined by type"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNSUPPORTED_CIPHER),
+    "unsupported cipher"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE),
+    "unsupported public key type"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNSUPPORTED_TYPE), "unsupported type"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_WRONG_INTEGER_TYPE),
+    "wrong integer type"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_WRONG_PUBLIC_KEY_TYPE),
+    "wrong public key type"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_WRONG_TAG), "wrong tag"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_ASN1_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+    if (ERR_func_error_string(ASN1_str_functs[0].error) == NULL) {
+        ERR_load_strings_const(ASN1_str_functs);
+        ERR_load_strings_const(ASN1_str_reasons);
+    }
+#endif
+    return 1;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn1_gen.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn1_gen.c
new file mode 100644
index 0000000..493a693
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn1_gen.c
@@ -0,0 +1,789 @@
+/*
+ * Copyright 2002-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/x509v3.h>
+
+#define ASN1_GEN_FLAG           0x10000
+#define ASN1_GEN_FLAG_IMP       (ASN1_GEN_FLAG|1)
+#define ASN1_GEN_FLAG_EXP       (ASN1_GEN_FLAG|2)
+#define ASN1_GEN_FLAG_TAG       (ASN1_GEN_FLAG|3)
+#define ASN1_GEN_FLAG_BITWRAP   (ASN1_GEN_FLAG|4)
+#define ASN1_GEN_FLAG_OCTWRAP   (ASN1_GEN_FLAG|5)
+#define ASN1_GEN_FLAG_SEQWRAP   (ASN1_GEN_FLAG|6)
+#define ASN1_GEN_FLAG_SETWRAP   (ASN1_GEN_FLAG|7)
+#define ASN1_GEN_FLAG_FORMAT    (ASN1_GEN_FLAG|8)
+
+#define ASN1_GEN_STR(str,val)   {str, sizeof(str) - 1, val}
+
+#define ASN1_FLAG_EXP_MAX       20
+/* Maximum number of nested sequences */
+#define ASN1_GEN_SEQ_MAX_DEPTH  50
+
+/* Input formats */
+
+/* ASCII: default */
+#define ASN1_GEN_FORMAT_ASCII   1
+/* UTF8 */
+#define ASN1_GEN_FORMAT_UTF8    2
+/* Hex */
+#define ASN1_GEN_FORMAT_HEX     3
+/* List of bits */
+#define ASN1_GEN_FORMAT_BITLIST 4
+
+struct tag_name_st {
+    const char *strnam;
+    int len;
+    int tag;
+};
+
+typedef struct {
+    int exp_tag;
+    int exp_class;
+    int exp_constructed;
+    int exp_pad;
+    long exp_len;
+} tag_exp_type;
+
+typedef struct {
+    int imp_tag;
+    int imp_class;
+    int utype;
+    int format;
+    const char *str;
+    tag_exp_type exp_list[ASN1_FLAG_EXP_MAX];
+    int exp_count;
+} tag_exp_arg;
+
+static ASN1_TYPE *generate_v3(const char *str, X509V3_CTX *cnf, int depth,
+                              int *perr);
+static int bitstr_cb(const char *elem, int len, void *bitstr);
+static int asn1_cb(const char *elem, int len, void *bitstr);
+static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class,
+                      int exp_constructed, int exp_pad, int imp_ok);
+static int parse_tagging(const char *vstart, int vlen, int *ptag,
+                         int *pclass);
+static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf,
+                             int depth, int *perr);
+static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype);
+static int asn1_str2tag(const char *tagstr, int len);
+
+ASN1_TYPE *ASN1_generate_nconf(const char *str, CONF *nconf)
+{
+    X509V3_CTX cnf;
+
+    if (!nconf)
+        return ASN1_generate_v3(str, NULL);
+
+    X509V3_set_nconf(&cnf, nconf);
+    return ASN1_generate_v3(str, &cnf);
+}
+
+ASN1_TYPE *ASN1_generate_v3(const char *str, X509V3_CTX *cnf)
+{
+    int err = 0;
+    ASN1_TYPE *ret = generate_v3(str, cnf, 0, &err);
+    if (err)
+        ASN1err(ASN1_F_ASN1_GENERATE_V3, err);
+    return ret;
+}
+
+static ASN1_TYPE *generate_v3(const char *str, X509V3_CTX *cnf, int depth,
+                              int *perr)
+{
+    ASN1_TYPE *ret;
+    tag_exp_arg asn1_tags;
+    tag_exp_type *etmp;
+
+    int i, len;
+
+    unsigned char *orig_der = NULL, *new_der = NULL;
+    const unsigned char *cpy_start;
+    unsigned char *p;
+    const unsigned char *cp;
+    int cpy_len;
+    long hdr_len = 0;
+    int hdr_constructed = 0, hdr_tag, hdr_class;
+    int r;
+
+    asn1_tags.imp_tag = -1;
+    asn1_tags.imp_class = -1;
+    asn1_tags.format = ASN1_GEN_FORMAT_ASCII;
+    asn1_tags.exp_count = 0;
+    if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) {
+        *perr = ASN1_R_UNKNOWN_TAG;
+        return NULL;
+    }
+
+    if ((asn1_tags.utype == V_ASN1_SEQUENCE)
+        || (asn1_tags.utype == V_ASN1_SET)) {
+        if (!cnf) {
+            *perr = ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG;
+            return NULL;
+        }
+        if (depth >= ASN1_GEN_SEQ_MAX_DEPTH) {
+            *perr = ASN1_R_ILLEGAL_NESTED_TAGGING;
+            return NULL;
+        }
+        ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf, depth, perr);
+    } else
+        ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype);
+
+    if (!ret)
+        return NULL;
+
+    /* If no tagging return base type */
+    if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0))
+        return ret;
+
+    /* Generate the encoding */
+    cpy_len = i2d_ASN1_TYPE(ret, &orig_der);
+    ASN1_TYPE_free(ret);
+    ret = NULL;
+    /* Set point to start copying for modified encoding */
+    cpy_start = orig_der;
+
+    /* Do we need IMPLICIT tagging? */
+    if (asn1_tags.imp_tag != -1) {
+        /* If IMPLICIT we will replace the underlying tag */
+        /* Skip existing tag+len */
+        r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class,
+                            cpy_len);
+        if (r & 0x80)
+            goto err;
+        /* Update copy length */
+        cpy_len -= cpy_start - orig_der;
+        /*
+         * For IMPLICIT tagging the length should match the original length
+         * and constructed flag should be consistent.
+         */
+        if (r & 0x1) {
+            /* Indefinite length constructed */
+            hdr_constructed = 2;
+            hdr_len = 0;
+        } else
+            /* Just retain constructed flag */
+            hdr_constructed = r & V_ASN1_CONSTRUCTED;
+        /*
+         * Work out new length with IMPLICIT tag: ignore constructed because
+         * it will mess up if indefinite length
+         */
+        len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag);
+    } else
+        len = cpy_len;
+
+    /* Work out length in any EXPLICIT, starting from end */
+
+    for (i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1;
+         i < asn1_tags.exp_count; i++, etmp--) {
+        /* Content length: number of content octets + any padding */
+        len += etmp->exp_pad;
+        etmp->exp_len = len;
+        /* Total object length: length including new header */
+        len = ASN1_object_size(0, len, etmp->exp_tag);
+    }
+
+    /* Allocate buffer for new encoding */
+
+    new_der = OPENSSL_malloc(len);
+    if (new_der == NULL)
+        goto err;
+
+    /* Generate tagged encoding */
+
+    p = new_der;
+
+    /* Output explicit tags first */
+
+    for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count;
+         i++, etmp++) {
+        ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len,
+                        etmp->exp_tag, etmp->exp_class);
+        if (etmp->exp_pad)
+            *p++ = 0;
+    }
+
+    /* If IMPLICIT, output tag */
+
+    if (asn1_tags.imp_tag != -1) {
+        if (asn1_tags.imp_class == V_ASN1_UNIVERSAL
+            && (asn1_tags.imp_tag == V_ASN1_SEQUENCE
+                || asn1_tags.imp_tag == V_ASN1_SET))
+            hdr_constructed = V_ASN1_CONSTRUCTED;
+        ASN1_put_object(&p, hdr_constructed, hdr_len,
+                        asn1_tags.imp_tag, asn1_tags.imp_class);
+    }
+
+    /* Copy across original encoding */
+    memcpy(p, cpy_start, cpy_len);
+
+    cp = new_der;
+
+    /* Obtain new ASN1_TYPE structure */
+    ret = d2i_ASN1_TYPE(NULL, &cp, len);
+
+ err:
+    OPENSSL_free(orig_der);
+    OPENSSL_free(new_der);
+
+    return ret;
+
+}
+
+static int asn1_cb(const char *elem, int len, void *bitstr)
+{
+    tag_exp_arg *arg = bitstr;
+    int i;
+    int utype;
+    int vlen = 0;
+    const char *p, *vstart = NULL;
+
+    int tmp_tag, tmp_class;
+
+    if (elem == NULL)
+        return -1;
+
+    for (i = 0, p = elem; i < len; p++, i++) {
+        /* Look for the ':' in name value pairs */
+        if (*p == ':') {
+            vstart = p + 1;
+            vlen = len - (vstart - elem);
+            len = p - elem;
+            break;
+        }
+    }
+
+    utype = asn1_str2tag(elem, len);
+
+    if (utype == -1) {
+        ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_TAG);
+        ERR_add_error_data(2, "tag=", elem);
+        return -1;
+    }
+
+    /* If this is not a modifier mark end of string and exit */
+    if (!(utype & ASN1_GEN_FLAG)) {
+        arg->utype = utype;
+        arg->str = vstart;
+        /* If no value and not end of string, error */
+        if (!vstart && elem[len]) {
+            ASN1err(ASN1_F_ASN1_CB, ASN1_R_MISSING_VALUE);
+            return -1;
+        }
+        return 0;
+    }
+
+    switch (utype) {
+
+    case ASN1_GEN_FLAG_IMP:
+        /* Check for illegal multiple IMPLICIT tagging */
+        if (arg->imp_tag != -1) {
+            ASN1err(ASN1_F_ASN1_CB, ASN1_R_ILLEGAL_NESTED_TAGGING);
+            return -1;
+        }
+        if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class))
+            return -1;
+        break;
+
+    case ASN1_GEN_FLAG_EXP:
+
+        if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class))
+            return -1;
+        if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0))
+            return -1;
+        break;
+
+    case ASN1_GEN_FLAG_SEQWRAP:
+        if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1))
+            return -1;
+        break;
+
+    case ASN1_GEN_FLAG_SETWRAP:
+        if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1))
+            return -1;
+        break;
+
+    case ASN1_GEN_FLAG_BITWRAP:
+        if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1))
+            return -1;
+        break;
+
+    case ASN1_GEN_FLAG_OCTWRAP:
+        if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1))
+            return -1;
+        break;
+
+    case ASN1_GEN_FLAG_FORMAT:
+        if (!vstart) {
+            ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT);
+            return -1;
+        }
+        if (strncmp(vstart, "ASCII", 5) == 0)
+            arg->format = ASN1_GEN_FORMAT_ASCII;
+        else if (strncmp(vstart, "UTF8", 4) == 0)
+            arg->format = ASN1_GEN_FORMAT_UTF8;
+        else if (strncmp(vstart, "HEX", 3) == 0)
+            arg->format = ASN1_GEN_FORMAT_HEX;
+        else if (strncmp(vstart, "BITLIST", 7) == 0)
+            arg->format = ASN1_GEN_FORMAT_BITLIST;
+        else {
+            ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT);
+            return -1;
+        }
+        break;
+
+    }
+
+    return 1;
+
+}
+
+static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass)
+{
+    char erch[2];
+    long tag_num;
+    char *eptr;
+    if (!vstart)
+        return 0;
+    tag_num = strtoul(vstart, &eptr, 10);
+    /* Check we haven't gone past max length: should be impossible */
+    if (eptr && *eptr && (eptr > vstart + vlen))
+        return 0;
+    if (tag_num < 0) {
+        ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_NUMBER);
+        return 0;
+    }
+    *ptag = tag_num;
+    /* If we have non numeric characters, parse them */
+    if (eptr)
+        vlen -= eptr - vstart;
+    else
+        vlen = 0;
+    if (vlen) {
+        switch (*eptr) {
+
+        case 'U':
+            *pclass = V_ASN1_UNIVERSAL;
+            break;
+
+        case 'A':
+            *pclass = V_ASN1_APPLICATION;
+            break;
+
+        case 'P':
+            *pclass = V_ASN1_PRIVATE;
+            break;
+
+        case 'C':
+            *pclass = V_ASN1_CONTEXT_SPECIFIC;
+            break;
+
+        default:
+            erch[0] = *eptr;
+            erch[1] = 0;
+            ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_MODIFIER);
+            ERR_add_error_data(2, "Char=", erch);
+            return 0;
+
+        }
+    } else
+        *pclass = V_ASN1_CONTEXT_SPECIFIC;
+
+    return 1;
+
+}
+
+/* Handle multiple types: SET and SEQUENCE */
+
+static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf,
+                             int depth, int *perr)
+{
+    ASN1_TYPE *ret = NULL;
+    STACK_OF(ASN1_TYPE) *sk = NULL;
+    STACK_OF(CONF_VALUE) *sect = NULL;
+    unsigned char *der = NULL;
+    int derlen;
+    int i;
+    sk = sk_ASN1_TYPE_new_null();
+    if (!sk)
+        goto bad;
+    if (section) {
+        if (!cnf)
+            goto bad;
+        sect = X509V3_get_section(cnf, (char *)section);
+        if (!sect)
+            goto bad;
+        for (i = 0; i < sk_CONF_VALUE_num(sect); i++) {
+            ASN1_TYPE *typ =
+                generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf,
+                            depth + 1, perr);
+            if (!typ)
+                goto bad;
+            if (!sk_ASN1_TYPE_push(sk, typ))
+                goto bad;
+        }
+    }
+
+    /*
+     * Now we has a STACK of the components, convert to the correct form
+     */
+
+    if (utype == V_ASN1_SET)
+        derlen = i2d_ASN1_SET_ANY(sk, &der);
+    else
+        derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der);
+
+    if (derlen < 0)
+        goto bad;
+    if ((ret = ASN1_TYPE_new()) == NULL)
+        goto bad;
+    if ((ret->value.asn1_string = ASN1_STRING_type_new(utype)) == NULL)
+        goto bad;
+
+    ret->type = utype;
+    ret->value.asn1_string->data = der;
+    ret->value.asn1_string->length = derlen;
+
+    der = NULL;
+
+ bad:
+
+    OPENSSL_free(der);
+
+    sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
+    X509V3_section_free(cnf, sect);
+
+    return ret;
+}
+
+static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class,
+                      int exp_constructed, int exp_pad, int imp_ok)
+{
+    tag_exp_type *exp_tmp;
+    /* Can only have IMPLICIT if permitted */
+    if ((arg->imp_tag != -1) && !imp_ok) {
+        ASN1err(ASN1_F_APPEND_EXP, ASN1_R_ILLEGAL_IMPLICIT_TAG);
+        return 0;
+    }
+
+    if (arg->exp_count == ASN1_FLAG_EXP_MAX) {
+        ASN1err(ASN1_F_APPEND_EXP, ASN1_R_DEPTH_EXCEEDED);
+        return 0;
+    }
+
+    exp_tmp = &arg->exp_list[arg->exp_count++];
+
+    /*
+     * If IMPLICIT set tag to implicit value then reset implicit tag since it
+     * has been used.
+     */
+    if (arg->imp_tag != -1) {
+        exp_tmp->exp_tag = arg->imp_tag;
+        exp_tmp->exp_class = arg->imp_class;
+        arg->imp_tag = -1;
+        arg->imp_class = -1;
+    } else {
+        exp_tmp->exp_tag = exp_tag;
+        exp_tmp->exp_class = exp_class;
+    }
+    exp_tmp->exp_constructed = exp_constructed;
+    exp_tmp->exp_pad = exp_pad;
+
+    return 1;
+}
+
+static int asn1_str2tag(const char *tagstr, int len)
+{
+    unsigned int i;
+    static const struct tag_name_st *tntmp, tnst[] = {
+        ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN),
+        ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN),
+        ASN1_GEN_STR("NULL", V_ASN1_NULL),
+        ASN1_GEN_STR("INT", V_ASN1_INTEGER),
+        ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER),
+        ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED),
+        ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED),
+        ASN1_GEN_STR("OID", V_ASN1_OBJECT),
+        ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT),
+        ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME),
+        ASN1_GEN_STR("UTC", V_ASN1_UTCTIME),
+        ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME),
+        ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME),
+        ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING),
+        ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING),
+        ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING),
+        ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING),
+        ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING),
+        ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING),
+        ASN1_GEN_STR("IA5", V_ASN1_IA5STRING),
+        ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING),
+        ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING),
+        ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING),
+        ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING),
+        ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING),
+        ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING),
+        ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING),
+        ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING),
+        ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING),
+        ASN1_GEN_STR("T61", V_ASN1_T61STRING),
+        ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING),
+        ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING),
+        ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING),
+        ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING),
+        ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING),
+        ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING),
+
+        /* Special cases */
+        ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE),
+        ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE),
+        ASN1_GEN_STR("SET", V_ASN1_SET),
+        /* type modifiers */
+        /* Explicit tag */
+        ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP),
+        ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP),
+        /* Implicit tag */
+        ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP),
+        ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP),
+        /* OCTET STRING wrapper */
+        ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP),
+        /* SEQUENCE wrapper */
+        ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP),
+        /* SET wrapper */
+        ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP),
+        /* BIT STRING wrapper */
+        ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP),
+        ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT),
+        ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT),
+    };
+
+    if (len == -1)
+        len = strlen(tagstr);
+
+    tntmp = tnst;
+    for (i = 0; i < OSSL_NELEM(tnst); i++, tntmp++) {
+        if ((len == tntmp->len) && (strncmp(tntmp->strnam, tagstr, len) == 0))
+            return tntmp->tag;
+    }
+
+    return -1;
+}
+
+static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
+{
+    ASN1_TYPE *atmp = NULL;
+    CONF_VALUE vtmp;
+    unsigned char *rdata;
+    long rdlen;
+    int no_unused = 1;
+
+    if ((atmp = ASN1_TYPE_new()) == NULL) {
+        ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    if (!str)
+        str = "";
+
+    switch (utype) {
+
+    case V_ASN1_NULL:
+        if (str && *str) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE);
+            goto bad_form;
+        }
+        break;
+
+    case V_ASN1_BOOLEAN:
+        if (format != ASN1_GEN_FORMAT_ASCII) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT);
+            goto bad_form;
+        }
+        vtmp.name = NULL;
+        vtmp.section = NULL;
+        vtmp.value = (char *)str;
+        if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN);
+            goto bad_str;
+        }
+        break;
+
+    case V_ASN1_INTEGER:
+    case V_ASN1_ENUMERATED:
+        if (format != ASN1_GEN_FORMAT_ASCII) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT);
+            goto bad_form;
+        }
+        if ((atmp->value.integer
+                    = s2i_ASN1_INTEGER(NULL, str)) == NULL) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER);
+            goto bad_str;
+        }
+        break;
+
+    case V_ASN1_OBJECT:
+        if (format != ASN1_GEN_FORMAT_ASCII) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT);
+            goto bad_form;
+        }
+        if ((atmp->value.object = OBJ_txt2obj(str, 0)) == NULL) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT);
+            goto bad_str;
+        }
+        break;
+
+    case V_ASN1_UTCTIME:
+    case V_ASN1_GENERALIZEDTIME:
+        if (format != ASN1_GEN_FORMAT_ASCII) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT);
+            goto bad_form;
+        }
+        if ((atmp->value.asn1_string = ASN1_STRING_new()) == NULL) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+            goto bad_str;
+        }
+        if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+            goto bad_str;
+        }
+        atmp->value.asn1_string->type = utype;
+        if (!ASN1_TIME_check(atmp->value.asn1_string)) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_TIME_VALUE);
+            goto bad_str;
+        }
+
+        break;
+
+    case V_ASN1_BMPSTRING:
+    case V_ASN1_PRINTABLESTRING:
+    case V_ASN1_IA5STRING:
+    case V_ASN1_T61STRING:
+    case V_ASN1_UTF8STRING:
+    case V_ASN1_VISIBLESTRING:
+    case V_ASN1_UNIVERSALSTRING:
+    case V_ASN1_GENERALSTRING:
+    case V_ASN1_NUMERICSTRING:
+        if (format == ASN1_GEN_FORMAT_ASCII)
+            format = MBSTRING_ASC;
+        else if (format == ASN1_GEN_FORMAT_UTF8)
+            format = MBSTRING_UTF8;
+        else {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT);
+            goto bad_form;
+        }
+
+        if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str,
+                               -1, format, ASN1_tag2bit(utype)) <= 0) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+            goto bad_str;
+        }
+
+        break;
+
+    case V_ASN1_BIT_STRING:
+    case V_ASN1_OCTET_STRING:
+        if ((atmp->value.asn1_string = ASN1_STRING_new()) == NULL) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+            goto bad_form;
+        }
+
+        if (format == ASN1_GEN_FORMAT_HEX) {
+            if ((rdata = OPENSSL_hexstr2buf(str, &rdlen)) == NULL) {
+                ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX);
+                goto bad_str;
+            }
+            atmp->value.asn1_string->data = rdata;
+            atmp->value.asn1_string->length = rdlen;
+            atmp->value.asn1_string->type = utype;
+        } else if (format == ASN1_GEN_FORMAT_ASCII)
+            ASN1_STRING_set(atmp->value.asn1_string, str, -1);
+        else if ((format == ASN1_GEN_FORMAT_BITLIST)
+                 && (utype == V_ASN1_BIT_STRING)) {
+            if (!CONF_parse_list
+                (str, ',', 1, bitstr_cb, atmp->value.bit_string)) {
+                ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR);
+                goto bad_str;
+            }
+            no_unused = 0;
+
+        } else {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
+            goto bad_form;
+        }
+
+        if ((utype == V_ASN1_BIT_STRING) && no_unused) {
+            atmp->value.asn1_string->flags
+                &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+            atmp->value.asn1_string->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+        }
+
+        break;
+
+    default:
+        ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE);
+        goto bad_str;
+    }
+
+    atmp->type = utype;
+    return atmp;
+
+ bad_str:
+    ERR_add_error_data(2, "string=", str);
+ bad_form:
+
+    ASN1_TYPE_free(atmp);
+    return NULL;
+
+}
+
+static int bitstr_cb(const char *elem, int len, void *bitstr)
+{
+    long bitnum;
+    char *eptr;
+    if (!elem)
+        return 0;
+    bitnum = strtoul(elem, &eptr, 10);
+    if (eptr && *eptr && (eptr != elem + len))
+        return 0;
+    if (bitnum < 0) {
+        ASN1err(ASN1_F_BITSTR_CB, ASN1_R_INVALID_NUMBER);
+        return 0;
+    }
+    if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) {
+        ASN1err(ASN1_F_BITSTR_CB, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    return 1;
+}
+
+static int mask_cb(const char *elem, int len, void *arg)
+{
+    unsigned long *pmask = arg, tmpmask;
+    int tag;
+    if (elem == NULL)
+        return 0;
+    if ((len == 3) && (strncmp(elem, "DIR", 3) == 0)) {
+        *pmask |= B_ASN1_DIRECTORYSTRING;
+        return 1;
+    }
+    tag = asn1_str2tag(elem, len);
+    if (!tag || (tag & ASN1_GEN_FLAG))
+        return 0;
+    tmpmask = ASN1_tag2bit(tag);
+    if (!tmpmask)
+        return 0;
+    *pmask |= tmpmask;
+    return 1;
+}
+
+int ASN1_str2mask(const char *str, unsigned long *pmask)
+{
+    *pmask = 0;
+    return CONF_parse_list(str, '|', 1, mask_cb, pmask);
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn1_item_list.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn1_item_list.c
new file mode 100644
index 0000000..9798192
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn1_item_list.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2000-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/cms.h>
+#include <openssl/dh.h>
+#include <openssl/ocsp.h>
+#include <openssl/pkcs7.h>
+#include <openssl/pkcs12.h>
+#include <openssl/rsa.h>
+#include <openssl/x509v3.h>
+
+#include "asn1_item_list.h"
+
+const ASN1_ITEM *ASN1_ITEM_lookup(const char *name)
+{
+    size_t i;
+
+    for (i = 0; i < OSSL_NELEM(asn1_item_list); i++) {
+        const ASN1_ITEM *it = ASN1_ITEM_ptr(asn1_item_list[i]);
+
+        if (strcmp(it->sname, name) == 0)
+            return it;
+    }
+    return NULL;
+}
+
+const ASN1_ITEM *ASN1_ITEM_get(size_t i)
+{
+    if (i >= OSSL_NELEM(asn1_item_list))
+        return NULL;
+    return ASN1_ITEM_ptr(asn1_item_list[i]);
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn1_item_list.h b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn1_item_list.h
new file mode 100644
index 0000000..db8107e
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn1_item_list.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2000-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+static ASN1_ITEM_EXP *asn1_item_list[] = {
+
+    ASN1_ITEM_ref(ACCESS_DESCRIPTION),
+#ifndef OPENSSL_NO_RFC3779
+    ASN1_ITEM_ref(ASIdOrRange),
+    ASN1_ITEM_ref(ASIdentifierChoice),
+    ASN1_ITEM_ref(ASIdentifiers),
+#endif
+    ASN1_ITEM_ref(ASN1_ANY),
+    ASN1_ITEM_ref(ASN1_BIT_STRING),
+    ASN1_ITEM_ref(ASN1_BMPSTRING),
+    ASN1_ITEM_ref(ASN1_BOOLEAN),
+    ASN1_ITEM_ref(ASN1_ENUMERATED),
+    ASN1_ITEM_ref(ASN1_FBOOLEAN),
+    ASN1_ITEM_ref(ASN1_GENERALIZEDTIME),
+    ASN1_ITEM_ref(ASN1_GENERALSTRING),
+    ASN1_ITEM_ref(ASN1_IA5STRING),
+    ASN1_ITEM_ref(ASN1_INTEGER),
+    ASN1_ITEM_ref(ASN1_NULL),
+    ASN1_ITEM_ref(ASN1_OBJECT),
+    ASN1_ITEM_ref(ASN1_OCTET_STRING_NDEF),
+    ASN1_ITEM_ref(ASN1_OCTET_STRING),
+    ASN1_ITEM_ref(ASN1_PRINTABLESTRING),
+    ASN1_ITEM_ref(ASN1_PRINTABLE),
+    ASN1_ITEM_ref(ASN1_SEQUENCE_ANY),
+    ASN1_ITEM_ref(ASN1_SEQUENCE),
+    ASN1_ITEM_ref(ASN1_SET_ANY),
+    ASN1_ITEM_ref(ASN1_T61STRING),
+    ASN1_ITEM_ref(ASN1_TBOOLEAN),
+    ASN1_ITEM_ref(ASN1_TIME),
+    ASN1_ITEM_ref(ASN1_UNIVERSALSTRING),
+    ASN1_ITEM_ref(ASN1_UTCTIME),
+    ASN1_ITEM_ref(ASN1_UTF8STRING),
+    ASN1_ITEM_ref(ASN1_VISIBLESTRING),
+#ifndef OPENSSL_NO_RFC3779
+    ASN1_ITEM_ref(ASRange),
+#endif
+    ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
+    ASN1_ITEM_ref(AUTHORITY_KEYID),
+    ASN1_ITEM_ref(BASIC_CONSTRAINTS),
+    ASN1_ITEM_ref(BIGNUM),
+    ASN1_ITEM_ref(CBIGNUM),
+    ASN1_ITEM_ref(CERTIFICATEPOLICIES),
+#ifndef OPENSSL_NO_CMS
+    ASN1_ITEM_ref(CMS_ContentInfo),
+    ASN1_ITEM_ref(CMS_ReceiptRequest),
+#endif
+    ASN1_ITEM_ref(CRL_DIST_POINTS),
+#ifndef OPENSSL_NO_DH
+    ASN1_ITEM_ref(DHparams),
+#endif
+    ASN1_ITEM_ref(DIRECTORYSTRING),
+    ASN1_ITEM_ref(DISPLAYTEXT),
+    ASN1_ITEM_ref(DIST_POINT_NAME),
+    ASN1_ITEM_ref(DIST_POINT),
+#ifndef OPENSSL_NO_EC
+    ASN1_ITEM_ref(ECPARAMETERS),
+    ASN1_ITEM_ref(ECPKPARAMETERS),
+#endif
+    ASN1_ITEM_ref(EDIPARTYNAME),
+    ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
+    ASN1_ITEM_ref(GENERAL_NAMES),
+    ASN1_ITEM_ref(GENERAL_NAME),
+    ASN1_ITEM_ref(GENERAL_SUBTREE),
+#ifndef OPENSSL_NO_RFC3779
+    ASN1_ITEM_ref(IPAddressChoice),
+    ASN1_ITEM_ref(IPAddressFamily),
+    ASN1_ITEM_ref(IPAddressOrRange),
+    ASN1_ITEM_ref(IPAddressRange),
+#endif
+    ASN1_ITEM_ref(ISSUING_DIST_POINT),
+#if OPENSSL_API_COMPAT < 0x10200000L
+    ASN1_ITEM_ref(LONG),
+#endif
+    ASN1_ITEM_ref(NAME_CONSTRAINTS),
+    ASN1_ITEM_ref(NETSCAPE_CERT_SEQUENCE),
+    ASN1_ITEM_ref(NETSCAPE_SPKAC),
+    ASN1_ITEM_ref(NETSCAPE_SPKI),
+    ASN1_ITEM_ref(NOTICEREF),
+#ifndef OPENSSL_NO_OCSP
+    ASN1_ITEM_ref(OCSP_BASICRESP),
+    ASN1_ITEM_ref(OCSP_CERTID),
+    ASN1_ITEM_ref(OCSP_CERTSTATUS),
+    ASN1_ITEM_ref(OCSP_CRLID),
+    ASN1_ITEM_ref(OCSP_ONEREQ),
+    ASN1_ITEM_ref(OCSP_REQINFO),
+    ASN1_ITEM_ref(OCSP_REQUEST),
+    ASN1_ITEM_ref(OCSP_RESPBYTES),
+    ASN1_ITEM_ref(OCSP_RESPDATA),
+    ASN1_ITEM_ref(OCSP_RESPID),
+    ASN1_ITEM_ref(OCSP_RESPONSE),
+    ASN1_ITEM_ref(OCSP_REVOKEDINFO),
+    ASN1_ITEM_ref(OCSP_SERVICELOC),
+    ASN1_ITEM_ref(OCSP_SIGNATURE),
+    ASN1_ITEM_ref(OCSP_SINGLERESP),
+#endif
+    ASN1_ITEM_ref(OTHERNAME),
+    ASN1_ITEM_ref(PBE2PARAM),
+    ASN1_ITEM_ref(PBEPARAM),
+    ASN1_ITEM_ref(PBKDF2PARAM),
+    ASN1_ITEM_ref(PKCS12_AUTHSAFES),
+    ASN1_ITEM_ref(PKCS12_BAGS),
+    ASN1_ITEM_ref(PKCS12_MAC_DATA),
+    ASN1_ITEM_ref(PKCS12_SAFEBAGS),
+    ASN1_ITEM_ref(PKCS12_SAFEBAG),
+    ASN1_ITEM_ref(PKCS12),
+    ASN1_ITEM_ref(PKCS7_ATTR_SIGN),
+    ASN1_ITEM_ref(PKCS7_ATTR_VERIFY),
+    ASN1_ITEM_ref(PKCS7_DIGEST),
+    ASN1_ITEM_ref(PKCS7_ENCRYPT),
+    ASN1_ITEM_ref(PKCS7_ENC_CONTENT),
+    ASN1_ITEM_ref(PKCS7_ENVELOPE),
+    ASN1_ITEM_ref(PKCS7_ISSUER_AND_SERIAL),
+    ASN1_ITEM_ref(PKCS7_RECIP_INFO),
+    ASN1_ITEM_ref(PKCS7_SIGNED),
+    ASN1_ITEM_ref(PKCS7_SIGNER_INFO),
+    ASN1_ITEM_ref(PKCS7_SIGN_ENVELOPE),
+    ASN1_ITEM_ref(PKCS7),
+    ASN1_ITEM_ref(PKCS8_PRIV_KEY_INFO),
+    ASN1_ITEM_ref(PKEY_USAGE_PERIOD),
+    ASN1_ITEM_ref(POLICYINFO),
+    ASN1_ITEM_ref(POLICYQUALINFO),
+    ASN1_ITEM_ref(POLICY_CONSTRAINTS),
+    ASN1_ITEM_ref(POLICY_MAPPINGS),
+    ASN1_ITEM_ref(POLICY_MAPPING),
+    ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION),
+    ASN1_ITEM_ref(PROXY_POLICY),
+#ifndef OPENSSL_NO_RSA
+    ASN1_ITEM_ref(RSAPrivateKey),
+    ASN1_ITEM_ref(RSAPublicKey),
+    ASN1_ITEM_ref(RSA_OAEP_PARAMS),
+    ASN1_ITEM_ref(RSA_PSS_PARAMS),
+#endif
+#ifndef OPENSSL_NO_SCRYPT
+    ASN1_ITEM_ref(SCRYPT_PARAMS),
+#endif
+    ASN1_ITEM_ref(SXNETID),
+    ASN1_ITEM_ref(SXNET),
+    ASN1_ITEM_ref(USERNOTICE),
+    ASN1_ITEM_ref(X509_ALGORS),
+    ASN1_ITEM_ref(X509_ALGOR),
+    ASN1_ITEM_ref(X509_ATTRIBUTE),
+    ASN1_ITEM_ref(X509_CERT_AUX),
+    ASN1_ITEM_ref(X509_CINF),
+    ASN1_ITEM_ref(X509_CRL_INFO),
+    ASN1_ITEM_ref(X509_CRL),
+    ASN1_ITEM_ref(X509_EXTENSIONS),
+    ASN1_ITEM_ref(X509_EXTENSION),
+    ASN1_ITEM_ref(X509_NAME_ENTRY),
+    ASN1_ITEM_ref(X509_NAME),
+    ASN1_ITEM_ref(X509_PUBKEY),
+    ASN1_ITEM_ref(X509_REQ_INFO),
+    ASN1_ITEM_ref(X509_REQ),
+    ASN1_ITEM_ref(X509_REVOKED),
+    ASN1_ITEM_ref(X509_SIG),
+    ASN1_ITEM_ref(X509_VAL),
+    ASN1_ITEM_ref(X509),
+#if OPENSSL_API_COMPAT < 0x10200000L
+    ASN1_ITEM_ref(ZLONG),
+#endif
+    ASN1_ITEM_ref(INT32),
+    ASN1_ITEM_ref(UINT32),
+    ASN1_ITEM_ref(ZINT32),
+    ASN1_ITEM_ref(ZUINT32),
+    ASN1_ITEM_ref(INT64),
+    ASN1_ITEM_ref(UINT64),
+    ASN1_ITEM_ref(ZINT64),
+    ASN1_ITEM_ref(ZUINT64),
+};
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn1_lib.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn1_lib.c
new file mode 100644
index 0000000..b9b7ad8
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn1_lib.c
@@ -0,0 +1,417 @@
+/*
+ * Copyright 1995-2021 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <limits.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include "asn1_local.h"
+
+static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
+                           long max);
+static void asn1_put_length(unsigned char **pp, int length);
+
+static int _asn1_check_infinite_end(const unsigned char **p, long len)
+{
+    /*
+     * If there is 0 or 1 byte left, the length check should pick things up
+     */
+    if (len <= 0)
+        return 1;
+    else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) {
+        (*p) += 2;
+        return 1;
+    }
+    return 0;
+}
+
+int ASN1_check_infinite_end(unsigned char **p, long len)
+{
+    return _asn1_check_infinite_end((const unsigned char **)p, len);
+}
+
+int ASN1_const_check_infinite_end(const unsigned char **p, long len)
+{
+    return _asn1_check_infinite_end(p, len);
+}
+
+int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
+                    int *pclass, long omax)
+{
+    int i, ret;
+    long l;
+    const unsigned char *p = *pp;
+    int tag, xclass, inf;
+    long max = omax;
+
+    if (!max)
+        goto err;
+    ret = (*p & V_ASN1_CONSTRUCTED);
+    xclass = (*p & V_ASN1_PRIVATE);
+    i = *p & V_ASN1_PRIMITIVE_TAG;
+    if (i == V_ASN1_PRIMITIVE_TAG) { /* high-tag */
+        p++;
+        if (--max == 0)
+            goto err;
+        l = 0;
+        while (*p & 0x80) {
+            l <<= 7L;
+            l |= *(p++) & 0x7f;
+            if (--max == 0)
+                goto err;
+            if (l > (INT_MAX >> 7L))
+                goto err;
+        }
+        l <<= 7L;
+        l |= *(p++) & 0x7f;
+        tag = (int)l;
+        if (--max == 0)
+            goto err;
+    } else {
+        tag = i;
+        p++;
+        if (--max == 0)
+            goto err;
+    }
+    *ptag = tag;
+    *pclass = xclass;
+    if (!asn1_get_length(&p, &inf, plength, max))
+        goto err;
+
+    if (inf && !(ret & V_ASN1_CONSTRUCTED))
+        goto err;
+
+    if (*plength > (omax - (p - *pp))) {
+        ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_TOO_LONG);
+        /*
+         * Set this so that even if things are not long enough the values are
+         * set correctly
+         */
+        ret |= 0x80;
+    }
+    *pp = p;
+    return ret | inf;
+ err:
+    ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_HEADER_TOO_LONG);
+    return 0x80;
+}
+
+/*
+ * Decode a length field.
+ * The short form is a single byte defining a length 0 - 127.
+ * The long form is a byte 0 - 127 with the top bit set and this indicates
+ * the number of following octets that contain the length.  These octets
+ * are stored most significant digit first.
+ */
+static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
+                           long max)
+{
+    const unsigned char *p = *pp;
+    unsigned long ret = 0;
+    int i;
+
+    if (max-- < 1)
+        return 0;
+    if (*p == 0x80) {
+        *inf = 1;
+        p++;
+    } else {
+        *inf = 0;
+        i = *p & 0x7f;
+        if (*p++ & 0x80) {
+            if (max < i + 1)
+                return 0;
+            /* Skip leading zeroes */
+            while (i > 0 && *p == 0) {
+                p++;
+                i--;
+            }
+            if (i > (int)sizeof(long))
+                return 0;
+            while (i > 0) {
+                ret <<= 8;
+                ret |= *p++;
+                i--;
+            }
+            if (ret > LONG_MAX)
+                return 0;
+        } else
+            ret = i;
+    }
+    *pp = p;
+    *rl = (long)ret;
+    return 1;
+}
+
+/*
+ * class 0 is constructed constructed == 2 for indefinite length constructed
+ */
+void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
+                     int xclass)
+{
+    unsigned char *p = *pp;
+    int i, ttag;
+
+    i = (constructed) ? V_ASN1_CONSTRUCTED : 0;
+    i |= (xclass & V_ASN1_PRIVATE);
+    if (tag < 31)
+        *(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG);
+    else {
+        *(p++) = i | V_ASN1_PRIMITIVE_TAG;
+        for (i = 0, ttag = tag; ttag > 0; i++)
+            ttag >>= 7;
+        ttag = i;
+        while (i-- > 0) {
+            p[i] = tag & 0x7f;
+            if (i != (ttag - 1))
+                p[i] |= 0x80;
+            tag >>= 7;
+        }
+        p += ttag;
+    }
+    if (constructed == 2)
+        *(p++) = 0x80;
+    else
+        asn1_put_length(&p, length);
+    *pp = p;
+}
+
+int ASN1_put_eoc(unsigned char **pp)
+{
+    unsigned char *p = *pp;
+    *p++ = 0;
+    *p++ = 0;
+    *pp = p;
+    return 2;
+}
+
+static void asn1_put_length(unsigned char **pp, int length)
+{
+    unsigned char *p = *pp;
+    int i, l;
+    if (length <= 127)
+        *(p++) = (unsigned char)length;
+    else {
+        l = length;
+        for (i = 0; l > 0; i++)
+            l >>= 8;
+        *(p++) = i | 0x80;
+        l = i;
+        while (i-- > 0) {
+            p[i] = length & 0xff;
+            length >>= 8;
+        }
+        p += l;
+    }
+    *pp = p;
+}
+
+int ASN1_object_size(int constructed, int length, int tag)
+{
+    int ret = 1;
+    if (length < 0)
+        return -1;
+    if (tag >= 31) {
+        while (tag > 0) {
+            tag >>= 7;
+            ret++;
+        }
+    }
+    if (constructed == 2) {
+        ret += 3;
+    } else {
+        ret++;
+        if (length > 127) {
+            int tmplen = length;
+            while (tmplen > 0) {
+                tmplen >>= 8;
+                ret++;
+            }
+        }
+    }
+    if (ret >= INT_MAX - length)
+        return -1;
+    return ret + length;
+}
+
+int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
+{
+    if (str == NULL)
+        return 0;
+    dst->type = str->type;
+    if (!ASN1_STRING_set(dst, str->data, str->length))
+        return 0;
+    /* Copy flags but preserve embed value */
+    dst->flags &= ASN1_STRING_FLAG_EMBED;
+    dst->flags |= str->flags & ~ASN1_STRING_FLAG_EMBED;
+    return 1;
+}
+
+ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str)
+{
+    ASN1_STRING *ret;
+    if (!str)
+        return NULL;
+    ret = ASN1_STRING_new();
+    if (ret == NULL)
+        return NULL;
+    if (!ASN1_STRING_copy(ret, str)) {
+        ASN1_STRING_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+
+int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len_in)
+{
+    unsigned char *c;
+    const char *data = _data;
+    size_t len;
+
+    if (len_in < 0) {
+        if (data == NULL)
+            return 0;
+        len = strlen(data);
+    } else {
+        len = (size_t)len_in;
+    }
+    /*
+     * Verify that the length fits within an integer for assignment to
+     * str->length below.  The additional 1 is subtracted to allow for the
+     * '\0' terminator even though this isn't strictly necessary.
+     */
+    if (len > INT_MAX - 1) {
+        ASN1err(0, ASN1_R_TOO_LARGE);
+        return 0;
+    }
+    if ((size_t)str->length <= len || str->data == NULL) {
+        c = str->data;
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+        /* No NUL terminator in fuzzing builds */
+        str->data = OPENSSL_realloc(c, len != 0 ? len : 1);
+#else
+        str->data = OPENSSL_realloc(c, len + 1);
+#endif
+        if (str->data == NULL) {
+            ASN1err(ASN1_F_ASN1_STRING_SET, ERR_R_MALLOC_FAILURE);
+            str->data = c;
+            return 0;
+        }
+    }
+    str->length = len;
+    if (data != NULL) {
+        memcpy(str->data, data, len);
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+        /* Set the unused byte to something non NUL and printable. */
+        if (len == 0)
+            str->data[len] = '~';
+#else
+        /*
+         * Add a NUL terminator. This should not be necessary - but we add it as
+         * a safety precaution
+         */
+        str->data[len] = '\0';
+#endif
+    }
+    return 1;
+}
+
+void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
+{
+    OPENSSL_free(str->data);
+    str->data = data;
+    str->length = len;
+}
+
+ASN1_STRING *ASN1_STRING_new(void)
+{
+    return ASN1_STRING_type_new(V_ASN1_OCTET_STRING);
+}
+
+ASN1_STRING *ASN1_STRING_type_new(int type)
+{
+    ASN1_STRING *ret;
+
+    ret = OPENSSL_zalloc(sizeof(*ret));
+    if (ret == NULL) {
+        ASN1err(ASN1_F_ASN1_STRING_TYPE_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    ret->type = type;
+    return ret;
+}
+
+void asn1_string_embed_free(ASN1_STRING *a, int embed)
+{
+    if (a == NULL)
+        return;
+    if (!(a->flags & ASN1_STRING_FLAG_NDEF))
+        OPENSSL_free(a->data);
+    if (embed == 0)
+        OPENSSL_free(a);
+}
+
+void ASN1_STRING_free(ASN1_STRING *a)
+{
+    if (a == NULL)
+        return;
+    asn1_string_embed_free(a, a->flags & ASN1_STRING_FLAG_EMBED);
+}
+
+void ASN1_STRING_clear_free(ASN1_STRING *a)
+{
+    if (a == NULL)
+        return;
+    if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
+        OPENSSL_cleanse(a->data, a->length);
+    ASN1_STRING_free(a);
+}
+
+int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
+{
+    int i;
+
+    i = (a->length - b->length);
+    if (i == 0) {
+        if (a->length != 0)
+            i = memcmp(a->data, b->data, a->length);
+        if (i == 0)
+            return a->type - b->type;
+        else
+            return i;
+    } else
+        return i;
+}
+
+int ASN1_STRING_length(const ASN1_STRING *x)
+{
+    return x->length;
+}
+
+void ASN1_STRING_length_set(ASN1_STRING *x, int len)
+{
+    x->length = len;
+}
+
+int ASN1_STRING_type(const ASN1_STRING *x)
+{
+    return x->type;
+}
+
+const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x)
+{
+    return x->data;
+}
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+unsigned char *ASN1_STRING_data(ASN1_STRING *x)
+{
+    return x->data;
+}
+#endif
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn1_local.h b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn1_local.h
new file mode 100644
index 0000000..cec1417
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn1_local.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2005-2017 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/* Internal ASN1 structures and functions: not for application use */
+
+int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d);
+int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d);
+int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d);
+
+/* ASN1 scan context structure */
+
+struct asn1_sctx_st {
+    /* The ASN1_ITEM associated with this field */
+    const ASN1_ITEM *it;
+    /* If ASN1_TEMPLATE associated with this field */
+    const ASN1_TEMPLATE *tt;
+    /* Various flags associated with field and context */
+    unsigned long flags;
+    /* If SEQUENCE OF or SET OF, field index */
+    int skidx;
+    /* ASN1 depth of field */
+    int depth;
+    /* Structure and field name */
+    const char *sname, *fname;
+    /* If a primitive type the type of underlying field */
+    int prim_type;
+    /* The field value itself */
+    ASN1_VALUE **field;
+    /* Callback to pass information to */
+    int (*scan_cb) (ASN1_SCTX *ctx);
+    /* Context specific application data */
+    void *app_data;
+} /* ASN1_SCTX */ ;
+
+typedef struct mime_param_st MIME_PARAM;
+DEFINE_STACK_OF(MIME_PARAM)
+typedef struct mime_header_st MIME_HEADER;
+DEFINE_STACK_OF(MIME_HEADER)
+
+void asn1_string_embed_free(ASN1_STRING *a, int embed);
+
+int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it);
+int asn1_set_choice_selector(ASN1_VALUE **pval, int value,
+                             const ASN1_ITEM *it);
+
+ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+
+const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
+                                 int nullerr);
+
+int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it);
+
+void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it);
+void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
+                     const ASN1_ITEM *it);
+int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
+                  const ASN1_ITEM *it);
+
+void asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed);
+void asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed);
+void asn1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+
+ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
+                             long length);
+int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp);
+ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
+                                     const unsigned char **pp, long length);
+int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp);
+ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
+                               long length);
+
+/* Internal functions used by x_int64.c */
+int c2i_uint64_int(uint64_t *ret, int *neg, const unsigned char **pp, long len);
+int i2c_uint64_int(unsigned char *p, uint64_t r, int neg);
+
+ASN1_TIME *asn1_time_from_tm(ASN1_TIME *s, struct tm *ts, int type);
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn1_par.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn1_par.c
new file mode 100644
index 0000000..a32fa47
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn1_par.c
@@ -0,0 +1,380 @@
+/*
+ * Copyright 1995-2021 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/asn1.h>
+
+#ifndef ASN1_PARSE_MAXDEPTH
+#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 const char fmt[] = "%-18s";
+    char str[128];
+    const char *p;
+
+    if (constructed & V_ASN1_CONSTRUCTED)
+        p = "cons: ";
+    else
+        p = "prim: ";
+    if (BIO_write(bp, p, 6) < 6)
+        goto err;
+    BIO_indent(bp, indent, 128);
+
+    p = str;
+    if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
+        BIO_snprintf(str, sizeof(str), "priv [ %d ] ", tag);
+    else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
+        BIO_snprintf(str, sizeof(str), "cont [ %d ]", tag);
+    else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
+        BIO_snprintf(str, sizeof(str), "appl [ %d ]", tag);
+    else if (tag > 30)
+        BIO_snprintf(str, sizeof(str), "<ASN1 %d>", tag);
+    else
+        p = ASN1_tag2str(tag);
+
+    if (BIO_printf(bp, fmt, p) <= 0)
+        goto err;
+    return 1;
+ err:
+    return 0;
+}
+
+int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent)
+{
+    return asn1_parse2(bp, &pp, len, 0, 0, indent, 0);
+}
+
+int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent,
+                    int dump)
+{
+    return asn1_parse2(bp, &pp, len, 0, 0, indent, dump);
+}
+
+static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
+                       int offset, int depth, int indent, int dump)
+{
+    const unsigned char *p, *ep, *tot, *op, *opp;
+    long len;
+    int tag, xclass, ret = 0;
+    int nl, hl, j, r;
+    ASN1_OBJECT *o = NULL;
+    ASN1_OCTET_STRING *os = NULL;
+    ASN1_INTEGER *ai = NULL;
+    ASN1_ENUMERATED *ae = NULL;
+    /* ASN1_BMPSTRING *bmp=NULL; */
+    int dump_indent, dump_cont = 0;
+
+    if (depth > ASN1_PARSE_MAXDEPTH) {
+        BIO_puts(bp, "BAD RECURSION DEPTH\n");
+        return 0;
+    }
+
+    dump_indent = 6;            /* Because we know BIO_dump_indent() */
+    p = *pp;
+    tot = p + length;
+    while (length > 0) {
+        op = p;
+        j = ASN1_get_object(&p, &len, &tag, &xclass, length);
+        if (j & 0x80) {
+            if (BIO_write(bp, "Error in encoding\n", 18) <= 0)
+                goto end;
+            ret = 0;
+            goto end;
+        }
+        hl = (p - op);
+        length -= hl;
+        /*
+         * 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))
+            goto end;
+        if (j & V_ASN1_CONSTRUCTED) {
+            const unsigned char *sp = p;
+
+            ep = p + len;
+            if (BIO_write(bp, "\n", 1) <= 0)
+                goto end;
+            if (len > length) {
+                BIO_printf(bp, "length is greater than %ld\n", length);
+                ret = 0;
+                goto end;
+            }
+            if ((j == 0x21) && (len == 0)) {
+                for (;;) {
+                    r = asn1_parse2(bp, &p, (long)(tot - p),
+                                    offset + (p - *pp), depth + 1,
+                                    indent, dump);
+                    if (r == 0) {
+                        ret = 0;
+                        goto end;
+                    }
+                    if ((r == 2) || (p >= tot)) {
+                        len = p - sp;
+                        break;
+                    }
+                }
+            } else {
+                long tmp = len;
+
+                while (p < ep) {
+                    sp = p;
+                    r = asn1_parse2(bp, &p, tmp,
+                                    offset + (p - *pp), depth + 1,
+                                    indent, dump);
+                    if (r == 0) {
+                        ret = 0;
+                        goto end;
+                    }
+                    tmp -= p - sp;
+                }
+            }
+        } else if (xclass != 0) {
+            p += len;
+            if (BIO_write(bp, "\n", 1) <= 0)
+                goto end;
+        } else {
+            nl = 0;
+            if ((tag == V_ASN1_PRINTABLESTRING) ||
+                (tag == V_ASN1_T61STRING) ||
+                (tag == V_ASN1_IA5STRING) ||
+                (tag == V_ASN1_VISIBLESTRING) ||
+                (tag == V_ASN1_NUMERICSTRING) ||
+                (tag == V_ASN1_UTF8STRING) ||
+                (tag == V_ASN1_UTCTIME) || (tag == V_ASN1_GENERALIZEDTIME)) {
+                if (BIO_write(bp, ":", 1) <= 0)
+                    goto end;
+                if ((len > 0) && BIO_write(bp, (const char *)p, (int)len)
+                    != (int)len)
+                    goto end;
+            } else if (tag == V_ASN1_OBJECT) {
+                opp = op;
+                if (d2i_ASN1_OBJECT(&o, &opp, len + hl) != NULL) {
+                    if (BIO_write(bp, ":", 1) <= 0)
+                        goto end;
+                    i2a_ASN1_OBJECT(bp, o);
+                } else {
+                    if (BIO_puts(bp, ":BAD OBJECT") <= 0)
+                        goto end;
+                    dump_cont = 1;
+                }
+            } else if (tag == V_ASN1_BOOLEAN) {
+                if (len != 1) {
+                    if (BIO_puts(bp, ":BAD BOOLEAN") <= 0)
+                        goto end;
+                    dump_cont = 1;
+                }
+                if (len > 0)
+                    BIO_printf(bp, ":%u", p[0]);
+            } else if (tag == V_ASN1_BMPSTRING) {
+                /* do the BMP thang */
+            } else if (tag == V_ASN1_OCTET_STRING) {
+                int i, printable = 1;
+
+                opp = op;
+                os = d2i_ASN1_OCTET_STRING(NULL, &opp, len + hl);
+                if (os != NULL && os->length > 0) {
+                    opp = os->data;
+                    /*
+                     * testing whether the octet string is printable
+                     */
+                    for (i = 0; i < os->length; i++) {
+                        if (((opp[i] < ' ') &&
+                             (opp[i] != '\n') &&
+                             (opp[i] != '\r') &&
+                             (opp[i] != '\t')) || (opp[i] > '~')) {
+                            printable = 0;
+                            break;
+                        }
+                    }
+                    if (printable)
+                        /* printable string */
+                    {
+                        if (BIO_write(bp, ":", 1) <= 0)
+                            goto end;
+                        if (BIO_write(bp, (const char *)opp, os->length) <= 0)
+                            goto end;
+                    } else if (!dump)
+                        /*
+                         * not printable => print octet string as hex dump
+                         */
+                    {
+                        if (BIO_write(bp, "[HEX DUMP]:", 11) <= 0)
+                            goto end;
+                        for (i = 0; i < os->length; i++) {
+                            if (BIO_printf(bp, "%02X", opp[i]) <= 0)
+                                goto end;
+                        }
+                    } else
+                        /* print the normal dump */
+                    {
+                        if (!nl) {
+                            if (BIO_write(bp, "\n", 1) <= 0)
+                                goto end;
+                        }
+                        if (BIO_dump_indent(bp,
+                                            (const char *)opp,
+                                            ((dump == -1 || dump >
+                                              os->
+                                              length) ? os->length : dump),
+                                            dump_indent) <= 0)
+                            goto end;
+                        nl = 1;
+                    }
+                }
+                ASN1_OCTET_STRING_free(os);
+                os = NULL;
+            } else if (tag == V_ASN1_INTEGER) {
+                int i;
+
+                opp = op;
+                ai = d2i_ASN1_INTEGER(NULL, &opp, len + hl);
+                if (ai != NULL) {
+                    if (BIO_write(bp, ":", 1) <= 0)
+                        goto end;
+                    if (ai->type == V_ASN1_NEG_INTEGER)
+                        if (BIO_write(bp, "-", 1) <= 0)
+                            goto end;
+                    for (i = 0; i < ai->length; i++) {
+                        if (BIO_printf(bp, "%02X", ai->data[i]) <= 0)
+                            goto end;
+                    }
+                    if (ai->length == 0) {
+                        if (BIO_write(bp, "00", 2) <= 0)
+                            goto end;
+                    }
+                } else {
+                    if (BIO_puts(bp, ":BAD INTEGER") <= 0)
+                        goto end;
+                    dump_cont = 1;
+                }
+                ASN1_INTEGER_free(ai);
+                ai = NULL;
+            } else if (tag == V_ASN1_ENUMERATED) {
+                int i;
+
+                opp = op;
+                ae = d2i_ASN1_ENUMERATED(NULL, &opp, len + hl);
+                if (ae != NULL) {
+                    if (BIO_write(bp, ":", 1) <= 0)
+                        goto end;
+                    if (ae->type == V_ASN1_NEG_ENUMERATED)
+                        if (BIO_write(bp, "-", 1) <= 0)
+                            goto end;
+                    for (i = 0; i < ae->length; i++) {
+                        if (BIO_printf(bp, "%02X", ae->data[i]) <= 0)
+                            goto end;
+                    }
+                    if (ae->length == 0) {
+                        if (BIO_write(bp, "00", 2) <= 0)
+                            goto end;
+                    }
+                } else {
+                    if (BIO_puts(bp, ":BAD ENUMERATED") <= 0)
+                        goto end;
+                    dump_cont = 1;
+                }
+                ASN1_ENUMERATED_free(ae);
+                ae = NULL;
+            } else if (len > 0 && dump) {
+                if (!nl) {
+                    if (BIO_write(bp, "\n", 1) <= 0)
+                        goto end;
+                }
+                if (BIO_dump_indent(bp, (const char *)p,
+                                    ((dump == -1 || dump > len) ? len : dump),
+                                    dump_indent) <= 0)
+                    goto end;
+                nl = 1;
+            }
+            if (dump_cont) {
+                int i;
+                const unsigned char *tmp = op + hl;
+                if (BIO_puts(bp, ":[") <= 0)
+                    goto end;
+                for (i = 0; i < len; i++) {
+                    if (BIO_printf(bp, "%02X", tmp[i]) <= 0)
+                        goto end;
+                }
+                if (BIO_puts(bp, "]") <= 0)
+                    goto end;
+                dump_cont = 0;
+            }
+
+            if (!nl) {
+                if (BIO_write(bp, "\n", 1) <= 0)
+                    goto end;
+            }
+            p += len;
+            if ((tag == V_ASN1_EOC) && (xclass == 0)) {
+                ret = 2;        /* End of sequence */
+                goto end;
+            }
+        }
+        length -= len;
+    }
+    ret = 1;
+ end:
+    ASN1_OBJECT_free(o);
+    ASN1_OCTET_STRING_free(os);
+    ASN1_INTEGER_free(ai);
+    ASN1_ENUMERATED_free(ae);
+    *pp = p;
+    return ret;
+}
+
+const char *ASN1_tag2str(int tag)
+{
+    static const char *const tag2str[] = {
+        /* 0-4 */
+        "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING",
+        /* 5-9 */
+        "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL",
+        /* 10-13 */
+        "ENUMERATED", "<ASN1 11>", "UTF8STRING", "<ASN1 13>",
+        /* 15-17 */
+        "<ASN1 14>", "<ASN1 15>", "SEQUENCE", "SET",
+        /* 18-20 */
+        "NUMERICSTRING", "PRINTABLESTRING", "T61STRING",
+        /* 21-24 */
+        "VIDEOTEXSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME",
+        /* 25-27 */
+        "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING",
+        /* 28-30 */
+        "UNIVERSALSTRING", "<ASN1 29>", "BMPSTRING"
+    };
+
+    if ((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
+        tag &= ~0x100;
+
+    if (tag < 0 || tag > 30)
+        return "(unknown)";
+    return tag2str[tag];
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn_mime.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn_mime.c
new file mode 100644
index 0000000..3685361
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn_mime.c
@@ -0,0 +1,975 @@
+/*
+ * Copyright 2008-2020 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "crypto/ctype.h"
+#include "internal/cryptlib.h"
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include "crypto/evp.h"
+#include "internal/bio.h"
+#include "asn1_local.h"
+
+/*
+ * Generalised MIME like utilities for streaming ASN1. Although many have a
+ * PKCS7/CMS like flavour others are more general purpose.
+ */
+
+/*
+ * MIME format structures Note that all are translated to lower case apart
+ * from parameter values. Quotes are stripped off
+ */
+
+struct mime_param_st {
+    char *param_name;           /* Param name e.g. "micalg" */
+    char *param_value;          /* Param value e.g. "sha1" */
+};
+
+struct mime_header_st {
+    char *name;                 /* Name of line e.g. "content-type" */
+    char *value;                /* Value of line e.g. "text/plain" */
+    STACK_OF(MIME_PARAM) *params; /* Zero or more parameters */
+};
+
+static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
+                            const ASN1_ITEM *it);
+static char *strip_ends(char *name);
+static char *strip_start(char *name);
+static char *strip_end(char *name);
+static MIME_HEADER *mime_hdr_new(const char *name, const char *value);
+static int mime_hdr_addparam(MIME_HEADER *mhdr, const char *name, const char *value);
+static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio);
+static int mime_hdr_cmp(const MIME_HEADER *const *a,
+                        const MIME_HEADER *const *b);
+static int mime_param_cmp(const MIME_PARAM *const *a,
+                          const MIME_PARAM *const *b);
+static void mime_param_free(MIME_PARAM *param);
+static int mime_bound_check(char *line, int linelen, const char *bound, int blen);
+static int multi_split(BIO *bio, const char *bound, STACK_OF(BIO) **ret);
+static int strip_eol(char *linebuf, int *plen, int flags);
+static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, const char *name);
+static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, const char *name);
+static void mime_hdr_free(MIME_HEADER *hdr);
+
+#define MAX_SMLEN 1024
+#define mime_debug(x)           /* x */
+
+/* Output an ASN1 structure in BER format streaming if necessary */
+
+int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+                        const ASN1_ITEM *it)
+{
+    /* If streaming create stream BIO and copy all content through it */
+    if (flags & SMIME_STREAM) {
+        BIO *bio, *tbio;
+        bio = BIO_new_NDEF(out, val, it);
+        if (!bio) {
+            ASN1err(ASN1_F_I2D_ASN1_BIO_STREAM, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        SMIME_crlf_copy(in, bio, flags);
+        (void)BIO_flush(bio);
+        /* Free up successive BIOs until we hit the old output BIO */
+        do {
+            tbio = BIO_pop(bio);
+            BIO_free(bio);
+            bio = tbio;
+        } while (bio != out);
+    }
+    /*
+     * else just write out ASN1 structure which will have all content stored
+     * internally
+     */
+    else
+        ASN1_item_i2d_bio(it, out, val);
+    return 1;
+}
+
+/* Base 64 read and write of ASN1 structure */
+
+static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+                          const ASN1_ITEM *it)
+{
+    BIO *b64;
+    int r;
+    b64 = BIO_new(BIO_f_base64());
+    if (b64 == NULL) {
+        ASN1err(ASN1_F_B64_WRITE_ASN1, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    /*
+     * prepend the b64 BIO so all data is base64 encoded.
+     */
+    out = BIO_push(b64, out);
+    r = i2d_ASN1_bio_stream(out, val, in, flags, it);
+    (void)BIO_flush(out);
+    BIO_pop(out);
+    BIO_free(b64);
+    return r;
+}
+
+/* Streaming ASN1 PEM write */
+
+int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+                              const char *hdr, const ASN1_ITEM *it)
+{
+    int r;
+    BIO_printf(out, "-----BEGIN %s-----\n", hdr);
+    r = B64_write_ASN1(out, val, in, flags, it);
+    BIO_printf(out, "-----END %s-----\n", hdr);
+    return r;
+}
+
+static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it)
+{
+    BIO *b64;
+    ASN1_VALUE *val;
+
+    if ((b64 = BIO_new(BIO_f_base64())) == NULL) {
+        ASN1err(ASN1_F_B64_READ_ASN1, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    bio = BIO_push(b64, bio);
+    val = ASN1_item_d2i_bio(it, bio, NULL);
+    if (!val)
+        ASN1err(ASN1_F_B64_READ_ASN1, ASN1_R_DECODE_ERROR);
+    (void)BIO_flush(bio);
+    BIO_pop(bio);
+    BIO_free(b64);
+    return val;
+}
+
+/* Generate the MIME "micalg" parameter from RFC3851, RFC4490 */
+
+static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
+{
+    const EVP_MD *md;
+    int i, have_unknown = 0, write_comma, ret = 0, md_nid;
+    have_unknown = 0;
+    write_comma = 0;
+    for (i = 0; i < sk_X509_ALGOR_num(mdalgs); i++) {
+        if (write_comma)
+            BIO_write(out, ",", 1);
+        write_comma = 1;
+        md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm);
+        md = EVP_get_digestbynid(md_nid);
+        if (md && md->md_ctrl) {
+            int rv;
+            char *micstr;
+            rv = md->md_ctrl(NULL, EVP_MD_CTRL_MICALG, 0, &micstr);
+            if (rv > 0) {
+                BIO_puts(out, micstr);
+                OPENSSL_free(micstr);
+                continue;
+            }
+            if (rv != -2)
+                goto err;
+        }
+        switch (md_nid) {
+        case NID_sha1:
+            BIO_puts(out, "sha1");
+            break;
+
+        case NID_md5:
+            BIO_puts(out, "md5");
+            break;
+
+        case NID_sha256:
+            BIO_puts(out, "sha-256");
+            break;
+
+        case NID_sha384:
+            BIO_puts(out, "sha-384");
+            break;
+
+        case NID_sha512:
+            BIO_puts(out, "sha-512");
+            break;
+
+        case NID_id_GostR3411_94:
+            BIO_puts(out, "gostr3411-94");
+            goto err;
+
+        case NID_id_GostR3411_2012_256:
+            BIO_puts(out, "gostr3411-2012-256");
+            goto err;
+
+        case NID_id_GostR3411_2012_512:
+            BIO_puts(out, "gostr3411-2012-512");
+            goto err;
+
+        default:
+            if (have_unknown)
+                write_comma = 0;
+            else {
+                BIO_puts(out, "unknown");
+                have_unknown = 1;
+            }
+            break;
+
+        }
+    }
+
+    ret = 1;
+ err:
+
+    return ret;
+
+}
+
+/* SMIME sender */
+
+int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
+                     int ctype_nid, int econt_nid,
+                     STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it)
+{
+    char bound[33], c;
+    int i;
+    const char *mime_prefix, *mime_eol, *cname = "smime.p7m";
+    const char *msg_type = NULL;
+    if (flags & SMIME_OLDMIME)
+        mime_prefix = "application/x-pkcs7-";
+    else
+        mime_prefix = "application/pkcs7-";
+
+    if (flags & SMIME_CRLFEOL)
+        mime_eol = "\r\n";
+    else
+        mime_eol = "\n";
+    if ((flags & SMIME_DETACHED) && data) {
+        /* We want multipart/signed */
+        /* Generate a random boundary */
+        if (RAND_bytes((unsigned char *)bound, 32) <= 0)
+            return 0;
+        for (i = 0; i < 32; i++) {
+            c = bound[i] & 0xf;
+            if (c < 10)
+                c += '0';
+            else
+                c += 'A' - 10;
+            bound[i] = c;
+        }
+        bound[32] = 0;
+        BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
+        BIO_printf(bio, "Content-Type: multipart/signed;");
+        BIO_printf(bio, " protocol=\"%ssignature\";", mime_prefix);
+        BIO_puts(bio, " micalg=\"");
+        asn1_write_micalg(bio, mdalgs);
+        BIO_printf(bio, "\"; boundary=\"----%s\"%s%s",
+                   bound, mime_eol, mime_eol);
+        BIO_printf(bio, "This is an S/MIME signed message%s%s",
+                   mime_eol, mime_eol);
+        /* Now write out the first part */
+        BIO_printf(bio, "------%s%s", bound, mime_eol);
+        if (!asn1_output_data(bio, data, val, flags, it))
+            return 0;
+        BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol);
+
+        /* Headers for signature */
+
+        BIO_printf(bio, "Content-Type: %ssignature;", mime_prefix);
+        BIO_printf(bio, " name=\"smime.p7s\"%s", mime_eol);
+        BIO_printf(bio, "Content-Transfer-Encoding: base64%s", mime_eol);
+        BIO_printf(bio, "Content-Disposition: attachment;");
+        BIO_printf(bio, " filename=\"smime.p7s\"%s%s", mime_eol, mime_eol);
+        B64_write_ASN1(bio, val, NULL, 0, it);
+        BIO_printf(bio, "%s------%s--%s%s", mime_eol, bound,
+                   mime_eol, mime_eol);
+        return 1;
+    }
+
+    /* Determine smime-type header */
+
+    if (ctype_nid == NID_pkcs7_enveloped)
+        msg_type = "enveloped-data";
+    else if (ctype_nid == NID_pkcs7_signed) {
+        if (econt_nid == NID_id_smime_ct_receipt)
+            msg_type = "signed-receipt";
+        else if (sk_X509_ALGOR_num(mdalgs) >= 0)
+            msg_type = "signed-data";
+        else
+            msg_type = "certs-only";
+    } else if (ctype_nid == NID_id_smime_ct_compressedData) {
+        msg_type = "compressed-data";
+        cname = "smime.p7z";
+    }
+    /* MIME headers */
+    BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
+    BIO_printf(bio, "Content-Disposition: attachment;");
+    BIO_printf(bio, " filename=\"%s\"%s", cname, mime_eol);
+    BIO_printf(bio, "Content-Type: %smime;", mime_prefix);
+    if (msg_type)
+        BIO_printf(bio, " smime-type=%s;", msg_type);
+    BIO_printf(bio, " name=\"%s\"%s", cname, mime_eol);
+    BIO_printf(bio, "Content-Transfer-Encoding: base64%s%s",
+               mime_eol, mime_eol);
+    if (!B64_write_ASN1(bio, val, data, flags, it))
+        return 0;
+    BIO_printf(bio, "%s", mime_eol);
+    return 1;
+}
+
+/* Handle output of ASN1 data */
+
+static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
+                            const ASN1_ITEM *it)
+{
+    BIO *tmpbio;
+    const ASN1_AUX *aux = it->funcs;
+    ASN1_STREAM_ARG sarg;
+    int rv = 1;
+
+    /*
+     * If data is not detached or resigning then the output BIO is already
+     * set up to finalise when it is written through.
+     */
+    if (!(flags & SMIME_DETACHED) || (flags & PKCS7_REUSE_DIGEST)) {
+        SMIME_crlf_copy(data, out, flags);
+        return 1;
+    }
+
+    if (!aux || !aux->asn1_cb) {
+        ASN1err(ASN1_F_ASN1_OUTPUT_DATA, ASN1_R_STREAMING_NOT_SUPPORTED);
+        return 0;
+    }
+
+    sarg.out = out;
+    sarg.ndef_bio = NULL;
+    sarg.boundary = NULL;
+
+    /* Let ASN1 code prepend any needed BIOs */
+
+    if (aux->asn1_cb(ASN1_OP_DETACHED_PRE, &val, it, &sarg) <= 0)
+        return 0;
+
+    /* Copy data across, passing through filter BIOs for processing */
+    SMIME_crlf_copy(data, sarg.ndef_bio, flags);
+
+    /* Finalize structure */
+    if (aux->asn1_cb(ASN1_OP_DETACHED_POST, &val, it, &sarg) <= 0)
+        rv = 0;
+
+    /* Now remove any digests prepended to the BIO */
+
+    while (sarg.ndef_bio != out) {
+        tmpbio = BIO_pop(sarg.ndef_bio);
+        BIO_free(sarg.ndef_bio);
+        sarg.ndef_bio = tmpbio;
+    }
+
+    return rv;
+
+}
+
+/*
+ * SMIME reader: handle multipart/signed and opaque signing. in multipart
+ * case the content is placed in a memory BIO pointed to by "bcont". In
+ * opaque this is set to NULL
+ */
+
+ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
+{
+    BIO *asnin;
+    STACK_OF(MIME_HEADER) *headers = NULL;
+    STACK_OF(BIO) *parts = NULL;
+    MIME_HEADER *hdr;
+    MIME_PARAM *prm;
+    ASN1_VALUE *val;
+    int ret;
+
+    if (bcont)
+        *bcont = NULL;
+
+    if ((headers = mime_parse_hdr(bio)) == NULL) {
+        ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_MIME_PARSE_ERROR);
+        return NULL;
+    }
+
+    if ((hdr = mime_hdr_find(headers, "content-type")) == NULL
+        || hdr->value == NULL) {
+        sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+        ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_CONTENT_TYPE);
+        return NULL;
+    }
+
+    /* Handle multipart/signed */
+
+    if (strcmp(hdr->value, "multipart/signed") == 0) {
+        /* Split into two parts */
+        prm = mime_param_find(hdr, "boundary");
+        if (!prm || !prm->param_value) {
+            sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+            ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BOUNDARY);
+            return NULL;
+        }
+        ret = multi_split(bio, prm->param_value, &parts);
+        sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+        if (!ret || (sk_BIO_num(parts) != 2)) {
+            ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BODY_FAILURE);
+            sk_BIO_pop_free(parts, BIO_vfree);
+            return NULL;
+        }
+
+        /* Parse the signature piece */
+        asnin = sk_BIO_value(parts, 1);
+
+        if ((headers = mime_parse_hdr(asnin)) == NULL) {
+            ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_MIME_SIG_PARSE_ERROR);
+            sk_BIO_pop_free(parts, BIO_vfree);
+            return NULL;
+        }
+
+        /* Get content type */
+
+        if ((hdr = mime_hdr_find(headers, "content-type")) == NULL
+            || hdr->value == NULL) {
+            sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+            ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE);
+            sk_BIO_pop_free(parts, BIO_vfree);
+            return NULL;
+        }
+
+        if (strcmp(hdr->value, "application/x-pkcs7-signature") &&
+            strcmp(hdr->value, "application/pkcs7-signature")) {
+            ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_SIG_INVALID_MIME_TYPE);
+            ERR_add_error_data(2, "type: ", hdr->value);
+            sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+            sk_BIO_pop_free(parts, BIO_vfree);
+            return NULL;
+        }
+        sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+        /* Read in ASN1 */
+        if ((val = b64_read_asn1(asnin, it)) == NULL) {
+            ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_SIG_PARSE_ERROR);
+            sk_BIO_pop_free(parts, BIO_vfree);
+            return NULL;
+        }
+
+        if (bcont) {
+            *bcont = sk_BIO_value(parts, 0);
+            BIO_free(asnin);
+            sk_BIO_free(parts);
+        } else
+            sk_BIO_pop_free(parts, BIO_vfree);
+        return val;
+    }
+
+    /* OK, if not multipart/signed try opaque signature */
+
+    if (strcmp(hdr->value, "application/x-pkcs7-mime") &&
+        strcmp(hdr->value, "application/pkcs7-mime")) {
+        ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_INVALID_MIME_TYPE);
+        ERR_add_error_data(2, "type: ", hdr->value);
+        sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+        return NULL;
+    }
+
+    sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+
+    if ((val = b64_read_asn1(bio, it)) == NULL) {
+        ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_PARSE_ERROR);
+        return NULL;
+    }
+    return val;
+
+}
+
+/* Copy text from one BIO to another making the output CRLF at EOL */
+int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
+{
+    BIO *bf;
+    char eol;
+    int len;
+    char linebuf[MAX_SMLEN];
+    int ret;
+    /*
+     * Buffer output so we don't write one line at a time. This is useful
+     * when streaming as we don't end up with one OCTET STRING per line.
+     */
+    bf = BIO_new(BIO_f_buffer());
+    if (bf == NULL)
+        return 0;
+    out = BIO_push(bf, out);
+    if (flags & SMIME_BINARY) {
+        while ((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0)
+            BIO_write(out, linebuf, len);
+    } else {
+        int eolcnt = 0;
+        if (flags & SMIME_TEXT)
+            BIO_printf(out, "Content-Type: text/plain\r\n\r\n");
+        while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0) {
+            eol = strip_eol(linebuf, &len, flags);
+            if (len) {
+                /* Not EOF: write out all CRLF */
+                if (flags & SMIME_ASCIICRLF) {
+                    int i;
+                    for (i = 0; i < eolcnt; i++)
+                        BIO_write(out, "\r\n", 2);
+                    eolcnt = 0;
+                }
+                BIO_write(out, linebuf, len);
+                if (eol)
+                    BIO_write(out, "\r\n", 2);
+            } else if (flags & SMIME_ASCIICRLF)
+                eolcnt++;
+            else if (eol)
+                BIO_write(out, "\r\n", 2);
+        }
+    }
+    ret = BIO_flush(out);
+    BIO_pop(out);
+    BIO_free(bf);
+    if (ret <= 0)
+        return 0;
+
+    return 1;
+}
+
+/* Strip off headers if they are text/plain */
+int SMIME_text(BIO *in, BIO *out)
+{
+    char iobuf[4096];
+    int len;
+    STACK_OF(MIME_HEADER) *headers;
+    MIME_HEADER *hdr;
+
+    if ((headers = mime_parse_hdr(in)) == NULL) {
+        ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_PARSE_ERROR);
+        return 0;
+    }
+    if ((hdr = mime_hdr_find(headers, "content-type")) == NULL
+        || hdr->value == NULL) {
+        ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_NO_CONTENT_TYPE);
+        sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+        return 0;
+    }
+    if (strcmp(hdr->value, "text/plain")) {
+        ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_INVALID_MIME_TYPE);
+        ERR_add_error_data(2, "type: ", hdr->value);
+        sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+        return 0;
+    }
+    sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+    while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0)
+        BIO_write(out, iobuf, len);
+    if (len < 0)
+        return 0;
+    return 1;
+}
+
+/*
+ * Split a multipart/XXX message body into component parts: result is
+ * canonical parts in a STACK of bios
+ */
+
+static int multi_split(BIO *bio, const char *bound, STACK_OF(BIO) **ret)
+{
+    char linebuf[MAX_SMLEN];
+    int len, blen;
+    int eol = 0, next_eol = 0;
+    BIO *bpart = NULL;
+    STACK_OF(BIO) *parts;
+    char state, part, first;
+
+    blen = strlen(bound);
+    part = 0;
+    state = 0;
+    first = 1;
+    parts = sk_BIO_new_null();
+    *ret = parts;
+    if (*ret == NULL)
+        return 0;
+    while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
+        state = mime_bound_check(linebuf, len, bound, blen);
+        if (state == 1) {
+            first = 1;
+            part++;
+        } else if (state == 2) {
+            if (!sk_BIO_push(parts, bpart)) {
+                BIO_free(bpart);
+                return 0;
+            }
+            return 1;
+        } else if (part) {
+            /* Strip CR+LF from linebuf */
+            next_eol = strip_eol(linebuf, &len, 0);
+            if (first) {
+                first = 0;
+                if (bpart)
+                    if (!sk_BIO_push(parts, bpart)) {
+                        BIO_free(bpart);
+                        return 0;
+                    }
+                bpart = BIO_new(BIO_s_mem());
+                if (bpart == NULL)
+                    return 0;
+                BIO_set_mem_eof_return(bpart, 0);
+            } else if (eol)
+                BIO_write(bpart, "\r\n", 2);
+            eol = next_eol;
+            if (len)
+                BIO_write(bpart, linebuf, len);
+        }
+    }
+    BIO_free(bpart);
+    return 0;
+}
+
+/* This is the big one: parse MIME header lines up to message body */
+
+#define MIME_INVALID    0
+#define MIME_START      1
+#define MIME_TYPE       2
+#define MIME_NAME       3
+#define MIME_VALUE      4
+#define MIME_QUOTE      5
+#define MIME_COMMENT    6
+
+static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
+{
+    char *p, *q, c;
+    char *ntmp;
+    char linebuf[MAX_SMLEN];
+    MIME_HEADER *mhdr = NULL, *new_hdr = NULL;
+    STACK_OF(MIME_HEADER) *headers;
+    int len, state, save_state = 0;
+
+    headers = sk_MIME_HEADER_new(mime_hdr_cmp);
+    if (headers == NULL)
+        return NULL;
+    while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
+        /* If whitespace at line start then continuation line */
+        if (mhdr && ossl_isspace(linebuf[0]))
+            state = MIME_NAME;
+        else
+            state = MIME_START;
+        ntmp = NULL;
+        /* Go through all characters */
+        for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && (c != '\n');
+             p++) {
+
+            /*
+             * State machine to handle MIME headers if this looks horrible
+             * that's because it *is*
+             */
+
+            switch (state) {
+            case MIME_START:
+                if (c == ':') {
+                    state = MIME_TYPE;
+                    *p = 0;
+                    ntmp = strip_ends(q);
+                    q = p + 1;
+                }
+                break;
+
+            case MIME_TYPE:
+                if (c == ';') {
+                    mime_debug("Found End Value\n");
+                    *p = 0;
+                    new_hdr = mime_hdr_new(ntmp, strip_ends(q));
+                    if (new_hdr == NULL)
+                        goto err;
+                    if (!sk_MIME_HEADER_push(headers, new_hdr))
+                        goto err;
+                    mhdr = new_hdr;
+                    new_hdr = NULL;
+                    ntmp = NULL;
+                    q = p + 1;
+                    state = MIME_NAME;
+                } else if (c == '(') {
+                    save_state = state;
+                    state = MIME_COMMENT;
+                }
+                break;
+
+            case MIME_COMMENT:
+                if (c == ')') {
+                    state = save_state;
+                }
+                break;
+
+            case MIME_NAME:
+                if (c == '=') {
+                    state = MIME_VALUE;
+                    *p = 0;
+                    ntmp = strip_ends(q);
+                    q = p + 1;
+                }
+                break;
+
+            case MIME_VALUE:
+                if (c == ';') {
+                    state = MIME_NAME;
+                    *p = 0;
+                    mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
+                    ntmp = NULL;
+                    q = p + 1;
+                } else if (c == '"') {
+                    mime_debug("Found Quote\n");
+                    state = MIME_QUOTE;
+                } else if (c == '(') {
+                    save_state = state;
+                    state = MIME_COMMENT;
+                }
+                break;
+
+            case MIME_QUOTE:
+                if (c == '"') {
+                    mime_debug("Found Match Quote\n");
+                    state = MIME_VALUE;
+                }
+                break;
+            }
+        }
+
+        if (state == MIME_TYPE) {
+            new_hdr = mime_hdr_new(ntmp, strip_ends(q));
+            if (new_hdr == NULL)
+                goto err;
+            if (!sk_MIME_HEADER_push(headers, new_hdr))
+                goto err;
+            mhdr = new_hdr;
+            new_hdr = NULL;
+        } else if (state == MIME_VALUE)
+            mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
+        if (p == linebuf)
+            break;              /* Blank line means end of headers */
+    }
+
+    return headers;
+
+err:
+    mime_hdr_free(new_hdr);
+    sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+    return NULL;
+}
+
+static char *strip_ends(char *name)
+{
+    return strip_end(strip_start(name));
+}
+
+/* Strip a parameter of whitespace from start of param */
+static char *strip_start(char *name)
+{
+    char *p, c;
+    /* Look for first non white space or quote */
+    for (p = name; (c = *p); p++) {
+        if (c == '"') {
+            /* Next char is start of string if non null */
+            if (p[1])
+                return p + 1;
+            /* Else null string */
+            return NULL;
+        }
+        if (!ossl_isspace(c))
+            return p;
+    }
+    return NULL;
+}
+
+/* As above but strip from end of string : maybe should handle brackets? */
+static char *strip_end(char *name)
+{
+    char *p, c;
+    if (!name)
+        return NULL;
+    /* Look for first non white space or quote */
+    for (p = name + strlen(name) - 1; p >= name; p--) {
+        c = *p;
+        if (c == '"') {
+            if (p - 1 == name)
+                return NULL;
+            *p = 0;
+            return name;
+        }
+        if (ossl_isspace(c))
+            *p = 0;
+        else
+            return name;
+    }
+    return NULL;
+}
+
+static MIME_HEADER *mime_hdr_new(const char *name, const char *value)
+{
+    MIME_HEADER *mhdr = NULL;
+    char *tmpname = NULL, *tmpval = NULL, *p;
+
+    if (name) {
+        if ((tmpname = OPENSSL_strdup(name)) == NULL)
+            return NULL;
+        for (p = tmpname; *p; p++)
+            *p = ossl_tolower(*p);
+    }
+    if (value) {
+        if ((tmpval = OPENSSL_strdup(value)) == NULL)
+            goto err;
+        for (p = tmpval; *p; p++)
+            *p = ossl_tolower(*p);
+    }
+    mhdr = OPENSSL_malloc(sizeof(*mhdr));
+    if (mhdr == NULL)
+        goto err;
+    mhdr->name = tmpname;
+    mhdr->value = tmpval;
+    if ((mhdr->params = sk_MIME_PARAM_new(mime_param_cmp)) == NULL)
+        goto err;
+    return mhdr;
+
+ err:
+    OPENSSL_free(tmpname);
+    OPENSSL_free(tmpval);
+    OPENSSL_free(mhdr);
+    return NULL;
+}
+
+static int mime_hdr_addparam(MIME_HEADER *mhdr, const char *name, const char *value)
+{
+    char *tmpname = NULL, *tmpval = NULL, *p;
+    MIME_PARAM *mparam = NULL;
+
+    if (name) {
+        tmpname = OPENSSL_strdup(name);
+        if (!tmpname)
+            goto err;
+        for (p = tmpname; *p; p++)
+            *p = ossl_tolower(*p);
+    }
+    if (value) {
+        tmpval = OPENSSL_strdup(value);
+        if (!tmpval)
+            goto err;
+    }
+    /* Parameter values are case sensitive so leave as is */
+    mparam = OPENSSL_malloc(sizeof(*mparam));
+    if (mparam == NULL)
+        goto err;
+    mparam->param_name = tmpname;
+    mparam->param_value = tmpval;
+    if (!sk_MIME_PARAM_push(mhdr->params, mparam))
+        goto err;
+    return 1;
+ err:
+    OPENSSL_free(tmpname);
+    OPENSSL_free(tmpval);
+    OPENSSL_free(mparam);
+    return 0;
+}
+
+static int mime_hdr_cmp(const MIME_HEADER *const *a,
+                        const MIME_HEADER *const *b)
+{
+    if (!(*a)->name || !(*b)->name)
+        return ! !(*a)->name - ! !(*b)->name;
+
+    return strcmp((*a)->name, (*b)->name);
+}
+
+static int mime_param_cmp(const MIME_PARAM *const *a,
+                          const MIME_PARAM *const *b)
+{
+    if (!(*a)->param_name || !(*b)->param_name)
+        return ! !(*a)->param_name - ! !(*b)->param_name;
+    return strcmp((*a)->param_name, (*b)->param_name);
+}
+
+/* Find a header with a given name (if possible) */
+
+static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, const char *name)
+{
+    MIME_HEADER htmp;
+    int idx;
+
+    htmp.name = (char *)name;
+    htmp.value = NULL;
+    htmp.params = NULL;
+
+    idx = sk_MIME_HEADER_find(hdrs, &htmp);
+    return sk_MIME_HEADER_value(hdrs, idx);
+}
+
+static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, const char *name)
+{
+    MIME_PARAM param;
+    int idx;
+
+    param.param_name = (char *)name;
+    param.param_value = NULL;
+    idx = sk_MIME_PARAM_find(hdr->params, &param);
+    return sk_MIME_PARAM_value(hdr->params, idx);
+}
+
+static void mime_hdr_free(MIME_HEADER *hdr)
+{
+    if (hdr == NULL)
+        return;
+    OPENSSL_free(hdr->name);
+    OPENSSL_free(hdr->value);
+    if (hdr->params)
+        sk_MIME_PARAM_pop_free(hdr->params, mime_param_free);
+    OPENSSL_free(hdr);
+}
+
+static void mime_param_free(MIME_PARAM *param)
+{
+    OPENSSL_free(param->param_name);
+    OPENSSL_free(param->param_value);
+    OPENSSL_free(param);
+}
+
+/*-
+ * Check for a multipart boundary. Returns:
+ * 0 : no boundary
+ * 1 : part boundary
+ * 2 : final boundary
+ */
+static int mime_bound_check(char *line, int linelen, const char *bound, int blen)
+{
+    if (linelen == -1)
+        linelen = strlen(line);
+    if (blen == -1)
+        blen = strlen(bound);
+    /* Quickly eliminate if line length too short */
+    if (blen + 2 > linelen)
+        return 0;
+    /* Check for part boundary */
+    if ((strncmp(line, "--", 2) == 0)
+        && strncmp(line + 2, bound, blen) == 0) {
+        if (strncmp(line + blen + 2, "--", 2) == 0)
+            return 2;
+        else
+            return 1;
+    }
+    return 0;
+}
+
+static int strip_eol(char *linebuf, int *plen, int flags)
+{
+    int len = *plen;
+    char *p, c;
+    int is_eol = 0;
+
+    for (p = linebuf + len - 1; len > 0; len--, p--) {
+        c = *p;
+        if (c == '\n') {
+            is_eol = 1;
+        } else if (is_eol && flags & SMIME_ASCIICRLF && c == 32) {
+            /* Strip trailing space on a line; 32 == ASCII for ' ' */
+            continue;
+        } else if (c != '\r') {
+            break;
+        }
+    }
+    *plen = len;
+    return is_eol;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn_moid.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn_moid.c
new file mode 100644
index 0000000..732ce97
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn_moid.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2002-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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "crypto/ctype.h"
+#include <openssl/crypto.h>
+#include "internal/cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509.h>
+#include "crypto/asn1.h"
+#include "crypto/objects.h"
+
+/* Simple ASN1 OID module: add all objects in a given section */
+
+static int do_create(const char *value, const char *name);
+
+static int oid_module_init(CONF_IMODULE *md, const CONF *cnf)
+{
+    int i;
+    const char *oid_section;
+    STACK_OF(CONF_VALUE) *sktmp;
+    CONF_VALUE *oval;
+
+    oid_section = CONF_imodule_get_value(md);
+    if ((sktmp = NCONF_get_section(cnf, oid_section)) == NULL) {
+        ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ERROR_LOADING_SECTION);
+        return 0;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
+        oval = sk_CONF_VALUE_value(sktmp, i);
+        if (!do_create(oval->value, oval->name)) {
+            ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ADDING_OBJECT);
+            return 0;
+        }
+    }
+    return 1;
+}
+
+static void oid_module_finish(CONF_IMODULE *md)
+{
+}
+
+void ASN1_add_oid_module(void)
+{
+    CONF_module_add("oid_section", oid_module_init, oid_module_finish);
+}
+
+/*-
+ * Create an OID based on a name value pair. Accept two formats.
+ * shortname = 1.2.3.4
+ * shortname = some long name, 1.2.3.4
+ */
+
+static int do_create(const char *value, const char *name)
+{
+    int nid;
+    const char *ln, *ostr, *p;
+    char *lntmp = NULL;
+
+    p = strrchr(value, ',');
+    if (p == NULL) {
+        ln = name;
+        ostr = value;
+    } else {
+        ln = value;
+        ostr = p + 1;
+        if (*ostr == '\0')
+            return 0;
+        while (ossl_isspace(*ostr))
+            ostr++;
+        while (ossl_isspace(*ln))
+            ln++;
+        p--;
+        while (ossl_isspace(*p)) {
+            if (p == ln)
+                return 0;
+            p--;
+        }
+        p++;
+        if ((lntmp = OPENSSL_malloc((p - ln) + 1)) == NULL) {
+            ASN1err(ASN1_F_DO_CREATE, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        memcpy(lntmp, ln, p - ln);
+        lntmp[p - ln] = '\0';
+        ln = lntmp;
+    }
+
+    nid = OBJ_create(ostr, name, ln);
+
+    OPENSSL_free(lntmp);
+
+    return nid != NID_undef;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn_mstbl.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn_mstbl.c
new file mode 100644
index 0000000..ddcbcd0
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn_mstbl.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2012-2017 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <openssl/crypto.h>
+#include "internal/cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+/* Multi string module: add table entries from a given section */
+
+static int do_tcreate(const char *value, const char *name);
+
+static int stbl_module_init(CONF_IMODULE *md, const CONF *cnf)
+{
+    int i;
+    const char *stbl_section;
+    STACK_OF(CONF_VALUE) *sktmp;
+    CONF_VALUE *mval;
+
+    stbl_section = CONF_imodule_get_value(md);
+    if ((sktmp = NCONF_get_section(cnf, stbl_section)) == NULL) {
+        ASN1err(ASN1_F_STBL_MODULE_INIT, ASN1_R_ERROR_LOADING_SECTION);
+        return 0;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
+        mval = sk_CONF_VALUE_value(sktmp, i);
+        if (!do_tcreate(mval->value, mval->name)) {
+            ASN1err(ASN1_F_STBL_MODULE_INIT, ASN1_R_INVALID_VALUE);
+            return 0;
+        }
+    }
+    return 1;
+}
+
+static void stbl_module_finish(CONF_IMODULE *md)
+{
+    ASN1_STRING_TABLE_cleanup();
+}
+
+void ASN1_add_stable_module(void)
+{
+    CONF_module_add("stbl_section", stbl_module_init, stbl_module_finish);
+}
+
+/*
+ * Create an table entry based on a name value pair. format is oid_name =
+ * n1:v1, n2:v2,... where name is "min", "max", "mask" or "flags".
+ */
+
+static int do_tcreate(const char *value, const char *name)
+{
+    char *eptr;
+    int nid, i, rv = 0;
+    long tbl_min = -1, tbl_max = -1;
+    unsigned long tbl_mask = 0, tbl_flags = 0;
+    STACK_OF(CONF_VALUE) *lst = NULL;
+    CONF_VALUE *cnf = NULL;
+    nid = OBJ_sn2nid(name);
+    if (nid == NID_undef)
+        nid = OBJ_ln2nid(name);
+    if (nid == NID_undef)
+        goto err;
+    lst = X509V3_parse_list(value);
+    if (!lst)
+        goto err;
+    for (i = 0; i < sk_CONF_VALUE_num(lst); i++) {
+        cnf = sk_CONF_VALUE_value(lst, i);
+        if (strcmp(cnf->name, "min") == 0) {
+            tbl_min = strtoul(cnf->value, &eptr, 0);
+            if (*eptr)
+                goto err;
+        } else if (strcmp(cnf->name, "max") == 0) {
+            tbl_max = strtoul(cnf->value, &eptr, 0);
+            if (*eptr)
+                goto err;
+        } else if (strcmp(cnf->name, "mask") == 0) {
+            if (!ASN1_str2mask(cnf->value, &tbl_mask) || !tbl_mask)
+                goto err;
+        } else if (strcmp(cnf->name, "flags") == 0) {
+            if (strcmp(cnf->value, "nomask") == 0)
+                tbl_flags = STABLE_NO_MASK;
+            else if (strcmp(cnf->value, "none") == 0)
+                tbl_flags = STABLE_FLAGS_CLEAR;
+            else
+                goto err;
+        } else
+            goto err;
+    }
+    rv = 1;
+ err:
+    if (rv == 0) {
+        ASN1err(ASN1_F_DO_TCREATE, ASN1_R_INVALID_STRING_TABLE_VALUE);
+        if (cnf)
+            ERR_add_error_data(4, "field=", cnf->name,
+                               ", value=", cnf->value);
+        else
+            ERR_add_error_data(4, "name=", name, ", value=", value);
+    } else {
+        rv = ASN1_STRING_TABLE_add(nid, tbl_min, tbl_max,
+                                   tbl_mask, tbl_flags);
+        if (!rv)
+            ASN1err(ASN1_F_DO_TCREATE, ERR_R_MALLOC_FAILURE);
+    }
+    sk_CONF_VALUE_pop_free(lst, X509V3_conf_free);
+    return rv;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn_pack.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn_pack.c
new file mode 100644
index 0000000..63bc306
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/asn_pack.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright 1999-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+
+/* ASN1 packing and unpacking functions */
+
+ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
+{
+    ASN1_STRING *octmp;
+
+     if (oct == NULL || *oct == NULL) {
+        if ((octmp = ASN1_STRING_new()) == NULL) {
+            ASN1err(ASN1_F_ASN1_ITEM_PACK, ERR_R_MALLOC_FAILURE);
+            return NULL;
+        }
+    } else {
+        octmp = *oct;
+    }
+
+    OPENSSL_free(octmp->data);
+    octmp->data = NULL;
+
+    if ((octmp->length = ASN1_item_i2d(obj, &octmp->data, it)) == 0) {
+        ASN1err(ASN1_F_ASN1_ITEM_PACK, ASN1_R_ENCODE_ERROR);
+        goto err;
+    }
+    if (octmp->data == NULL) {
+        ASN1err(ASN1_F_ASN1_ITEM_PACK, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (oct != NULL && *oct == NULL)
+        *oct = octmp;
+
+    return octmp;
+ err:
+    if (oct == NULL || *oct == NULL)
+        ASN1_STRING_free(octmp);
+    return NULL;
+}
+
+/* Extract an ASN1 object from an ASN1_STRING */
+
+void *ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it)
+{
+    const unsigned char *p;
+    void *ret;
+
+    p = oct->data;
+    if ((ret = ASN1_item_d2i(NULL, &p, oct->length, it)) == NULL)
+        ASN1err(ASN1_F_ASN1_ITEM_UNPACK, ASN1_R_DECODE_ERROR);
+    return ret;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/bio_asn1.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/bio_asn1.c
new file mode 100644
index 0000000..17b0d1a
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/bio_asn1.c
@@ -0,0 +1,449 @@
+/*
+ * Copyright 2006-2021 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * Experimental ASN1 BIO. When written through the data is converted to an
+ * ASN1 string type: default is OCTET STRING. Additional functions can be
+ * provided to add prefix and suffix data.
+ */
+
+#include <string.h>
+#include "internal/bio.h"
+#include <openssl/asn1.h>
+#include "internal/cryptlib.h"
+
+/* Must be large enough for biggest tag+length */
+#define DEFAULT_ASN1_BUF_SIZE 20
+
+typedef enum {
+    ASN1_STATE_START,
+    ASN1_STATE_PRE_COPY,
+    ASN1_STATE_HEADER,
+    ASN1_STATE_HEADER_COPY,
+    ASN1_STATE_DATA_COPY,
+    ASN1_STATE_POST_COPY,
+    ASN1_STATE_DONE
+} asn1_bio_state_t;
+
+typedef struct BIO_ASN1_EX_FUNCS_st {
+    asn1_ps_func *ex_func;
+    asn1_ps_func *ex_free_func;
+} BIO_ASN1_EX_FUNCS;
+
+typedef struct BIO_ASN1_BUF_CTX_t {
+    /* Internal state */
+    asn1_bio_state_t state;
+    /* Internal buffer */
+    unsigned char *buf;
+    /* Size of buffer */
+    int bufsize;
+    /* Current position in buffer */
+    int bufpos;
+    /* Current buffer length */
+    int buflen;
+    /* Amount of data to copy */
+    int copylen;
+    /* Class and tag to use */
+    int asn1_class, asn1_tag;
+    asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
+    /* Extra buffer for prefix and suffix data */
+    unsigned char *ex_buf;
+    int ex_len;
+    int ex_pos;
+    void *ex_arg;
+} BIO_ASN1_BUF_CTX;
+
+static int asn1_bio_write(BIO *h, const char *buf, int num);
+static int asn1_bio_read(BIO *h, char *buf, int size);
+static int asn1_bio_puts(BIO *h, const char *str);
+static int asn1_bio_gets(BIO *h, char *str, int size);
+static long asn1_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int asn1_bio_new(BIO *h);
+static int asn1_bio_free(BIO *data);
+static long asn1_bio_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp);
+
+static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size);
+static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+                             asn1_ps_func *cleanup, asn1_bio_state_t next);
+static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+                             asn1_ps_func *setup,
+                             asn1_bio_state_t ex_state,
+                             asn1_bio_state_t other_state);
+
+static const BIO_METHOD methods_asn1 = {
+    BIO_TYPE_ASN1,
+    "asn1",
+    /* TODO: Convert to new style write function */
+    bwrite_conv,
+    asn1_bio_write,
+    /* TODO: Convert to new style read function */
+    bread_conv,
+    asn1_bio_read,
+    asn1_bio_puts,
+    asn1_bio_gets,
+    asn1_bio_ctrl,
+    asn1_bio_new,
+    asn1_bio_free,
+    asn1_bio_callback_ctrl,
+};
+
+const BIO_METHOD *BIO_f_asn1(void)
+{
+    return &methods_asn1;
+}
+
+static int asn1_bio_new(BIO *b)
+{
+    BIO_ASN1_BUF_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+    if (ctx == NULL)
+        return 0;
+    if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) {
+        OPENSSL_free(ctx);
+        return 0;
+    }
+    BIO_set_data(b, ctx);
+    BIO_set_init(b, 1);
+
+    return 1;
+}
+
+static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size)
+{
+    if ((ctx->buf = OPENSSL_malloc(size)) == NULL) {
+        ASN1err(ASN1_F_ASN1_BIO_INIT, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    ctx->bufsize = size;
+    ctx->asn1_class = V_ASN1_UNIVERSAL;
+    ctx->asn1_tag = V_ASN1_OCTET_STRING;
+    ctx->state = ASN1_STATE_START;
+    return 1;
+}
+
+static int asn1_bio_free(BIO *b)
+{
+    BIO_ASN1_BUF_CTX *ctx;
+
+    if (b == NULL)
+        return 0;
+
+    ctx = BIO_get_data(b);
+    if (ctx == NULL)
+        return 0;
+
+    if (ctx->prefix_free != NULL)
+        ctx->prefix_free(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg);
+    if (ctx->suffix_free != NULL)
+        ctx->suffix_free(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg);
+
+    OPENSSL_free(ctx->buf);
+    OPENSSL_free(ctx);
+    BIO_set_data(b, NULL);
+    BIO_set_init(b, 0);
+
+    return 1;
+}
+
+static int asn1_bio_write(BIO *b, const char *in, int inl)
+{
+    BIO_ASN1_BUF_CTX *ctx;
+    int wrmax, wrlen, ret;
+    unsigned char *p;
+    BIO *next;
+
+    ctx = BIO_get_data(b);
+    next = BIO_next(b);
+    if (in == NULL || inl < 0 || ctx == NULL || next == NULL)
+        return 0;
+
+    wrlen = 0;
+    ret = -1;
+
+    for (;;) {
+        switch (ctx->state) {
+            /* Setup prefix data, call it */
+        case ASN1_STATE_START:
+            if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
+                                   ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
+                return -1;
+            break;
+
+            /* Copy any pre data first */
+        case ASN1_STATE_PRE_COPY:
+
+            ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
+                                    ASN1_STATE_HEADER);
+
+            if (ret <= 0)
+                goto done;
+
+            break;
+
+        case ASN1_STATE_HEADER:
+            ctx->buflen = ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
+            if (!ossl_assert(ctx->buflen <= ctx->bufsize))
+                return -1;
+            p = ctx->buf;
+            ASN1_put_object(&p, 0, inl, ctx->asn1_tag, ctx->asn1_class);
+            ctx->copylen = inl;
+            ctx->state = ASN1_STATE_HEADER_COPY;
+
+            break;
+
+        case ASN1_STATE_HEADER_COPY:
+            ret = BIO_write(next, ctx->buf + ctx->bufpos, ctx->buflen);
+            if (ret <= 0)
+                goto done;
+
+            ctx->buflen -= ret;
+            if (ctx->buflen)
+                ctx->bufpos += ret;
+            else {
+                ctx->bufpos = 0;
+                ctx->state = ASN1_STATE_DATA_COPY;
+            }
+
+            break;
+
+        case ASN1_STATE_DATA_COPY:
+
+            if (inl > ctx->copylen)
+                wrmax = ctx->copylen;
+            else
+                wrmax = inl;
+            ret = BIO_write(next, in, wrmax);
+            if (ret <= 0)
+                goto done;
+            wrlen += ret;
+            ctx->copylen -= ret;
+            in += ret;
+            inl -= ret;
+
+            if (ctx->copylen == 0)
+                ctx->state = ASN1_STATE_HEADER;
+
+            if (inl == 0)
+                goto done;
+
+            break;
+
+        case ASN1_STATE_POST_COPY:
+        case ASN1_STATE_DONE:
+            BIO_clear_retry_flags(b);
+            return 0;
+
+        }
+
+    }
+
+ done:
+    BIO_clear_retry_flags(b);
+    BIO_copy_next_retry(b);
+
+    return (wrlen > 0) ? wrlen : ret;
+
+}
+
+static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+                             asn1_ps_func *cleanup, asn1_bio_state_t next)
+{
+    int ret;
+
+    if (ctx->ex_len <= 0)
+        return 1;
+    for (;;) {
+        ret = BIO_write(BIO_next(b), ctx->ex_buf + ctx->ex_pos, ctx->ex_len);
+        if (ret <= 0)
+            break;
+        ctx->ex_len -= ret;
+        if (ctx->ex_len > 0)
+            ctx->ex_pos += ret;
+        else {
+            if (cleanup)
+                cleanup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg);
+            ctx->state = next;
+            ctx->ex_pos = 0;
+            break;
+        }
+    }
+    return ret;
+}
+
+static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+                             asn1_ps_func *setup,
+                             asn1_bio_state_t ex_state,
+                             asn1_bio_state_t other_state)
+{
+    if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg)) {
+        BIO_clear_retry_flags(b);
+        return 0;
+    }
+    if (ctx->ex_len > 0)
+        ctx->state = ex_state;
+    else
+        ctx->state = other_state;
+    return 1;
+}
+
+static int asn1_bio_read(BIO *b, char *in, int inl)
+{
+    BIO *next = BIO_next(b);
+    if (next == NULL)
+        return 0;
+    return BIO_read(next, in, inl);
+}
+
+static int asn1_bio_puts(BIO *b, const char *str)
+{
+    return asn1_bio_write(b, str, strlen(str));
+}
+
+static int asn1_bio_gets(BIO *b, char *str, int size)
+{
+    BIO *next = BIO_next(b);
+    if (next == NULL)
+        return 0;
+    return BIO_gets(next, str, size);
+}
+
+static long asn1_bio_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
+{
+    BIO *next = BIO_next(b);
+    if (next == NULL)
+        return 0;
+    return BIO_callback_ctrl(next, cmd, fp);
+}
+
+static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2)
+{
+    BIO_ASN1_BUF_CTX *ctx;
+    BIO_ASN1_EX_FUNCS *ex_func;
+    long ret = 1;
+    BIO *next;
+
+    ctx = BIO_get_data(b);
+    if (ctx == NULL)
+        return 0;
+    next = BIO_next(b);
+    switch (cmd) {
+
+    case BIO_C_SET_PREFIX:
+        ex_func = arg2;
+        ctx->prefix = ex_func->ex_func;
+        ctx->prefix_free = ex_func->ex_free_func;
+        break;
+
+    case BIO_C_GET_PREFIX:
+        ex_func = arg2;
+        ex_func->ex_func = ctx->prefix;
+        ex_func->ex_free_func = ctx->prefix_free;
+        break;
+
+    case BIO_C_SET_SUFFIX:
+        ex_func = arg2;
+        ctx->suffix = ex_func->ex_func;
+        ctx->suffix_free = ex_func->ex_free_func;
+        break;
+
+    case BIO_C_GET_SUFFIX:
+        ex_func = arg2;
+        ex_func->ex_func = ctx->suffix;
+        ex_func->ex_free_func = ctx->suffix_free;
+        break;
+
+    case BIO_C_SET_EX_ARG:
+        ctx->ex_arg = arg2;
+        break;
+
+    case BIO_C_GET_EX_ARG:
+        *(void **)arg2 = ctx->ex_arg;
+        break;
+
+    case BIO_CTRL_FLUSH:
+        if (next == NULL)
+            return 0;
+
+        /* Call post function if possible */
+        if (ctx->state == ASN1_STATE_HEADER) {
+            if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
+                                   ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
+                return 0;
+        }
+
+        if (ctx->state == ASN1_STATE_POST_COPY) {
+            ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
+                                    ASN1_STATE_DONE);
+            if (ret <= 0)
+                return ret;
+        }
+
+        if (ctx->state == ASN1_STATE_DONE)
+            return BIO_ctrl(next, cmd, arg1, arg2);
+        else {
+            BIO_clear_retry_flags(b);
+            return 0;
+        }
+
+    default:
+        if (next == NULL)
+            return 0;
+        return BIO_ctrl(next, cmd, arg1, arg2);
+
+    }
+
+    return ret;
+}
+
+static int asn1_bio_set_ex(BIO *b, int cmd,
+                           asn1_ps_func *ex_func, asn1_ps_func *ex_free_func)
+{
+    BIO_ASN1_EX_FUNCS extmp;
+    extmp.ex_func = ex_func;
+    extmp.ex_free_func = ex_free_func;
+    return BIO_ctrl(b, cmd, 0, &extmp);
+}
+
+static int asn1_bio_get_ex(BIO *b, int cmd,
+                           asn1_ps_func **ex_func,
+                           asn1_ps_func **ex_free_func)
+{
+    BIO_ASN1_EX_FUNCS extmp;
+    int ret;
+    ret = BIO_ctrl(b, cmd, 0, &extmp);
+    if (ret > 0) {
+        *ex_func = extmp.ex_func;
+        *ex_free_func = extmp.ex_free_func;
+    }
+    return ret;
+}
+
+int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix,
+                        asn1_ps_func *prefix_free)
+{
+    return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
+}
+
+int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix,
+                        asn1_ps_func **pprefix_free)
+{
+    return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
+}
+
+int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix,
+                        asn1_ps_func *suffix_free)
+{
+    return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
+}
+
+int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix,
+                        asn1_ps_func **psuffix_free)
+{
+    return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/bio_ndef.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/bio_ndef.c
new file mode 100644
index 0000000..c8a776b
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/bio_ndef.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2008-2023 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+
+#include <stdio.h>
+
+/* Experimental NDEF ASN1 BIO support routines */
+
+/*
+ * The usage is quite simple, initialize an ASN1 structure, get a BIO from it
+ * then any data written through the BIO will end up translated to
+ * appropriate format on the fly. The data is streamed out and does *not*
+ * need to be all held in memory at once. When the BIO is flushed the output
+ * is finalized and any signatures etc written out. The BIO is a 'proper'
+ * BIO and can handle non blocking I/O correctly. The usage is simple. The
+ * implementation is *not*...
+ */
+
+/* BIO support data stored in the ASN1 BIO ex_arg */
+
+typedef struct ndef_aux_st {
+    /* ASN1 structure this BIO refers to */
+    ASN1_VALUE *val;
+    const ASN1_ITEM *it;
+    /* Top of the BIO chain */
+    BIO *ndef_bio;
+    /* Output BIO */
+    BIO *out;
+    /* Boundary where content is inserted */
+    unsigned char **boundary;
+    /* DER buffer start */
+    unsigned char *derbuf;
+} NDEF_SUPPORT;
+
+static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen,
+                            void *parg);
+static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
+                            void *parg);
+
+/*
+ * On success, the returned BIO owns the input BIO as part of its BIO chain.
+ * On failure, NULL is returned and the input BIO is owned by the caller.
+ *
+ * Unfortunately cannot constify this due to CMS_stream() and PKCS7_stream()
+ */
+BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
+{
+    NDEF_SUPPORT *ndef_aux = NULL;
+    BIO *asn_bio = NULL;
+    const ASN1_AUX *aux = it->funcs;
+    ASN1_STREAM_ARG sarg;
+    BIO *pop_bio = NULL;
+
+    if (!aux || !aux->asn1_cb) {
+        ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
+        return NULL;
+    }
+    ndef_aux = OPENSSL_zalloc(sizeof(*ndef_aux));
+    asn_bio = BIO_new(BIO_f_asn1());
+    if (ndef_aux == NULL || asn_bio == NULL)
+        goto err;
+
+    /* ASN1 bio needs to be next to output BIO */
+    out = BIO_push(asn_bio, out);
+    if (out == NULL)
+        goto err;
+    pop_bio = asn_bio;
+
+    if (BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free) <= 0
+            || BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free) <= 0
+            || BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux) <= 0)
+        goto err;
+
+    /*
+     * Now let the callback prepend any digest, cipher, etc., that the BIO's
+     * ASN1 structure needs.
+     */
+
+    sarg.out = out;
+    sarg.ndef_bio = NULL;
+    sarg.boundary = NULL;
+
+    /*
+     * The asn1_cb(), must not have mutated asn_bio on error, leaving it in the
+     * middle of some partially built, but not returned BIO chain.
+     */
+    if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0) {
+        /*
+         * ndef_aux is now owned by asn_bio so we must not free it in the err
+         * clean up block
+         */
+        ndef_aux = NULL;
+        goto err;
+    }
+
+    /*
+     * We must not fail now because the callback has prepended additional
+     * BIOs to the chain
+     */
+
+    ndef_aux->val = val;
+    ndef_aux->it = it;
+    ndef_aux->ndef_bio = sarg.ndef_bio;
+    ndef_aux->boundary = sarg.boundary;
+    ndef_aux->out = out;
+
+    return sarg.ndef_bio;
+
+ err:
+    /* BIO_pop() is NULL safe */
+    (void)BIO_pop(pop_bio);
+    BIO_free(asn_bio);
+    OPENSSL_free(ndef_aux);
+    return NULL;
+}
+
+static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+{
+    NDEF_SUPPORT *ndef_aux;
+    unsigned char *p;
+    int derlen;
+
+    if (!parg)
+        return 0;
+
+    ndef_aux = *(NDEF_SUPPORT **)parg;
+
+    derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
+    if (derlen < 0)
+        return 0;
+    if ((p = OPENSSL_malloc(derlen)) == NULL) {
+        ASN1err(ASN1_F_NDEF_PREFIX, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    ndef_aux->derbuf = p;
+    *pbuf = p;
+    derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
+
+    if (!*ndef_aux->boundary)
+        return 0;
+
+    *plen = *ndef_aux->boundary - *pbuf;
+
+    return 1;
+}
+
+static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen,
+                            void *parg)
+{
+    NDEF_SUPPORT *ndef_aux;
+
+    if (!parg)
+        return 0;
+
+    ndef_aux = *(NDEF_SUPPORT **)parg;
+
+    if (ndef_aux == NULL)
+        return 0;
+
+    OPENSSL_free(ndef_aux->derbuf);
+
+    ndef_aux->derbuf = NULL;
+    *pbuf = NULL;
+    *plen = 0;
+    return 1;
+}
+
+static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
+                            void *parg)
+{
+    NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
+    if (!ndef_prefix_free(b, pbuf, plen, parg))
+        return 0;
+    OPENSSL_free(*pndef_aux);
+    *pndef_aux = NULL;
+    return 1;
+}
+
+static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+{
+    NDEF_SUPPORT *ndef_aux;
+    unsigned char *p;
+    int derlen;
+    const ASN1_AUX *aux;
+    ASN1_STREAM_ARG sarg;
+
+    if (!parg)
+        return 0;
+
+    ndef_aux = *(NDEF_SUPPORT **)parg;
+
+    aux = ndef_aux->it->funcs;
+
+    /* Finalize structures */
+    sarg.ndef_bio = ndef_aux->ndef_bio;
+    sarg.out = ndef_aux->out;
+    sarg.boundary = ndef_aux->boundary;
+    if (aux->asn1_cb(ASN1_OP_STREAM_POST,
+                     &ndef_aux->val, ndef_aux->it, &sarg) <= 0)
+        return 0;
+
+    derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
+    if ((p = OPENSSL_malloc(derlen)) == NULL) {
+        ASN1err(ASN1_F_NDEF_SUFFIX, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    ndef_aux->derbuf = p;
+    *pbuf = p;
+    derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
+
+    if (!*ndef_aux->boundary)
+        return 0;
+    *pbuf = *ndef_aux->boundary;
+    *plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
+
+    return 1;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/build.info b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/build.info
new file mode 100644
index 0000000..d3e92c8
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/build.info
@@ -0,0 +1,16 @@
+LIBS=../../libcrypto
+SOURCE[../../libcrypto]=\
+        a_object.c a_bitstr.c a_utctm.c a_gentm.c a_time.c a_int.c a_octet.c \
+        a_print.c a_type.c a_dup.c a_d2i_fp.c a_i2d_fp.c \
+        a_utf8.c a_sign.c a_digest.c a_verify.c a_mbstr.c a_strex.c \
+        x_algor.c x_val.c x_sig.c x_bignum.c \
+        x_long.c x_int64.c x_info.c x_spki.c nsseq.c \
+        d2i_pu.c d2i_pr.c i2d_pu.c i2d_pr.c\
+        t_pkey.c t_spki.c t_bitst.c \
+        tasn_new.c tasn_fre.c tasn_enc.c tasn_dec.c tasn_utl.c tasn_typ.c \
+        tasn_prn.c tasn_scn.c ameth_lib.c \
+        f_int.c f_string.c n_pkey.c \
+        x_pkey.c bio_asn1.c bio_ndef.c asn_mime.c \
+        asn1_gen.c asn1_par.c asn1_lib.c asn1_err.c a_strnid.c \
+        evp_asn1.c asn_pack.c p5_pbe.c p5_pbev2.c p5_scrypt.c p8_pkey.c \
+        asn_moid.c asn_mstbl.c asn1_item_list.c
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/charmap.h b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/charmap.h
new file mode 100644
index 0000000..5630291
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/charmap.h
@@ -0,0 +1,34 @@
+/*
+ * WARNING: do not edit!
+ * Generated by crypto/asn1/charmap.pl
+ *
+ * Copyright 2000-2022 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#define CHARTYPE_HOST_ANY 4096
+#define CHARTYPE_HOST_DOT 8192
+#define CHARTYPE_HOST_HYPHEN 16384
+#define CHARTYPE_HOST_WILD 32768
+
+/*
+ * Mask of various character properties
+ */
+
+static const unsigned short char_type[] = {
+    1026,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+       2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+       2,    2,    2,    2,    2,    2,    2,    2,  120,    0,    1,   40,
+       0,    0,    0,   16, 1040, 1040, 33792,   25,   25, 16400, 8208,   16,
+    4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112,   16,    9,
+       9,   16,    9,   16,    0, 4112, 4112, 4112, 4112, 4112, 4112, 4112,
+    4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112,
+    4112, 4112, 4112, 4112, 4112, 4112, 4112,    0, 1025,    0,    0,    0,
+       0, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112,
+    4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112,
+    4112, 4112, 4112,    0,    0,    0,    0,    2
+};
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/charmap.pl b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/charmap.pl
new file mode 100644
index 0000000..52fa5a7
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/charmap.pl
@@ -0,0 +1,122 @@
+#! /usr/bin/env perl
+# Copyright 2000-2022 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
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+use strict;
+use FindBin;
+use lib "$FindBin::Bin/../../util/perl";
+use OpenSSL::copyright;
+
+my ($i, @arr);
+
+# Set up an array with the type of ASCII characters
+# Each set bit represents a character property.
+
+# RFC2253 character properties
+my $RFC2253_ESC = 1;	# Character escaped with \
+my $ESC_CTRL	= 2;	# Escaped control character
+# These are used with RFC1779 quoting using "
+my $NOESC_QUOTE	= 8;	# Not escaped if quoted
+my $PSTRING_CHAR = 0x10;	# Valid PrintableString character
+my $RFC2253_FIRST_ESC = 0x20; # Escaped with \ if first character
+my $RFC2253_LAST_ESC = 0x40;  # Escaped with \ if last character
+my $RFC2254_ESC = 0x400;	# Character escaped \XX
+my $HOST_ANY = 0x1000;      # Valid hostname character anywhere in label
+my $HOST_DOT = 0x2000;  # Dot: hostname label separator
+my $HOST_HYPHEN = 0x4000; # Hyphen: not valid at start or end.
+my $HOST_WILD = 0x8000; # Wildcard character
+
+for($i = 0; $i < 128; $i++) {
+	# Set the RFC2253 escape characters (control)
+	$arr[$i] = 0;
+	if(($i < 32) || ($i > 126)) {
+		$arr[$i] |= $ESC_CTRL;
+	}
+
+	# Some PrintableString characters
+	if(		   ( ( $i >= ord("a")) && ( $i <= ord("z")) )
+			|| (  ( $i >= ord("A")) && ( $i <= ord("Z")) )
+			|| (  ( $i >= ord("0")) && ( $i <= ord("9")) )  ) {
+		$arr[$i] |= $PSTRING_CHAR | $HOST_ANY;
+	}
+}
+
+# Now setup the rest
+
+# Remaining RFC2253 escaped characters
+
+$arr[ord(" ")] |= $NOESC_QUOTE | $RFC2253_FIRST_ESC | $RFC2253_LAST_ESC;
+$arr[ord("#")] |= $NOESC_QUOTE | $RFC2253_FIRST_ESC;
+
+$arr[ord(",")] |= $NOESC_QUOTE | $RFC2253_ESC;
+$arr[ord("+")] |= $NOESC_QUOTE | $RFC2253_ESC;
+$arr[ord("\"")] |= $RFC2253_ESC;
+$arr[ord("\\")] |= $RFC2253_ESC;
+$arr[ord("<")] |= $NOESC_QUOTE | $RFC2253_ESC;
+$arr[ord(">")] |= $NOESC_QUOTE | $RFC2253_ESC;
+$arr[ord(";")] |= $NOESC_QUOTE | $RFC2253_ESC;
+
+# Remaining RFC2254 characters
+
+$arr[0] |= $RFC2254_ESC;
+$arr[ord("(")] |= $RFC2254_ESC;
+$arr[ord(")")] |= $RFC2254_ESC;
+$arr[ord("*")] |= $RFC2254_ESC | $HOST_WILD;
+$arr[ord("\\")] |= $RFC2254_ESC;
+
+# Remaining PrintableString characters
+
+$arr[ord(" ")] |= $PSTRING_CHAR;
+$arr[ord("'")] |= $PSTRING_CHAR;
+$arr[ord("(")] |= $PSTRING_CHAR;
+$arr[ord(")")] |= $PSTRING_CHAR;
+$arr[ord("+")] |= $PSTRING_CHAR;
+$arr[ord(",")] |= $PSTRING_CHAR;
+$arr[ord("-")] |= $PSTRING_CHAR | $HOST_HYPHEN;
+$arr[ord(".")] |= $PSTRING_CHAR | $HOST_DOT;
+$arr[ord("/")] |= $PSTRING_CHAR;
+$arr[ord(":")] |= $PSTRING_CHAR;
+$arr[ord("=")] |= $PSTRING_CHAR;
+$arr[ord("?")] |= $PSTRING_CHAR;
+
+# Now generate the C code
+
+# Year the file was generated.
+my $YEAR = OpenSSL::copyright::year_of($0);
+print <<EOF;
+/*
+ * WARNING: do not edit!
+ * Generated by crypto/asn1/charmap.pl
+ *
+ * Copyright 2000-$YEAR 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#define CHARTYPE_HOST_ANY $HOST_ANY
+#define CHARTYPE_HOST_DOT $HOST_DOT
+#define CHARTYPE_HOST_HYPHEN $HOST_HYPHEN
+#define CHARTYPE_HOST_WILD $HOST_WILD
+
+/*
+ * Mask of various character properties
+ */
+
+static const unsigned short char_type[] = {
+EOF
+
+print "   ";
+for($i = 0; $i < 128; $i++) {
+	print("\n   ") if($i && (($i % 12) == 0));
+	printf(" %4d", $arr[$i]);
+	print(",") if ($i != 127);
+}
+print("\n};\n");
+
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/d2i_pr.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/d2i_pr.c
new file mode 100644
index 0000000..2094963
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/d2i_pr.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright 1995-2021 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/engine.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include "crypto/asn1.h"
+#include "crypto/evp.h"
+
+EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
+                         long length)
+{
+    EVP_PKEY *ret;
+    const unsigned char *p = *pp;
+
+    if ((a == NULL) || (*a == NULL)) {
+        if ((ret = EVP_PKEY_new()) == NULL) {
+            ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_EVP_LIB);
+            return NULL;
+        }
+    } else {
+        ret = *a;
+#ifndef OPENSSL_NO_ENGINE
+        ENGINE_finish(ret->engine);
+        ret->engine = NULL;
+#endif
+    }
+
+    if (!EVP_PKEY_set_type(ret, type)) {
+        ASN1err(ASN1_F_D2I_PRIVATEKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
+        goto err;
+    }
+
+    if (!ret->ameth->old_priv_decode ||
+        !ret->ameth->old_priv_decode(ret, &p, length)) {
+        if (ret->ameth->priv_decode) {
+            EVP_PKEY *tmp;
+            PKCS8_PRIV_KEY_INFO *p8 = NULL;
+            p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
+            if (!p8)
+                goto err;
+            tmp = EVP_PKCS82PKEY(p8);
+            PKCS8_PRIV_KEY_INFO_free(p8);
+            if (tmp == NULL)
+                goto err;
+            EVP_PKEY_free(ret);
+            ret = tmp;
+            if (EVP_PKEY_type(type) != EVP_PKEY_base_id(ret))
+                goto err;
+        } else {
+            ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB);
+            goto err;
+        }
+    }
+    *pp = p;
+    if (a != NULL)
+        (*a) = ret;
+    return ret;
+ err:
+    if (a == NULL || *a != ret)
+        EVP_PKEY_free(ret);
+    return NULL;
+}
+
+/*
+ * This works like d2i_PrivateKey() except it automatically works out the
+ * type
+ */
+
+static EVP_PKEY *key_as_pkcs8(const unsigned char **pp, long length, int *carry_on)
+{
+    const unsigned char *p = *pp;
+    PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
+    EVP_PKEY *ret;
+
+    if (p8 == NULL)
+        return NULL;
+
+    ret = EVP_PKCS82PKEY(p8);
+    if (ret == NULL)
+        *carry_on = 0;
+
+    PKCS8_PRIV_KEY_INFO_free(p8);
+
+    if (ret != NULL)
+        *pp = p;
+
+    return ret;
+}
+
+EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
+                             long length)
+{
+    STACK_OF(ASN1_TYPE) *inkey;
+    const unsigned char *p;
+    int keytype;
+    EVP_PKEY *ret = NULL;
+    int carry_on = 1;
+
+    ERR_set_mark();
+    ret = key_as_pkcs8(pp, length, &carry_on);
+    if (ret != NULL) {
+        ERR_clear_last_mark();
+        if (a != NULL)
+            *a = ret;
+        return ret;
+    }
+
+    if (carry_on == 0) {
+        ERR_clear_last_mark();
+        ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY,
+                ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+        return NULL;
+    }
+    p = *pp;
+
+    /*
+     * Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): by
+     * analyzing it we can determine the passed structure: this assumes the
+     * input is surrounded by an ASN1 SEQUENCE.
+     */
+    inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length);
+    p = *pp;
+    /*
+     * Since we only need to discern "traditional format" RSA and DSA keys we
+     * can just count the elements.
+     */
+    if (sk_ASN1_TYPE_num(inkey) == 6)
+        keytype = EVP_PKEY_DSA;
+    else if (sk_ASN1_TYPE_num(inkey) == 4)
+        keytype = EVP_PKEY_EC;
+    else
+        keytype = EVP_PKEY_RSA;
+    sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
+
+    ret = d2i_PrivateKey(keytype, a, pp, length);
+    if (ret != NULL)
+        ERR_pop_to_mark();
+    else
+        ERR_clear_last_mark();
+
+    return ret;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/d2i_pu.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/d2i_pu.c
new file mode 100644
index 0000000..8327ac1
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/d2i_pu.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright 1995-2019 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/asn1.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/ec.h>
+
+#include "crypto/evp.h"
+
+EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp,
+                        long length)
+{
+    EVP_PKEY *ret;
+
+    if ((a == NULL) || (*a == NULL)) {
+        if ((ret = EVP_PKEY_new()) == NULL) {
+            ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB);
+            return NULL;
+        }
+    } else
+        ret = *a;
+
+    if (type != EVP_PKEY_id(ret) && !EVP_PKEY_set_type(ret, type)) {
+        ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB);
+        goto err;
+    }
+
+    switch (EVP_PKEY_id(ret)) {
+#ifndef OPENSSL_NO_RSA
+    case EVP_PKEY_RSA:
+        if ((ret->pkey.rsa = d2i_RSAPublicKey(NULL, pp, length)) == NULL) {
+            ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
+            goto err;
+        }
+        break;
+#endif
+#ifndef OPENSSL_NO_DSA
+    case EVP_PKEY_DSA:
+        /* TMP UGLY CAST */
+        if (!d2i_DSAPublicKey(&ret->pkey.dsa, pp, length)) {
+            ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
+            goto err;
+        }
+        break;
+#endif
+#ifndef OPENSSL_NO_EC
+    case EVP_PKEY_EC:
+        if (!o2i_ECPublicKey(&ret->pkey.ec, pp, length)) {
+            ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
+            goto err;
+        }
+        break;
+#endif
+    default:
+        ASN1err(ASN1_F_D2I_PUBLICKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
+        goto err;
+    }
+    if (a != NULL)
+        (*a) = ret;
+    return ret;
+ err:
+    if (a == NULL || *a != ret)
+        EVP_PKEY_free(ret);
+    return NULL;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/evp_asn1.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/evp_asn1.c
new file mode 100644
index 0000000..895085a
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/evp_asn1.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright 1995-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+
+int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len)
+{
+    ASN1_STRING *os;
+
+    if ((os = ASN1_OCTET_STRING_new()) == NULL)
+        return 0;
+    if (!ASN1_OCTET_STRING_set(os, data, len)) {
+        ASN1_OCTET_STRING_free(os);
+        return 0;
+    }
+    ASN1_TYPE_set(a, V_ASN1_OCTET_STRING, os);
+    return 1;
+}
+
+/* int max_len:  for returned value    */
+int ASN1_TYPE_get_octetstring(const ASN1_TYPE *a, unsigned char *data, int max_len)
+{
+    int ret, num;
+    const unsigned char *p;
+
+    if ((a->type != V_ASN1_OCTET_STRING) || (a->value.octet_string == NULL)) {
+        ASN1err(ASN1_F_ASN1_TYPE_GET_OCTETSTRING, ASN1_R_DATA_IS_WRONG);
+        return -1;
+    }
+    p = ASN1_STRING_get0_data(a->value.octet_string);
+    ret = ASN1_STRING_length(a->value.octet_string);
+    if (ret < max_len)
+        num = ret;
+    else
+        num = max_len;
+    memcpy(data, p, num);
+    return ret;
+}
+
+typedef struct {
+    int32_t num;
+    ASN1_OCTET_STRING *oct;
+} asn1_int_oct;
+
+ASN1_SEQUENCE(asn1_int_oct) = {
+        ASN1_EMBED(asn1_int_oct, num, INT32),
+        ASN1_SIMPLE(asn1_int_oct, oct, ASN1_OCTET_STRING)
+} static_ASN1_SEQUENCE_END(asn1_int_oct)
+
+DECLARE_ASN1_ITEM(asn1_int_oct)
+
+int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, unsigned char *data,
+                                  int len)
+{
+    asn1_int_oct atmp;
+    ASN1_OCTET_STRING oct;
+
+    atmp.num = num;
+    atmp.oct = &oct;
+    oct.data = data;
+    oct.type = V_ASN1_OCTET_STRING;
+    oct.length = len;
+    oct.flags = 0;
+
+    if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(asn1_int_oct), &atmp, &a))
+        return 1;
+    return 0;
+}
+
+/*
+ * we return the actual length...
+ */
+/* int max_len:  for returned value    */
+int ASN1_TYPE_get_int_octetstring(const ASN1_TYPE *a, long *num,
+                                  unsigned char *data, int max_len)
+{
+    asn1_int_oct *atmp = NULL;
+    int ret = -1, n;
+
+    if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL)) {
+        goto err;
+    }
+
+    atmp = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(asn1_int_oct), a);
+
+    if (atmp == NULL)
+        goto err;
+
+    if (num != NULL)
+        *num = atmp->num;
+
+    ret = ASN1_STRING_length(atmp->oct);
+    if (max_len > ret)
+        n = ret;
+    else
+        n = max_len;
+
+    if (data != NULL)
+        memcpy(data, ASN1_STRING_get0_data(atmp->oct), n);
+    if (ret == -1) {
+ err:
+        ASN1err(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING, ASN1_R_DATA_IS_WRONG);
+    }
+    M_ASN1_free_of(atmp, asn1_int_oct);
+    return ret;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/f_int.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/f_int.c
new file mode 100644
index 0000000..3a18381
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/f_int.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright 1995-2017 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "crypto/ctype.h"
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1.h>
+
+int i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a)
+{
+    int i, n = 0;
+    static const char *h = "0123456789ABCDEF";
+    char buf[2];
+
+    if (a == NULL)
+        return 0;
+
+    if (a->type & V_ASN1_NEG) {
+        if (BIO_write(bp, "-", 1) != 1)
+            goto err;
+        n = 1;
+    }
+
+    if (a->length == 0) {
+        if (BIO_write(bp, "00", 2) != 2)
+            goto err;
+        n += 2;
+    } else {
+        for (i = 0; i < a->length; i++) {
+            if ((i != 0) && (i % 35 == 0)) {
+                if (BIO_write(bp, "\\\n", 2) != 2)
+                    goto err;
+                n += 2;
+            }
+            buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
+            buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
+            if (BIO_write(bp, buf, 2) != 2)
+                goto err;
+            n += 2;
+        }
+    }
+    return n;
+ err:
+    return -1;
+}
+
+int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
+{
+    int i, j, k, m, n, again, bufsize;
+    unsigned char *s = NULL, *sp;
+    unsigned char *bufp;
+    int num = 0, slen = 0, first = 1;
+
+    bs->type = V_ASN1_INTEGER;
+
+    bufsize = BIO_gets(bp, buf, size);
+    for (;;) {
+        if (bufsize < 1)
+            goto err;
+        i = bufsize;
+        if (buf[i - 1] == '\n')
+            buf[--i] = '\0';
+        if (i == 0)
+            goto err;
+        if (buf[i - 1] == '\r')
+            buf[--i] = '\0';
+        if (i == 0)
+            goto err;
+        again = (buf[i - 1] == '\\');
+
+        for (j = 0; j < i; j++) {
+            if (!ossl_isxdigit(buf[j]))
+            {
+                i = j;
+                break;
+            }
+        }
+        buf[i] = '\0';
+        /*
+         * We have now cleared all the crap off the end of the line
+         */
+        if (i < 2)
+            goto err;
+
+        bufp = (unsigned char *)buf;
+        if (first) {
+            first = 0;
+            if ((bufp[0] == '0') && (bufp[1] == '0')) {
+                bufp += 2;
+                i -= 2;
+            }
+        }
+        k = 0;
+        i -= again;
+        if (i % 2 != 0) {
+            ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_ODD_NUMBER_OF_CHARS);
+            OPENSSL_free(s);
+            return 0;
+        }
+        i /= 2;
+        if (num + i > slen) {
+            sp = OPENSSL_clear_realloc(s, slen, num + i * 2);
+            if (sp == NULL) {
+                ASN1err(ASN1_F_A2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
+                OPENSSL_free(s);
+                return 0;
+            }
+            s = sp;
+            slen = num + i * 2;
+        }
+        for (j = 0; j < i; j++, k += 2) {
+            for (n = 0; n < 2; n++) {
+                m = OPENSSL_hexchar2int(bufp[k + n]);
+                if (m < 0) {
+                    ASN1err(ASN1_F_A2I_ASN1_INTEGER,
+                            ASN1_R_NON_HEX_CHARACTERS);
+                    goto err;
+                }
+                s[num + j] <<= 4;
+                s[num + j] |= m;
+            }
+        }
+        num += i;
+        if (again)
+            bufsize = BIO_gets(bp, buf, size);
+        else
+            break;
+    }
+    bs->length = num;
+    bs->data = s;
+    return 1;
+ err:
+    ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_SHORT_LINE);
+    OPENSSL_free(s);
+    return 0;
+}
+
+int i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a)
+{
+    return i2a_ASN1_INTEGER(bp, a);
+}
+
+int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
+{
+    int rv = a2i_ASN1_INTEGER(bp, bs, buf, size);
+    if (rv == 1)
+        bs->type = V_ASN1_INTEGER | (bs->type & V_ASN1_NEG);
+    return rv;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/f_string.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/f_string.c
new file mode 100644
index 0000000..53dfec7
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/f_string.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright 1995-2017 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "crypto/ctype.h"
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1.h>
+
+int i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *a, int type)
+{
+    int i, n = 0;
+    static const char *h = "0123456789ABCDEF";
+    char buf[2];
+
+    if (a == NULL)
+        return 0;
+
+    if (a->length == 0) {
+        if (BIO_write(bp, "0", 1) != 1)
+            goto err;
+        n = 1;
+    } else {
+        for (i = 0; i < a->length; i++) {
+            if ((i != 0) && (i % 35 == 0)) {
+                if (BIO_write(bp, "\\\n", 2) != 2)
+                    goto err;
+                n += 2;
+            }
+            buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
+            buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
+            if (BIO_write(bp, buf, 2) != 2)
+                goto err;
+            n += 2;
+        }
+    }
+    return n;
+ err:
+    return -1;
+}
+
+int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
+{
+    int i, j, k, m, n, again, bufsize;
+    unsigned char *s = NULL, *sp;
+    unsigned char *bufp;
+    int num = 0, slen = 0, first = 1;
+
+    bufsize = BIO_gets(bp, buf, size);
+    for (;;) {
+        if (bufsize < 1) {
+            if (first)
+                break;
+            else
+                goto err;
+        }
+        first = 0;
+
+        i = bufsize;
+        if (buf[i - 1] == '\n')
+            buf[--i] = '\0';
+        if (i == 0)
+            goto err;
+        if (buf[i - 1] == '\r')
+            buf[--i] = '\0';
+        if (i == 0)
+            goto err;
+        again = (buf[i - 1] == '\\');
+
+        for (j = i - 1; j > 0; j--) {
+            if (!ossl_isxdigit(buf[j])) {
+                i = j;
+                break;
+            }
+        }
+        buf[i] = '\0';
+        /*
+         * We have now cleared all the crap off the end of the line
+         */
+        if (i < 2)
+            goto err;
+
+        bufp = (unsigned char *)buf;
+
+        k = 0;
+        i -= again;
+        if (i % 2 != 0) {
+            ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_ODD_NUMBER_OF_CHARS);
+            OPENSSL_free(s);
+            return 0;
+        }
+        i /= 2;
+        if (num + i > slen) {
+            sp = OPENSSL_realloc(s, (unsigned int)num + i * 2);
+            if (sp == NULL) {
+                ASN1err(ASN1_F_A2I_ASN1_STRING, ERR_R_MALLOC_FAILURE);
+                OPENSSL_free(s);
+                return 0;
+            }
+            s = sp;
+            slen = num + i * 2;
+        }
+        for (j = 0; j < i; j++, k += 2) {
+            for (n = 0; n < 2; n++) {
+                m = OPENSSL_hexchar2int(bufp[k + n]);
+                if (m < 0) {
+                    ASN1err(ASN1_F_A2I_ASN1_STRING,
+                            ASN1_R_NON_HEX_CHARACTERS);
+                    OPENSSL_free(s);
+                    return 0;
+                }
+                s[num + j] <<= 4;
+                s[num + j] |= m;
+            }
+        }
+        num += i;
+        if (again)
+            bufsize = BIO_gets(bp, buf, size);
+        else
+            break;
+    }
+    bs->length = num;
+    bs->data = s;
+    return 1;
+
+ err:
+    ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_SHORT_LINE);
+    OPENSSL_free(s);
+    return 0;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/i2d_pr.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/i2d_pr.c
new file mode 100644
index 0000000..0374c0b
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/i2d_pr.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright 1995-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include "crypto/asn1.h"
+#include "crypto/evp.h"
+
+int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp)
+{
+    if (a->ameth && a->ameth->old_priv_encode) {
+        return a->ameth->old_priv_encode(a, pp);
+    }
+    if (a->ameth && a->ameth->priv_encode) {
+        PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a);
+        int ret = 0;
+        if (p8 != NULL) {
+            ret = i2d_PKCS8_PRIV_KEY_INFO(p8, pp);
+            PKCS8_PRIV_KEY_INFO_free(p8);
+        }
+        return ret;
+    }
+    ASN1err(ASN1_F_I2D_PRIVATEKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+    return -1;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/i2d_pu.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/i2d_pu.c
new file mode 100644
index 0000000..8986c43
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/i2d_pu.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright 1995-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/ec.h>
+
+int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp)
+{
+    switch (EVP_PKEY_id(a)) {
+#ifndef OPENSSL_NO_RSA
+    case EVP_PKEY_RSA:
+        return i2d_RSAPublicKey(EVP_PKEY_get0_RSA(a), pp);
+#endif
+#ifndef OPENSSL_NO_DSA
+    case EVP_PKEY_DSA:
+        return i2d_DSAPublicKey(EVP_PKEY_get0_DSA(a), pp);
+#endif
+#ifndef OPENSSL_NO_EC
+    case EVP_PKEY_EC:
+        return i2o_ECPublicKey(EVP_PKEY_get0_EC_KEY(a), pp);
+#endif
+    default:
+        ASN1err(ASN1_F_I2D_PUBLICKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+        return -1;
+    }
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/n_pkey.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/n_pkey.c
new file mode 100644
index 0000000..d1fb8a1
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/n_pkey.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright 1995-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "openssl/opensslconf.h"
+#ifdef OPENSSL_NO_RSA
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include "internal/cryptlib.h"
+# include <stdio.h>
+# include <openssl/rsa.h>
+# include <openssl/objects.h>
+# include <openssl/asn1t.h>
+# include <openssl/evp.h>
+# include <openssl/x509.h>
+
+# ifndef OPENSSL_NO_RC4
+
+typedef struct netscape_pkey_st {
+    int32_t version;
+    X509_ALGOR *algor;
+    ASN1_OCTET_STRING *private_key;
+} NETSCAPE_PKEY;
+
+typedef struct netscape_encrypted_pkey_st {
+    ASN1_OCTET_STRING *os;
+    /*
+     * This is the same structure as DigestInfo so use it: although this
+     * isn't really anything to do with digests.
+     */
+    X509_SIG *enckey;
+} NETSCAPE_ENCRYPTED_PKEY;
+
+
+ASN1_BROKEN_SEQUENCE(NETSCAPE_ENCRYPTED_PKEY) = {
+        ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, os, ASN1_OCTET_STRING),
+        ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, enckey, X509_SIG)
+} static_ASN1_BROKEN_SEQUENCE_END(NETSCAPE_ENCRYPTED_PKEY)
+
+DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY,NETSCAPE_ENCRYPTED_PKEY)
+IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY)
+
+ASN1_SEQUENCE(NETSCAPE_PKEY) = {
+        ASN1_EMBED(NETSCAPE_PKEY, version, INT32),
+        ASN1_SIMPLE(NETSCAPE_PKEY, algor, X509_ALGOR),
+        ASN1_SIMPLE(NETSCAPE_PKEY, private_key, ASN1_OCTET_STRING)
+} static_ASN1_SEQUENCE_END(NETSCAPE_PKEY)
+
+DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_PKEY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_PKEY,NETSCAPE_PKEY)
+IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_PKEY)
+
+# endif                         /* OPENSSL_NO_RC4 */
+
+#endif
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/nsseq.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/nsseq.c
new file mode 100644
index 0000000..c7baf40
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/nsseq.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright 1999-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+
+static int nsseq_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                    void *exarg)
+{
+    if (operation == ASN1_OP_NEW_POST) {
+        NETSCAPE_CERT_SEQUENCE *nsseq;
+        nsseq = (NETSCAPE_CERT_SEQUENCE *)*pval;
+        nsseq->type = OBJ_nid2obj(NID_netscape_cert_sequence);
+    }
+    return 1;
+}
+
+/* Netscape certificate sequence structure */
+
+ASN1_SEQUENCE_cb(NETSCAPE_CERT_SEQUENCE, nsseq_cb) = {
+        ASN1_SIMPLE(NETSCAPE_CERT_SEQUENCE, type, ASN1_OBJECT),
+        ASN1_EXP_SEQUENCE_OF_OPT(NETSCAPE_CERT_SEQUENCE, certs, X509, 0)
+} ASN1_SEQUENCE_END_cb(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE)
+
+IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE)
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/p5_pbe.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/p5_pbe.c
new file mode 100644
index 0000000..ab7e168
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/p5_pbe.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright 1999-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/rand.h>
+
+/* PKCS#5 password based encryption structure */
+
+ASN1_SEQUENCE(PBEPARAM) = {
+        ASN1_SIMPLE(PBEPARAM, salt, ASN1_OCTET_STRING),
+        ASN1_SIMPLE(PBEPARAM, iter, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(PBEPARAM)
+
+IMPLEMENT_ASN1_FUNCTIONS(PBEPARAM)
+
+/* Set an algorithm identifier for a PKCS#5 PBE algorithm */
+
+int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
+                         const unsigned char *salt, int saltlen)
+{
+    PBEPARAM *pbe = NULL;
+    ASN1_STRING *pbe_str = NULL;
+    unsigned char *sstr = NULL;
+
+    pbe = PBEPARAM_new();
+    if (pbe == NULL) {
+        ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    if (iter <= 0)
+        iter = PKCS5_DEFAULT_ITER;
+    if (!ASN1_INTEGER_set(pbe->iter, iter)) {
+        ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    if (!saltlen)
+        saltlen = PKCS5_SALT_LEN;
+
+    sstr = OPENSSL_malloc(saltlen);
+    if (sstr == NULL) {
+        ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    if (salt)
+        memcpy(sstr, salt, saltlen);
+    else if (RAND_bytes(sstr, saltlen) <= 0)
+        goto err;
+
+    ASN1_STRING_set0(pbe->salt, sstr, saltlen);
+    sstr = NULL;
+
+    if (!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str)) {
+        ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    PBEPARAM_free(pbe);
+    pbe = NULL;
+
+    if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str))
+        return 1;
+
+ err:
+    OPENSSL_free(sstr);
+    PBEPARAM_free(pbe);
+    ASN1_STRING_free(pbe_str);
+    return 0;
+}
+
+/* Return an algorithm identifier for a PKCS#5 PBE algorithm */
+
+X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
+                          const unsigned char *salt, int saltlen)
+{
+    X509_ALGOR *ret;
+    ret = X509_ALGOR_new();
+    if (ret == NULL) {
+        ASN1err(ASN1_F_PKCS5_PBE_SET, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    if (PKCS5_pbe_set0_algor(ret, alg, iter, salt, saltlen))
+        return ret;
+
+    X509_ALGOR_free(ret);
+    return NULL;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/p5_pbev2.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/p5_pbev2.c
new file mode 100644
index 0000000..f91ba08
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/p5_pbev2.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright 1999-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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/rand.h>
+
+/* PKCS#5 v2.0 password based encryption structures */
+
+ASN1_SEQUENCE(PBE2PARAM) = {
+        ASN1_SIMPLE(PBE2PARAM, keyfunc, X509_ALGOR),
+        ASN1_SIMPLE(PBE2PARAM, encryption, X509_ALGOR)
+} ASN1_SEQUENCE_END(PBE2PARAM)
+
+IMPLEMENT_ASN1_FUNCTIONS(PBE2PARAM)
+
+ASN1_SEQUENCE(PBKDF2PARAM) = {
+        ASN1_SIMPLE(PBKDF2PARAM, salt, ASN1_ANY),
+        ASN1_SIMPLE(PBKDF2PARAM, iter, ASN1_INTEGER),
+        ASN1_OPT(PBKDF2PARAM, keylength, ASN1_INTEGER),
+        ASN1_OPT(PBKDF2PARAM, prf, X509_ALGOR)
+} ASN1_SEQUENCE_END(PBKDF2PARAM)
+
+IMPLEMENT_ASN1_FUNCTIONS(PBKDF2PARAM)
+
+/*
+ * Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm: yes I know
+ * this is horrible! Extended version to allow application supplied PRF NID
+ * and IV.
+ */
+
+X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
+                              unsigned char *salt, int saltlen,
+                              unsigned char *aiv, int prf_nid)
+{
+    X509_ALGOR *scheme = NULL, *ret = NULL;
+    int alg_nid, keylen;
+    EVP_CIPHER_CTX *ctx = NULL;
+    unsigned char iv[EVP_MAX_IV_LENGTH];
+    PBE2PARAM *pbe2 = NULL;
+
+    alg_nid = EVP_CIPHER_type(cipher);
+    if (alg_nid == NID_undef) {
+        ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
+                ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
+        goto err;
+    }
+
+    if ((pbe2 = PBE2PARAM_new()) == NULL)
+        goto merr;
+
+    /* Setup the AlgorithmIdentifier for the encryption scheme */
+    scheme = pbe2->encryption;
+    scheme->algorithm = OBJ_nid2obj(alg_nid);
+    if ((scheme->parameter = ASN1_TYPE_new()) == NULL)
+        goto merr;
+
+    /* Create random IV */
+    if (EVP_CIPHER_iv_length(cipher)) {
+        if (aiv)
+            memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
+        else if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) <= 0)
+            goto err;
+    }
+
+    ctx = EVP_CIPHER_CTX_new();
+    if (ctx == NULL)
+        goto merr;
+
+    /* Dummy cipherinit to just setup the IV, and PRF */
+    if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, iv, 0))
+        goto err;
+    if (EVP_CIPHER_param_to_asn1(ctx, scheme->parameter) <= 0) {
+        ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
+        goto err;
+    }
+    /*
+     * If prf NID unspecified see if cipher has a preference. An error is OK
+     * here: just means use default PRF.
+     */
+    if ((prf_nid == -1) &&
+        EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0) {
+        ERR_clear_error();
+        prf_nid = NID_hmacWithSHA256;
+    }
+    EVP_CIPHER_CTX_free(ctx);
+    ctx = NULL;
+
+    /* If its RC2 then we'd better setup the key length */
+
+    if (alg_nid == NID_rc2_cbc)
+        keylen = EVP_CIPHER_key_length(cipher);
+    else
+        keylen = -1;
+
+    /* Setup keyfunc */
+
+    X509_ALGOR_free(pbe2->keyfunc);
+
+    pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen);
+
+    if (!pbe2->keyfunc)
+        goto merr;
+
+    /* Now set up top level AlgorithmIdentifier */
+
+    if ((ret = X509_ALGOR_new()) == NULL)
+        goto merr;
+
+    ret->algorithm = OBJ_nid2obj(NID_pbes2);
+
+    /* Encode PBE2PARAM into parameter */
+
+    if (!ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBE2PARAM), pbe2,
+                                 &ret->parameter))
+         goto merr;
+
+    PBE2PARAM_free(pbe2);
+    pbe2 = NULL;
+
+    return ret;
+
+ merr:
+    ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ERR_R_MALLOC_FAILURE);
+
+ err:
+    EVP_CIPHER_CTX_free(ctx);
+    PBE2PARAM_free(pbe2);
+    /* Note 'scheme' is freed as part of pbe2 */
+    X509_ALGOR_free(ret);
+
+    return NULL;
+}
+
+X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
+                           unsigned char *salt, int saltlen)
+{
+    return PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, -1);
+}
+
+X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
+                             int prf_nid, int keylen)
+{
+    X509_ALGOR *keyfunc = NULL;
+    PBKDF2PARAM *kdf = NULL;
+    ASN1_OCTET_STRING *osalt = NULL;
+
+    if ((kdf = PBKDF2PARAM_new()) == NULL)
+        goto merr;
+    if ((osalt = ASN1_OCTET_STRING_new()) == NULL)
+        goto merr;
+
+    kdf->salt->value.octet_string = osalt;
+    kdf->salt->type = V_ASN1_OCTET_STRING;
+
+    if (saltlen == 0)
+        saltlen = PKCS5_SALT_LEN;
+    if ((osalt->data = OPENSSL_malloc(saltlen)) == NULL)
+        goto merr;
+
+    osalt->length = saltlen;
+
+    if (salt)
+        memcpy(osalt->data, salt, saltlen);
+    else if (RAND_bytes(osalt->data, saltlen) <= 0)
+        goto merr;
+
+    if (iter <= 0)
+        iter = PKCS5_DEFAULT_ITER;
+
+    if (!ASN1_INTEGER_set(kdf->iter, iter))
+        goto merr;
+
+    /* If have a key len set it up */
+
+    if (keylen > 0) {
+        if ((kdf->keylength = ASN1_INTEGER_new()) == NULL)
+            goto merr;
+        if (!ASN1_INTEGER_set(kdf->keylength, keylen))
+            goto merr;
+    }
+
+    /* prf can stay NULL if we are using hmacWithSHA1 */
+    if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1) {
+        kdf->prf = X509_ALGOR_new();
+        if (kdf->prf == NULL)
+            goto merr;
+        X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid), V_ASN1_NULL, NULL);
+    }
+
+    /* Finally setup the keyfunc structure */
+
+    keyfunc = X509_ALGOR_new();
+    if (keyfunc == NULL)
+        goto merr;
+
+    keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);
+
+    /* Encode PBKDF2PARAM into parameter of pbe2 */
+
+    if (!ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBKDF2PARAM), kdf,
+                                 &keyfunc->parameter))
+         goto merr;
+
+    PBKDF2PARAM_free(kdf);
+    return keyfunc;
+
+ merr:
+    ASN1err(ASN1_F_PKCS5_PBKDF2_SET, ERR_R_MALLOC_FAILURE);
+    PBKDF2PARAM_free(kdf);
+    X509_ALGOR_free(keyfunc);
+    return NULL;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/p5_scrypt.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/p5_scrypt.c
new file mode 100644
index 0000000..1491d96
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/p5_scrypt.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright 2015-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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/rand.h>
+
+#ifndef OPENSSL_NO_SCRYPT
+/* PKCS#5 scrypt password based encryption structures */
+
+ASN1_SEQUENCE(SCRYPT_PARAMS) = {
+        ASN1_SIMPLE(SCRYPT_PARAMS, salt, ASN1_OCTET_STRING),
+        ASN1_SIMPLE(SCRYPT_PARAMS, costParameter, ASN1_INTEGER),
+        ASN1_SIMPLE(SCRYPT_PARAMS, blockSize, ASN1_INTEGER),
+        ASN1_SIMPLE(SCRYPT_PARAMS, parallelizationParameter, ASN1_INTEGER),
+        ASN1_OPT(SCRYPT_PARAMS, keyLength, ASN1_INTEGER),
+} ASN1_SEQUENCE_END(SCRYPT_PARAMS)
+
+IMPLEMENT_ASN1_FUNCTIONS(SCRYPT_PARAMS)
+
+static X509_ALGOR *pkcs5_scrypt_set(const unsigned char *salt, size_t saltlen,
+                                    size_t keylen, uint64_t N, uint64_t r,
+                                    uint64_t p);
+
+/*
+ * Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm using scrypt
+ */
+
+X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher,
+                                  const unsigned char *salt, int saltlen,
+                                  unsigned char *aiv, uint64_t N, uint64_t r,
+                                  uint64_t p)
+{
+    X509_ALGOR *scheme = NULL, *ret = NULL;
+    int alg_nid;
+    size_t keylen = 0;
+    EVP_CIPHER_CTX *ctx = NULL;
+    unsigned char iv[EVP_MAX_IV_LENGTH];
+    PBE2PARAM *pbe2 = NULL;
+
+    if (!cipher) {
+        ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ERR_R_PASSED_NULL_PARAMETER);
+        goto err;
+    }
+
+    if (EVP_PBE_scrypt(NULL, 0, NULL, 0, N, r, p, 0, NULL, 0) == 0) {
+        ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT,
+                ASN1_R_INVALID_SCRYPT_PARAMETERS);
+        goto err;
+    }
+
+    alg_nid = EVP_CIPHER_type(cipher);
+    if (alg_nid == NID_undef) {
+        ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT,
+                ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
+        goto err;
+    }
+
+    pbe2 = PBE2PARAM_new();
+    if (pbe2 == NULL)
+        goto merr;
+
+    /* Setup the AlgorithmIdentifier for the encryption scheme */
+    scheme = pbe2->encryption;
+
+    scheme->algorithm = OBJ_nid2obj(alg_nid);
+    scheme->parameter = ASN1_TYPE_new();
+    if (scheme->parameter == NULL)
+        goto merr;
+
+    /* Create random IV */
+    if (EVP_CIPHER_iv_length(cipher)) {
+        if (aiv)
+            memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
+        else if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) <= 0)
+            goto err;
+    }
+
+    ctx = EVP_CIPHER_CTX_new();
+    if (ctx == NULL)
+        goto merr;
+
+    /* Dummy cipherinit to just setup the IV */
+    if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, iv, 0) == 0)
+        goto err;
+    if (EVP_CIPHER_param_to_asn1(ctx, scheme->parameter) <= 0) {
+        ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT,
+                ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
+        goto err;
+    }
+    EVP_CIPHER_CTX_free(ctx);
+    ctx = NULL;
+
+    /* If its RC2 then we'd better setup the key length */
+
+    if (alg_nid == NID_rc2_cbc)
+        keylen = EVP_CIPHER_key_length(cipher);
+
+    /* Setup keyfunc */
+
+    X509_ALGOR_free(pbe2->keyfunc);
+
+    pbe2->keyfunc = pkcs5_scrypt_set(salt, saltlen, keylen, N, r, p);
+
+    if (pbe2->keyfunc == NULL)
+        goto merr;
+
+    /* Now set up top level AlgorithmIdentifier */
+
+    ret = X509_ALGOR_new();
+    if (ret == NULL)
+        goto merr;
+
+    ret->algorithm = OBJ_nid2obj(NID_pbes2);
+
+    /* Encode PBE2PARAM into parameter */
+
+    if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBE2PARAM), pbe2,
+                                &ret->parameter) == NULL)
+        goto merr;
+
+    PBE2PARAM_free(pbe2);
+    pbe2 = NULL;
+
+    return ret;
+
+ merr:
+    ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ERR_R_MALLOC_FAILURE);
+
+ err:
+    PBE2PARAM_free(pbe2);
+    X509_ALGOR_free(ret);
+    EVP_CIPHER_CTX_free(ctx);
+
+    return NULL;
+}
+
+static X509_ALGOR *pkcs5_scrypt_set(const unsigned char *salt, size_t saltlen,
+                                    size_t keylen, uint64_t N, uint64_t r,
+                                    uint64_t p)
+{
+    X509_ALGOR *keyfunc = NULL;
+    SCRYPT_PARAMS *sparam = SCRYPT_PARAMS_new();
+
+    if (sparam == NULL)
+        goto merr;
+
+    if (!saltlen)
+        saltlen = PKCS5_SALT_LEN;
+
+    /* This will either copy salt or grow the buffer */
+    if (ASN1_STRING_set(sparam->salt, salt, saltlen) == 0)
+        goto merr;
+
+    if (salt == NULL && RAND_bytes(sparam->salt->data, saltlen) <= 0)
+        goto err;
+
+    if (ASN1_INTEGER_set_uint64(sparam->costParameter, N) == 0)
+        goto merr;
+
+    if (ASN1_INTEGER_set_uint64(sparam->blockSize, r) == 0)
+        goto merr;
+
+    if (ASN1_INTEGER_set_uint64(sparam->parallelizationParameter, p) == 0)
+        goto merr;
+
+    /* If have a key len set it up */
+
+    if (keylen > 0) {
+        sparam->keyLength = ASN1_INTEGER_new();
+        if (sparam->keyLength == NULL)
+            goto merr;
+        if (ASN1_INTEGER_set_int64(sparam->keyLength, keylen) == 0)
+            goto merr;
+    }
+
+    /* Finally setup the keyfunc structure */
+
+    keyfunc = X509_ALGOR_new();
+    if (keyfunc == NULL)
+        goto merr;
+
+    keyfunc->algorithm = OBJ_nid2obj(NID_id_scrypt);
+
+    /* Encode SCRYPT_PARAMS into parameter of pbe2 */
+
+    if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(SCRYPT_PARAMS), sparam,
+                                &keyfunc->parameter) == NULL)
+        goto merr;
+
+    SCRYPT_PARAMS_free(sparam);
+    return keyfunc;
+
+ merr:
+    ASN1err(ASN1_F_PKCS5_SCRYPT_SET, ERR_R_MALLOC_FAILURE);
+ err:
+    SCRYPT_PARAMS_free(sparam);
+    X509_ALGOR_free(keyfunc);
+    return NULL;
+}
+
+int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
+                             int passlen, ASN1_TYPE *param,
+                             const EVP_CIPHER *c, const EVP_MD *md, int en_de)
+{
+    unsigned char *salt, key[EVP_MAX_KEY_LENGTH];
+    uint64_t p, r, N;
+    size_t saltlen;
+    size_t keylen = 0;
+    int rv = 0;
+    SCRYPT_PARAMS *sparam = NULL;
+
+    if (EVP_CIPHER_CTX_cipher(ctx) == NULL) {
+        EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, EVP_R_NO_CIPHER_SET);
+        goto err;
+    }
+
+    /* Decode parameter */
+
+    sparam = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(SCRYPT_PARAMS), param);
+
+    if (sparam == NULL) {
+        EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, EVP_R_DECODE_ERROR);
+        goto err;
+    }
+
+    keylen = EVP_CIPHER_CTX_key_length(ctx);
+
+    /* Now check the parameters of sparam */
+
+    if (sparam->keyLength) {
+        uint64_t spkeylen;
+        if ((ASN1_INTEGER_get_uint64(&spkeylen, sparam->keyLength) == 0)
+            || (spkeylen != keylen)) {
+            EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN,
+                   EVP_R_UNSUPPORTED_KEYLENGTH);
+            goto err;
+        }
+    }
+    /* Check all parameters fit in uint64_t and are acceptable to scrypt */
+    if (ASN1_INTEGER_get_uint64(&N, sparam->costParameter) == 0
+        || ASN1_INTEGER_get_uint64(&r, sparam->blockSize) == 0
+        || ASN1_INTEGER_get_uint64(&p, sparam->parallelizationParameter) == 0
+        || EVP_PBE_scrypt(NULL, 0, NULL, 0, N, r, p, 0, NULL, 0) == 0) {
+        EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN,
+               EVP_R_ILLEGAL_SCRYPT_PARAMETERS);
+        goto err;
+    }
+
+    /* it seems that its all OK */
+
+    salt = sparam->salt->data;
+    saltlen = sparam->salt->length;
+    if (EVP_PBE_scrypt(pass, passlen, salt, saltlen, N, r, p, 0, key, keylen)
+        == 0)
+        goto err;
+    rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);
+ err:
+    if (keylen)
+        OPENSSL_cleanse(key, keylen);
+    SCRYPT_PARAMS_free(sparam);
+    return rv;
+}
+#endif /* OPENSSL_NO_SCRYPT */
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/p8_pkey.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/p8_pkey.c
new file mode 100644
index 0000000..ab509b1
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/p8_pkey.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright 1999-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "crypto/x509.h"
+
+/* Minor tweak to operation: zero private key data */
+static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                   void *exarg)
+{
+    /* Since the structure must still be valid use ASN1_OP_FREE_PRE */
+    if (operation == ASN1_OP_FREE_PRE) {
+        PKCS8_PRIV_KEY_INFO *key = (PKCS8_PRIV_KEY_INFO *)*pval;
+        if (key->pkey)
+            OPENSSL_cleanse(key->pkey->data, key->pkey->length);
+    }
+    return 1;
+}
+
+ASN1_SEQUENCE_cb(PKCS8_PRIV_KEY_INFO, pkey_cb) = {
+        ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, version, ASN1_INTEGER),
+        ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkeyalg, X509_ALGOR),
+        ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkey, ASN1_OCTET_STRING),
+        ASN1_IMP_SET_OF_OPT(PKCS8_PRIV_KEY_INFO, attributes, X509_ATTRIBUTE, 0)
+} ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
+
+int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
+                    int version,
+                    int ptype, void *pval, unsigned char *penc, int penclen)
+{
+    if (version >= 0) {
+        if (!ASN1_INTEGER_set(priv->version, version))
+            return 0;
+    }
+    if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval))
+        return 0;
+    if (penc)
+        ASN1_STRING_set0(priv->pkey, penc, penclen);
+    return 1;
+}
+
+int PKCS8_pkey_get0(const ASN1_OBJECT **ppkalg,
+                    const unsigned char **pk, int *ppklen,
+                    const X509_ALGOR **pa, const PKCS8_PRIV_KEY_INFO *p8)
+{
+    if (ppkalg)
+        *ppkalg = p8->pkeyalg->algorithm;
+    if (pk) {
+        *pk = ASN1_STRING_get0_data(p8->pkey);
+        *ppklen = ASN1_STRING_length(p8->pkey);
+    }
+    if (pa)
+        *pa = p8->pkeyalg;
+    return 1;
+}
+
+const STACK_OF(X509_ATTRIBUTE) *
+PKCS8_pkey_get0_attrs(const PKCS8_PRIV_KEY_INFO *p8)
+{
+    return p8->attributes;
+}
+
+int PKCS8_pkey_add1_attr_by_NID(PKCS8_PRIV_KEY_INFO *p8, int nid, int type,
+                                const unsigned char *bytes, int len)
+{
+    if (X509at_add1_attr_by_NID(&p8->attributes, nid, type, bytes, len) != NULL)
+        return 1;
+    return 0;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/standard_methods.h b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/standard_methods.h
new file mode 100644
index 0000000..e74de55
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/standard_methods.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2006-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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * This table MUST be kept in ascending order of the NID each method
+ * represents (corresponding to the pkey_id field) as OBJ_bsearch
+ * is used to search it.
+ */
+static const EVP_PKEY_ASN1_METHOD *standard_methods[] = {
+#ifndef OPENSSL_NO_RSA
+    &rsa_asn1_meths[0],
+    &rsa_asn1_meths[1],
+#endif
+#ifndef OPENSSL_NO_DH
+    &dh_asn1_meth,
+#endif
+#ifndef OPENSSL_NO_DSA
+    &dsa_asn1_meths[0],
+    &dsa_asn1_meths[1],
+    &dsa_asn1_meths[2],
+    &dsa_asn1_meths[3],
+    &dsa_asn1_meths[4],
+#endif
+#ifndef OPENSSL_NO_EC
+    &eckey_asn1_meth,
+#endif
+    &hmac_asn1_meth,
+#ifndef OPENSSL_NO_CMAC
+    &cmac_asn1_meth,
+#endif
+#ifndef OPENSSL_NO_RSA
+    &rsa_pss_asn1_meth,
+#endif
+#ifndef OPENSSL_NO_DH
+    &dhx_asn1_meth,
+#endif
+#ifndef OPENSSL_NO_EC
+    &ecx25519_asn1_meth,
+    &ecx448_asn1_meth,
+#endif
+#ifndef OPENSSL_NO_POLY1305
+    &poly1305_asn1_meth,
+#endif
+#ifndef OPENSSL_NO_SIPHASH
+    &siphash_asn1_meth,
+#endif
+#ifndef OPENSSL_NO_EC
+    &ed25519_asn1_meth,
+    &ed448_asn1_meth,
+#endif
+#ifndef OPENSSL_NO_SM2
+    &sm2_asn1_meth,
+#endif
+};
+
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/t_bitst.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/t_bitst.c
new file mode 100644
index 0000000..c0aeca4
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/t_bitst.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright 1999-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
+                               BIT_STRING_BITNAME *tbl, int indent)
+{
+    BIT_STRING_BITNAME *bnam;
+    char first = 1;
+    BIO_printf(out, "%*s", indent, "");
+    for (bnam = tbl; bnam->lname; bnam++) {
+        if (ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) {
+            if (!first)
+                BIO_puts(out, ", ");
+            BIO_puts(out, bnam->lname);
+            first = 0;
+        }
+    }
+    BIO_puts(out, "\n");
+    return 1;
+}
+
+int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, const char *name, int value,
+                            BIT_STRING_BITNAME *tbl)
+{
+    int bitnum;
+    bitnum = ASN1_BIT_STRING_num_asc(name, tbl);
+    if (bitnum < 0)
+        return 0;
+    if (bs) {
+        if (!ASN1_BIT_STRING_set_bit(bs, bitnum, value))
+            return 0;
+    }
+    return 1;
+}
+
+int ASN1_BIT_STRING_num_asc(const char *name, BIT_STRING_BITNAME *tbl)
+{
+    BIT_STRING_BITNAME *bnam;
+    for (bnam = tbl; bnam->lname; bnam++) {
+        if ((strcmp(bnam->sname, name) == 0)
+            || (strcmp(bnam->lname, name) == 0))
+            return bnam->bitnum;
+    }
+    return -1;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/t_pkey.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/t_pkey.c
new file mode 100644
index 0000000..651622a
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/t_pkey.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright 1995-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include "crypto/bn.h"
+
+/* Number of octets per line */
+#define ASN1_BUF_PRINT_WIDTH    15
+/* Maximum indent */
+#define ASN1_PRINT_MAX_INDENT 128
+
+int ASN1_buf_print(BIO *bp, const unsigned char *buf, size_t buflen, int indent)
+{
+    size_t i;
+
+    for (i = 0; i < buflen; i++) {
+        if ((i % ASN1_BUF_PRINT_WIDTH) == 0) {
+            if (i > 0 && BIO_puts(bp, "\n") <= 0)
+                return 0;
+            if (!BIO_indent(bp, indent, ASN1_PRINT_MAX_INDENT))
+                return 0;
+        }
+        /*
+         * Use colon separators for each octet for compatibility as
+         * this function is used to print out key components.
+         */
+        if (BIO_printf(bp, "%02x%s", buf[i],
+                       (i == buflen - 1) ? "" : ":") <= 0)
+                return 0;
+    }
+    if (BIO_write(bp, "\n", 1) <= 0)
+        return 0;
+    return 1;
+}
+
+int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
+                  unsigned char *ign, int indent)
+{
+    int n, rv = 0;
+    const char *neg;
+    unsigned char *buf = NULL, *tmp = NULL;
+    int buflen;
+
+    if (num == NULL)
+        return 1;
+    neg = BN_is_negative(num) ? "-" : "";
+    if (!BIO_indent(bp, indent, ASN1_PRINT_MAX_INDENT))
+        return 0;
+    if (BN_is_zero(num)) {
+        if (BIO_printf(bp, "%s 0\n", number) <= 0)
+            return 0;
+        return 1;
+    }
+
+    if (BN_num_bytes(num) <= BN_BYTES) {
+        if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg,
+                       (unsigned long)bn_get_words(num)[0], neg,
+                       (unsigned long)bn_get_words(num)[0]) <= 0)
+            return 0;
+        return 1;
+    }
+
+    buflen = BN_num_bytes(num) + 1;
+    buf = tmp = OPENSSL_malloc(buflen);
+    if (buf == NULL)
+        goto err;
+    buf[0] = 0;
+    if (BIO_printf(bp, "%s%s\n", number,
+                   (neg[0] == '-') ? " (Negative)" : "") <= 0)
+        goto err;
+    n = BN_bn2bin(num, buf + 1);
+
+    if (buf[1] & 0x80)
+        n++;
+    else
+        tmp++;
+
+    if (ASN1_buf_print(bp, tmp, n, indent + 4) == 0)
+        goto err;
+    rv = 1;
+    err:
+    OPENSSL_clear_free(buf, buflen);
+    return rv;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/t_spki.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/t_spki.c
new file mode 100644
index 0000000..3d4aea8
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/t_spki.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright 1999-2021 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/bn.h>
+
+/* Print out an SPKI */
+
+int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki)
+{
+    EVP_PKEY *pkey;
+    ASN1_IA5STRING *chal;
+    ASN1_OBJECT *spkioid;
+    int i, n;
+    char *s;
+    BIO_printf(out, "Netscape SPKI:\n");
+    X509_PUBKEY_get0_param(&spkioid, NULL, NULL, NULL, spki->spkac->pubkey);
+    i = OBJ_obj2nid(spkioid);
+    BIO_printf(out, "  Public Key Algorithm: %s\n",
+               (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i));
+    pkey = X509_PUBKEY_get(spki->spkac->pubkey);
+    if (!pkey)
+        BIO_printf(out, "  Unable to load public key\n");
+    else {
+        EVP_PKEY_print_public(out, pkey, 4, NULL);
+        EVP_PKEY_free(pkey);
+    }
+    chal = spki->spkac->challenge;
+    if (chal->length)
+        BIO_printf(out, "  Challenge String: %.*s\n", chal->length, chal->data);
+    i = OBJ_obj2nid(spki->sig_algor.algorithm);
+    BIO_printf(out, "  Signature Algorithm: %s",
+               (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i));
+
+    n = spki->signature->length;
+    s = (char *)spki->signature->data;
+    for (i = 0; i < n; i++) {
+        if ((i % 18) == 0)
+            BIO_write(out, "\n      ", 7);
+        BIO_printf(out, "%02x%s", (unsigned char)s[i],
+                   ((i + 1) == n) ? "" : ":");
+    }
+    BIO_write(out, "\n", 1);
+    return 1;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_dec.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_dec.c
new file mode 100644
index 0000000..82577b1
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_dec.c
@@ -0,0 +1,1179 @@
+/*
+ * Copyright 2000-2020 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stddef.h>
+#include <string.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+#include "internal/numbers.h"
+#include "asn1_local.h"
+
+
+/*
+ * Constructed types with a recursive definition (such as can be found in PKCS7)
+ * could eventually exceed the stack given malicious input with excessive
+ * recursion. Therefore we limit the stack depth. This is the maximum number of
+ * recursive invocations of asn1_item_embed_d2i().
+ */
+#define ASN1_MAX_CONSTRUCTED_NEST 30
+
+static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
+                               long len, const ASN1_ITEM *it,
+                               int tag, int aclass, char opt, ASN1_TLC *ctx,
+                               int depth);
+
+static int asn1_check_eoc(const unsigned char **in, long len);
+static int asn1_find_end(const unsigned char **in, long len, char inf);
+
+static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
+                        char inf, int tag, int aclass, int depth);
+
+static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen);
+
+static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
+                           char *inf, char *cst,
+                           const unsigned char **in, long len,
+                           int exptag, int expclass, char opt, ASN1_TLC *ctx);
+
+static int asn1_template_ex_d2i(ASN1_VALUE **pval,
+                                const unsigned char **in, long len,
+                                const ASN1_TEMPLATE *tt, char opt,
+                                ASN1_TLC *ctx, int depth);
+static int asn1_template_noexp_d2i(ASN1_VALUE **val,
+                                   const unsigned char **in, long len,
+                                   const ASN1_TEMPLATE *tt, char opt,
+                                   ASN1_TLC *ctx, int depth);
+static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
+                                 const unsigned char **in, long len,
+                                 const ASN1_ITEM *it,
+                                 int tag, int aclass, char opt,
+                                 ASN1_TLC *ctx);
+static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+                       int utype, char *free_cont, const ASN1_ITEM *it);
+
+/* Table to convert tags to bit values, used for MSTRING type */
+static const unsigned long tag2bit[32] = {
+    /* tags  0 -  3 */
+    0, 0, 0, B_ASN1_BIT_STRING,
+    /* tags  4- 7 */
+    B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN,
+    /* tags  8-11 */
+    B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,
+    /* tags 12-15 */
+    B_ASN1_UTF8STRING, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,
+    /* tags 16-19 */
+    B_ASN1_SEQUENCE, 0, B_ASN1_NUMERICSTRING, B_ASN1_PRINTABLESTRING,
+    /* tags 20-22 */
+    B_ASN1_T61STRING, B_ASN1_VIDEOTEXSTRING, B_ASN1_IA5STRING,
+    /* tags 23-24 */
+    B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME,
+    /* tags 25-27 */
+    B_ASN1_GRAPHICSTRING, B_ASN1_ISO64STRING, B_ASN1_GENERALSTRING,
+    /* tags 28-31 */
+    B_ASN1_UNIVERSALSTRING, B_ASN1_UNKNOWN, B_ASN1_BMPSTRING, B_ASN1_UNKNOWN,
+};
+
+unsigned long ASN1_tag2bit(int tag)
+{
+    if ((tag < 0) || (tag > 30))
+        return 0;
+    return tag2bit[tag];
+}
+
+/* Macro to initialize and invalidate the cache */
+
+#define asn1_tlc_clear(c)       if (c) (c)->valid = 0
+/* Version to avoid compiler warning about 'c' always non-NULL */
+#define asn1_tlc_clear_nc(c)    (c)->valid = 0
+
+/*
+ * Decode an ASN1 item, this currently behaves just like a standard 'd2i'
+ * function. 'in' points to a buffer to read the data from, in future we
+ * will have more advanced versions that can input data a piece at a time and
+ * this will simply be a special case.
+ */
+
+ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval,
+                          const unsigned char **in, long len,
+                          const ASN1_ITEM *it)
+{
+    ASN1_TLC c;
+    ASN1_VALUE *ptmpval = NULL;
+    if (!pval)
+        pval = &ptmpval;
+    asn1_tlc_clear_nc(&c);
+    if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0)
+        return *pval;
+    return NULL;
+}
+
+int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
+                     const ASN1_ITEM *it,
+                     int tag, int aclass, char opt, ASN1_TLC *ctx)
+{
+    int rv;
+    rv = asn1_item_embed_d2i(pval, in, len, it, tag, aclass, opt, ctx, 0);
+    if (rv <= 0)
+        ASN1_item_ex_free(pval, it);
+    return rv;
+}
+
+/*
+ * Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and
+ * tag mismatch return -1 to handle OPTIONAL
+ */
+
+static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
+                               long len, const ASN1_ITEM *it,
+                               int tag, int aclass, char opt, ASN1_TLC *ctx,
+                               int depth)
+{
+    const ASN1_TEMPLATE *tt, *errtt = NULL;
+    const ASN1_EXTERN_FUNCS *ef;
+    const ASN1_AUX *aux = it->funcs;
+    ASN1_aux_cb *asn1_cb;
+    const unsigned char *p = NULL, *q;
+    unsigned char oclass;
+    char seq_eoc, seq_nolen, cst, isopt;
+    long tmplen;
+    int i;
+    int otag;
+    int ret = 0;
+    ASN1_VALUE **pchptr;
+    if (!pval)
+        return 0;
+    if (aux && aux->asn1_cb)
+        asn1_cb = aux->asn1_cb;
+    else
+        asn1_cb = 0;
+
+    if (++depth > ASN1_MAX_CONSTRUCTED_NEST) {
+        ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_NESTED_TOO_DEEP);
+        goto err;
+    }
+
+    switch (it->itype) {
+    case ASN1_ITYPE_PRIMITIVE:
+        if (it->templates) {
+            /*
+             * tagging or OPTIONAL is currently illegal on an item template
+             * because the flags can't get passed down. In practice this
+             * isn't a problem: we include the relevant flags from the item
+             * template in the template itself.
+             */
+            if ((tag != -1) || opt) {
+                ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I,
+                        ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
+                goto err;
+            }
+            return asn1_template_ex_d2i(pval, in, len,
+                                        it->templates, opt, ctx, depth);
+        }
+        return asn1_d2i_ex_primitive(pval, in, len, it,
+                                     tag, aclass, opt, ctx);
+
+    case ASN1_ITYPE_MSTRING:
+        /*
+         * It never makes sense for multi-strings to have implicit tagging, so
+         * if tag != -1, then this looks like an error in the template.
+         */
+        if (tag != -1) {
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_BAD_TEMPLATE);
+            goto err;
+        }
+
+        p = *in;
+        /* Just read in tag and class */
+        ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL,
+                              &p, len, -1, 0, 1, ctx);
+        if (!ret) {
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR);
+            goto err;
+        }
+
+        /* Must be UNIVERSAL class */
+        if (oclass != V_ASN1_UNIVERSAL) {
+            /* If OPTIONAL, assume this is OK */
+            if (opt)
+                return -1;
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_MSTRING_NOT_UNIVERSAL);
+            goto err;
+        }
+
+        /* Check tag matches bit map */
+        if (!(ASN1_tag2bit(otag) & it->utype)) {
+            /* If OPTIONAL, assume this is OK */
+            if (opt)
+                return -1;
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_MSTRING_WRONG_TAG);
+            goto err;
+        }
+        return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0, ctx);
+
+    case ASN1_ITYPE_EXTERN:
+        /* Use new style d2i */
+        ef = it->funcs;
+        return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx);
+
+    case ASN1_ITYPE_CHOICE:
+        /*
+         * It never makes sense for CHOICE types to have implicit tagging, so
+         * if tag != -1, then this looks like an error in the template.
+         */
+        if (tag != -1) {
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_BAD_TEMPLATE);
+            goto err;
+        }
+
+        if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
+            goto auxerr;
+        if (*pval) {
+            /* Free up and zero CHOICE value if initialised */
+            i = asn1_get_choice_selector(pval, it);
+            if ((i >= 0) && (i < it->tcount)) {
+                tt = it->templates + i;
+                pchptr = asn1_get_field_ptr(pval, tt);
+                asn1_template_free(pchptr, tt);
+                asn1_set_choice_selector(pval, -1, it);
+            }
+        } else if (!ASN1_item_ex_new(pval, it)) {
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR);
+            goto err;
+        }
+        /* CHOICE type, try each possibility in turn */
+        p = *in;
+        for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+            pchptr = asn1_get_field_ptr(pval, tt);
+            /*
+             * We mark field as OPTIONAL so its absence can be recognised.
+             */
+            ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx, depth);
+            /* If field not present, try the next one */
+            if (ret == -1)
+                continue;
+            /* If positive return, read OK, break loop */
+            if (ret > 0)
+                break;
+            /*
+             * Must be an ASN1 parsing error.
+             * Free up any partial choice value
+             */
+            asn1_template_free(pchptr, tt);
+            errtt = tt;
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR);
+            goto err;
+        }
+
+        /* Did we fall off the end without reading anything? */
+        if (i == it->tcount) {
+            /* If OPTIONAL, this is OK */
+            if (opt) {
+                /* Free and zero it */
+                ASN1_item_ex_free(pval, it);
+                return -1;
+            }
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_NO_MATCHING_CHOICE_TYPE);
+            goto err;
+        }
+
+        asn1_set_choice_selector(pval, i, it);
+
+        if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
+            goto auxerr;
+        *in = p;
+        return 1;
+
+    case ASN1_ITYPE_NDEF_SEQUENCE:
+    case ASN1_ITYPE_SEQUENCE:
+        p = *in;
+        tmplen = len;
+
+        /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
+        if (tag == -1) {
+            tag = V_ASN1_SEQUENCE;
+            aclass = V_ASN1_UNIVERSAL;
+        }
+        /* Get SEQUENCE length and update len, p */
+        ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst,
+                              &p, len, tag, aclass, opt, ctx);
+        if (!ret) {
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR);
+            goto err;
+        } else if (ret == -1)
+            return -1;
+        if (aux && (aux->flags & ASN1_AFLG_BROKEN)) {
+            len = tmplen - (p - *in);
+            seq_nolen = 1;
+        }
+        /* If indefinite we don't do a length check */
+        else
+            seq_nolen = seq_eoc;
+        if (!cst) {
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
+            goto err;
+        }
+
+        if (!*pval && !ASN1_item_ex_new(pval, it)) {
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR);
+            goto err;
+        }
+
+        if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
+            goto auxerr;
+
+        /* Free up and zero any ADB found */
+        for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+            if (tt->flags & ASN1_TFLG_ADB_MASK) {
+                const ASN1_TEMPLATE *seqtt;
+                ASN1_VALUE **pseqval;
+                seqtt = asn1_do_adb(pval, tt, 0);
+                if (seqtt == NULL)
+                    continue;
+                pseqval = asn1_get_field_ptr(pval, seqtt);
+                asn1_template_free(pseqval, seqtt);
+            }
+        }
+
+        /* Get each field entry */
+        for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+            const ASN1_TEMPLATE *seqtt;
+            ASN1_VALUE **pseqval;
+            seqtt = asn1_do_adb(pval, tt, 1);
+            if (seqtt == NULL)
+                goto err;
+            pseqval = asn1_get_field_ptr(pval, seqtt);
+            /* Have we ran out of data? */
+            if (!len)
+                break;
+            q = p;
+            if (asn1_check_eoc(&p, len)) {
+                if (!seq_eoc) {
+                    ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_UNEXPECTED_EOC);
+                    goto err;
+                }
+                len -= p - q;
+                seq_eoc = 0;
+                q = p;
+                break;
+            }
+            /*
+             * This determines the OPTIONAL flag value. The field cannot be
+             * omitted if it is the last of a SEQUENCE and there is still
+             * data to be read. This isn't strictly necessary but it
+             * increases efficiency in some cases.
+             */
+            if (i == (it->tcount - 1))
+                isopt = 0;
+            else
+                isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL);
+            /*
+             * attempt to read in field, allowing each to be OPTIONAL
+             */
+
+            ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx,
+                                       depth);
+            if (!ret) {
+                errtt = seqtt;
+                goto err;
+            } else if (ret == -1) {
+                /*
+                 * OPTIONAL component absent. Free and zero the field.
+                 */
+                asn1_template_free(pseqval, seqtt);
+                continue;
+            }
+            /* Update length */
+            len -= p - q;
+        }
+
+        /* Check for EOC if expecting one */
+        if (seq_eoc && !asn1_check_eoc(&p, len)) {
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_MISSING_EOC);
+            goto err;
+        }
+        /* Check all data read */
+        if (!seq_nolen && len) {
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_SEQUENCE_LENGTH_MISMATCH);
+            goto err;
+        }
+
+        /*
+         * If we get here we've got no more data in the SEQUENCE, however we
+         * may not have read all fields so check all remaining are OPTIONAL
+         * and clear any that are.
+         */
+        for (; i < it->tcount; tt++, i++) {
+            const ASN1_TEMPLATE *seqtt;
+            seqtt = asn1_do_adb(pval, tt, 1);
+            if (seqtt == NULL)
+                goto err;
+            if (seqtt->flags & ASN1_TFLG_OPTIONAL) {
+                ASN1_VALUE **pseqval;
+                pseqval = asn1_get_field_ptr(pval, seqtt);
+                asn1_template_free(pseqval, seqtt);
+            } else {
+                errtt = seqtt;
+                ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_FIELD_MISSING);
+                goto err;
+            }
+        }
+        /* Save encoding */
+        if (!asn1_enc_save(pval, *in, p - *in, it))
+            goto auxerr;
+        if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
+            goto auxerr;
+        *in = p;
+        return 1;
+
+    default:
+        return 0;
+    }
+ auxerr:
+    ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_AUX_ERROR);
+ err:
+    if (errtt)
+        ERR_add_error_data(4, "Field=", errtt->field_name,
+                           ", Type=", it->sname);
+    else
+        ERR_add_error_data(2, "Type=", it->sname);
+    return 0;
+}
+
+/*
+ * Templates are handled with two separate functions. One handles any
+ * EXPLICIT tag and the other handles the rest.
+ */
+
+static int asn1_template_ex_d2i(ASN1_VALUE **val,
+                                const unsigned char **in, long inlen,
+                                const ASN1_TEMPLATE *tt, char opt,
+                                ASN1_TLC *ctx, int depth)
+{
+    int flags, aclass;
+    int ret;
+    long len;
+    const unsigned char *p, *q;
+    char exp_eoc;
+    if (!val)
+        return 0;
+    flags = tt->flags;
+    aclass = flags & ASN1_TFLG_TAG_CLASS;
+
+    p = *in;
+
+    /* Check if EXPLICIT tag expected */
+    if (flags & ASN1_TFLG_EXPTAG) {
+        char cst;
+        /*
+         * Need to work out amount of data available to the inner content and
+         * where it starts: so read in EXPLICIT header to get the info.
+         */
+        ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst,
+                              &p, inlen, tt->tag, aclass, opt, ctx);
+        q = p;
+        if (!ret) {
+            ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+            return 0;
+        } else if (ret == -1)
+            return -1;
+        if (!cst) {
+            ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
+                    ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
+            return 0;
+        }
+        /* We've found the field so it can't be OPTIONAL now */
+        ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx, depth);
+        if (!ret) {
+            ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+            return 0;
+        }
+        /* We read the field in OK so update length */
+        len -= p - q;
+        if (exp_eoc) {
+            /* If NDEF we must have an EOC here */
+            if (!asn1_check_eoc(&p, len)) {
+                ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ASN1_R_MISSING_EOC);
+                goto err;
+            }
+        } else {
+            /*
+             * Otherwise we must hit the EXPLICIT tag end or its an error
+             */
+            if (len) {
+                ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
+                        ASN1_R_EXPLICIT_LENGTH_MISMATCH);
+                goto err;
+            }
+        }
+    } else
+        return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx, depth);
+
+    *in = p;
+    return 1;
+
+ err:
+    return 0;
+}
+
+static int asn1_template_noexp_d2i(ASN1_VALUE **val,
+                                   const unsigned char **in, long len,
+                                   const ASN1_TEMPLATE *tt, char opt,
+                                   ASN1_TLC *ctx, int depth)
+{
+    int flags, aclass;
+    int ret;
+    ASN1_VALUE *tval;
+    const unsigned char *p, *q;
+    if (!val)
+        return 0;
+    flags = tt->flags;
+    aclass = flags & ASN1_TFLG_TAG_CLASS;
+
+    p = *in;
+    q = p;
+
+    /*
+     * If field is embedded then val needs fixing so it is a pointer to
+     * a pointer to a field.
+     */
+    if (tt->flags & ASN1_TFLG_EMBED) {
+        tval = (ASN1_VALUE *)val;
+        val = &tval;
+    }
+
+    if (flags & ASN1_TFLG_SK_MASK) {
+        /* SET OF, SEQUENCE OF */
+        int sktag, skaclass;
+        char sk_eoc;
+        /* First work out expected inner tag value */
+        if (flags & ASN1_TFLG_IMPTAG) {
+            sktag = tt->tag;
+            skaclass = aclass;
+        } else {
+            skaclass = V_ASN1_UNIVERSAL;
+            if (flags & ASN1_TFLG_SET_OF)
+                sktag = V_ASN1_SET;
+            else
+                sktag = V_ASN1_SEQUENCE;
+        }
+        /* Get the tag */
+        ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL,
+                              &p, len, sktag, skaclass, opt, ctx);
+        if (!ret) {
+            ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
+            return 0;
+        } else if (ret == -1)
+            return -1;
+        if (!*val)
+            *val = (ASN1_VALUE *)sk_ASN1_VALUE_new_null();
+        else {
+            /*
+             * We've got a valid STACK: free up any items present
+             */
+            STACK_OF(ASN1_VALUE) *sktmp = (STACK_OF(ASN1_VALUE) *)*val;
+            ASN1_VALUE *vtmp;
+            while (sk_ASN1_VALUE_num(sktmp) > 0) {
+                vtmp = sk_ASN1_VALUE_pop(sktmp);
+                ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item));
+            }
+        }
+
+        if (!*val) {
+            ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+
+        /* Read as many items as we can */
+        while (len > 0) {
+            ASN1_VALUE *skfield;
+            q = p;
+            /* See if EOC found */
+            if (asn1_check_eoc(&p, len)) {
+                if (!sk_eoc) {
+                    ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
+                            ASN1_R_UNEXPECTED_EOC);
+                    goto err;
+                }
+                len -= p - q;
+                sk_eoc = 0;
+                break;
+            }
+            skfield = NULL;
+            if (!asn1_item_embed_d2i(&skfield, &p, len,
+                                     ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx,
+                                     depth)) {
+                ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
+                        ERR_R_NESTED_ASN1_ERROR);
+                /* |skfield| may be partially allocated despite failure. */
+                ASN1_item_free(skfield, ASN1_ITEM_ptr(tt->item));
+                goto err;
+            }
+            len -= p - q;
+            if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) {
+                ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE);
+                ASN1_item_free(skfield, ASN1_ITEM_ptr(tt->item));
+                goto err;
+            }
+        }
+        if (sk_eoc) {
+            ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_EOC);
+            goto err;
+        }
+    } else if (flags & ASN1_TFLG_IMPTAG) {
+        /* IMPLICIT tagging */
+        ret = asn1_item_embed_d2i(val, &p, len,
+                                  ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt,
+                                  ctx, depth);
+        if (!ret) {
+            ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
+            goto err;
+        } else if (ret == -1)
+            return -1;
+    } else {
+        /* Nothing special */
+        ret = asn1_item_embed_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
+                                  -1, 0, opt, ctx, depth);
+        if (!ret) {
+            ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
+            goto err;
+        } else if (ret == -1)
+            return -1;
+    }
+
+    *in = p;
+    return 1;
+
+ err:
+    return 0;
+}
+
+static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
+                                 const unsigned char **in, long inlen,
+                                 const ASN1_ITEM *it,
+                                 int tag, int aclass, char opt, ASN1_TLC *ctx)
+{
+    int ret = 0, utype;
+    long plen;
+    char cst, inf, free_cont = 0;
+    const unsigned char *p;
+    BUF_MEM buf = { 0, NULL, 0, 0 };
+    const unsigned char *cont = NULL;
+    long len;
+    if (!pval) {
+        ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL);
+        return 0;               /* Should never happen */
+    }
+
+    if (it->itype == ASN1_ITYPE_MSTRING) {
+        utype = tag;
+        tag = -1;
+    } else
+        utype = it->utype;
+
+    if (utype == V_ASN1_ANY) {
+        /* If type is ANY need to figure out type from tag */
+        unsigned char oclass;
+        if (tag >= 0) {
+            ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_TAGGED_ANY);
+            return 0;
+        }
+        if (opt) {
+            ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
+                    ASN1_R_ILLEGAL_OPTIONAL_ANY);
+            return 0;
+        }
+        p = *in;
+        ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL,
+                              &p, inlen, -1, 0, 0, ctx);
+        if (!ret) {
+            ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
+            return 0;
+        }
+        if (oclass != V_ASN1_UNIVERSAL)
+            utype = V_ASN1_OTHER;
+    }
+    if (tag == -1) {
+        tag = utype;
+        aclass = V_ASN1_UNIVERSAL;
+    }
+    p = *in;
+    /* Check header */
+    ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst,
+                          &p, inlen, tag, aclass, opt, ctx);
+    if (!ret) {
+        ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
+        return 0;
+    } else if (ret == -1)
+        return -1;
+    ret = 0;
+    /* SEQUENCE, SET and "OTHER" are left in encoded form */
+    if ((utype == V_ASN1_SEQUENCE)
+        || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) {
+        /*
+         * Clear context cache for type OTHER because the auto clear when we
+         * have a exact match won't work
+         */
+        if (utype == V_ASN1_OTHER) {
+            asn1_tlc_clear(ctx);
+        }
+        /* SEQUENCE and SET must be constructed */
+        else if (!cst) {
+            ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
+                    ASN1_R_TYPE_NOT_CONSTRUCTED);
+            return 0;
+        }
+
+        cont = *in;
+        /* If indefinite length constructed find the real end */
+        if (inf) {
+            if (!asn1_find_end(&p, plen, inf))
+                goto err;
+            len = p - cont;
+        } else {
+            len = p - cont + plen;
+            p += plen;
+        }
+    } else if (cst) {
+        if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN
+            || utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER
+            || utype == V_ASN1_ENUMERATED) {
+            ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_TYPE_NOT_PRIMITIVE);
+            return 0;
+        }
+
+        /* Free any returned 'buf' content */
+        free_cont = 1;
+        /*
+         * Should really check the internal tags are correct but some things
+         * may get this wrong. The relevant specs say that constructed string
+         * types should be OCTET STRINGs internally irrespective of the type.
+         * So instead just check for UNIVERSAL class and ignore the tag.
+         */
+        if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0)) {
+            goto err;
+        }
+        len = buf.length;
+        /* Append a final null to string */
+        if (!BUF_MEM_grow_clean(&buf, len + 1)) {
+            ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        buf.data[len] = 0;
+        cont = (const unsigned char *)buf.data;
+    } else {
+        cont = p;
+        len = plen;
+        p += plen;
+    }
+
+    /* We now have content length and type: translate into a structure */
+    /* asn1_ex_c2i may reuse allocated buffer, and so sets free_cont to 0 */
+    if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it))
+        goto err;
+
+    *in = p;
+    ret = 1;
+ err:
+    if (free_cont)
+        OPENSSL_free(buf.data);
+    return ret;
+}
+
+/* Translate ASN1 content octets into a structure */
+
+static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+                       int utype, char *free_cont, const ASN1_ITEM *it)
+{
+    ASN1_VALUE **opval = NULL;
+    ASN1_STRING *stmp;
+    ASN1_TYPE *typ = NULL;
+    int ret = 0;
+    const ASN1_PRIMITIVE_FUNCS *pf;
+    ASN1_INTEGER **tint;
+    pf = it->funcs;
+
+    if (pf && pf->prim_c2i)
+        return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
+    /* If ANY type clear type and set pointer to internal value */
+    if (it->utype == V_ASN1_ANY) {
+        if (!*pval) {
+            typ = ASN1_TYPE_new();
+            if (typ == NULL)
+                goto err;
+            *pval = (ASN1_VALUE *)typ;
+        } else
+            typ = (ASN1_TYPE *)*pval;
+
+        if (utype != typ->type)
+            ASN1_TYPE_set(typ, utype, NULL);
+        opval = pval;
+        pval = &typ->value.asn1_value;
+    }
+    switch (utype) {
+    case V_ASN1_OBJECT:
+        if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len))
+            goto err;
+        break;
+
+    case V_ASN1_NULL:
+        if (len) {
+            ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_NULL_IS_WRONG_LENGTH);
+            goto err;
+        }
+        *pval = (ASN1_VALUE *)1;
+        break;
+
+    case V_ASN1_BOOLEAN:
+        if (len != 1) {
+            ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
+            goto err;
+        } else {
+            ASN1_BOOLEAN *tbool;
+            tbool = (ASN1_BOOLEAN *)pval;
+            *tbool = *cont;
+        }
+        break;
+
+    case V_ASN1_BIT_STRING:
+        if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len))
+            goto err;
+        break;
+
+    case V_ASN1_INTEGER:
+    case V_ASN1_ENUMERATED:
+        tint = (ASN1_INTEGER **)pval;
+        if (!c2i_ASN1_INTEGER(tint, &cont, len))
+            goto err;
+        /* Fixup type to match the expected form */
+        (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG);
+        break;
+
+    case V_ASN1_OCTET_STRING:
+    case V_ASN1_NUMERICSTRING:
+    case V_ASN1_PRINTABLESTRING:
+    case V_ASN1_T61STRING:
+    case V_ASN1_VIDEOTEXSTRING:
+    case V_ASN1_IA5STRING:
+    case V_ASN1_UTCTIME:
+    case V_ASN1_GENERALIZEDTIME:
+    case V_ASN1_GRAPHICSTRING:
+    case V_ASN1_VISIBLESTRING:
+    case V_ASN1_GENERALSTRING:
+    case V_ASN1_UNIVERSALSTRING:
+    case V_ASN1_BMPSTRING:
+    case V_ASN1_UTF8STRING:
+    case V_ASN1_OTHER:
+    case V_ASN1_SET:
+    case V_ASN1_SEQUENCE:
+    default:
+        if (utype == V_ASN1_BMPSTRING && (len & 1)) {
+            ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
+            goto err;
+        }
+        if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) {
+            ASN1err(ASN1_F_ASN1_EX_C2I,
+                    ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
+            goto err;
+        }
+        /* All based on ASN1_STRING and handled the same */
+        if (!*pval) {
+            stmp = ASN1_STRING_type_new(utype);
+            if (stmp == NULL) {
+                ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            *pval = (ASN1_VALUE *)stmp;
+        } else {
+            stmp = (ASN1_STRING *)*pval;
+            stmp->type = utype;
+        }
+        /* If we've already allocated a buffer use it */
+        if (*free_cont) {
+            OPENSSL_free(stmp->data);
+            stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */
+            stmp->length = len;
+            *free_cont = 0;
+        } else {
+            if (!ASN1_STRING_set(stmp, cont, len)) {
+                ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE);
+                ASN1_STRING_free(stmp);
+                *pval = NULL;
+                goto err;
+            }
+        }
+        break;
+    }
+    /* If ASN1_ANY and NULL type fix up value */
+    if (typ && (utype == V_ASN1_NULL))
+        typ->value.ptr = NULL;
+
+    ret = 1;
+ err:
+    if (!ret) {
+        ASN1_TYPE_free(typ);
+        if (opval)
+            *opval = NULL;
+    }
+    return ret;
+}
+
+/*
+ * This function finds the end of an ASN1 structure when passed its maximum
+ * length, whether it is indefinite length and a pointer to the content. This
+ * is more efficient than calling asn1_collect because it does not recurse on
+ * each indefinite length header.
+ */
+
+static int asn1_find_end(const unsigned char **in, long len, char inf)
+{
+    uint32_t expected_eoc;
+    long plen;
+    const unsigned char *p = *in, *q;
+    /* If not indefinite length constructed just add length */
+    if (inf == 0) {
+        *in += len;
+        return 1;
+    }
+    expected_eoc = 1;
+    /*
+     * Indefinite length constructed form. Find the end when enough EOCs are
+     * found. If more indefinite length constructed headers are encountered
+     * increment the expected eoc count otherwise just skip to the end of the
+     * data.
+     */
+    while (len > 0) {
+        if (asn1_check_eoc(&p, len)) {
+            expected_eoc--;
+            if (expected_eoc == 0)
+                break;
+            len -= 2;
+            continue;
+        }
+        q = p;
+        /* Just read in a header: only care about the length */
+        if (!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len,
+                             -1, 0, 0, NULL)) {
+            ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR);
+            return 0;
+        }
+        if (inf) {
+            if (expected_eoc == UINT32_MAX) {
+                ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR);
+                return 0;
+            }
+            expected_eoc++;
+        } else {
+            p += plen;
+        }
+        len -= p - q;
+    }
+    if (expected_eoc) {
+        ASN1err(ASN1_F_ASN1_FIND_END, ASN1_R_MISSING_EOC);
+        return 0;
+    }
+    *in = p;
+    return 1;
+}
+
+/*
+ * This function collects the asn1 data from a constructed string type into
+ * a buffer. The values of 'in' and 'len' should refer to the contents of the
+ * constructed type and 'inf' should be set if it is indefinite length.
+ */
+
+#ifndef ASN1_MAX_STRING_NEST
+/*
+ * This determines how many levels of recursion are permitted in ASN1 string
+ * types. If it is not limited stack overflows can occur. If set to zero no
+ * recursion is allowed at all. Although zero should be adequate examples
+ * exist that require a value of 1. So 5 should be more than enough.
+ */
+# define ASN1_MAX_STRING_NEST 5
+#endif
+
+static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
+                        char inf, int tag, int aclass, int depth)
+{
+    const unsigned char *p, *q;
+    long plen;
+    char cst, ininf;
+    p = *in;
+    inf &= 1;
+    /*
+     * If no buffer and not indefinite length constructed just pass over the
+     * encoded data
+     */
+    if (!buf && !inf) {
+        *in += len;
+        return 1;
+    }
+    while (len > 0) {
+        q = p;
+        /* Check for EOC */
+        if (asn1_check_eoc(&p, len)) {
+            /*
+             * EOC is illegal outside indefinite length constructed form
+             */
+            if (!inf) {
+                ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_UNEXPECTED_EOC);
+                return 0;
+            }
+            inf = 0;
+            break;
+        }
+
+        if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p,
+                             len, tag, aclass, 0, NULL)) {
+            ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR);
+            return 0;
+        }
+
+        /* If indefinite length constructed update max length */
+        if (cst) {
+            if (depth >= ASN1_MAX_STRING_NEST) {
+                ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_NESTED_ASN1_STRING);
+                return 0;
+            }
+            if (!asn1_collect(buf, &p, plen, ininf, tag, aclass, depth + 1))
+                return 0;
+        } else if (plen && !collect_data(buf, &p, plen))
+            return 0;
+        len -= p - q;
+    }
+    if (inf) {
+        ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC);
+        return 0;
+    }
+    *in = p;
+    return 1;
+}
+
+static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen)
+{
+    int len;
+    if (buf) {
+        len = buf->length;
+        if (!BUF_MEM_grow_clean(buf, len + plen)) {
+            ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        memcpy(buf->data + len, *p, plen);
+    }
+    *p += plen;
+    return 1;
+}
+
+/* Check for ASN1 EOC and swallow it if found */
+
+static int asn1_check_eoc(const unsigned char **in, long len)
+{
+    const unsigned char *p;
+    if (len < 2)
+        return 0;
+    p = *in;
+    if (!p[0] && !p[1]) {
+        *in += 2;
+        return 1;
+    }
+    return 0;
+}
+
+/*
+ * Check an ASN1 tag and length: a bit like ASN1_get_object but it sets the
+ * length for indefinite length constructed form, we don't know the exact
+ * length but we can set an upper bound to the amount of data available minus
+ * the header length just read.
+ */
+
+static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
+                           char *inf, char *cst,
+                           const unsigned char **in, long len,
+                           int exptag, int expclass, char opt, ASN1_TLC *ctx)
+{
+    int i;
+    int ptag, pclass;
+    long plen;
+    const unsigned char *p, *q;
+    p = *in;
+    q = p;
+
+    if (ctx && ctx->valid) {
+        i = ctx->ret;
+        plen = ctx->plen;
+        pclass = ctx->pclass;
+        ptag = ctx->ptag;
+        p += ctx->hdrlen;
+    } else {
+        i = ASN1_get_object(&p, &plen, &ptag, &pclass, len);
+        if (ctx) {
+            ctx->ret = i;
+            ctx->plen = plen;
+            ctx->pclass = pclass;
+            ctx->ptag = ptag;
+            ctx->hdrlen = p - q;
+            ctx->valid = 1;
+            /*
+             * If definite length, and no error, length + header can't exceed
+             * total amount of data available.
+             */
+            if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) {
+                ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG);
+                asn1_tlc_clear(ctx);
+                return 0;
+            }
+        }
+    }
+
+    if (i & 0x80) {
+        ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER);
+        asn1_tlc_clear(ctx);
+        return 0;
+    }
+    if (exptag >= 0) {
+        if ((exptag != ptag) || (expclass != pclass)) {
+            /*
+             * If type is OPTIONAL, not an error: indicate missing type.
+             */
+            if (opt)
+                return -1;
+            asn1_tlc_clear(ctx);
+            ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG);
+            return 0;
+        }
+        /*
+         * We have a tag and class match: assume we are going to do something
+         * with it
+         */
+        asn1_tlc_clear(ctx);
+    }
+
+    if (i & 1)
+        plen = len - (p - q);
+
+    if (inf)
+        *inf = i & 1;
+
+    if (cst)
+        *cst = i & V_ASN1_CONSTRUCTED;
+
+    if (olen)
+        *olen = plen;
+
+    if (oclass)
+        *oclass = pclass;
+
+    if (otag)
+        *otag = ptag;
+
+    *in = p;
+    return 1;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_enc.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_enc.c
new file mode 100644
index 0000000..bcc9633
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_enc.c
@@ -0,0 +1,625 @@
+/*
+ * Copyright 2000-2020 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stddef.h>
+#include <string.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+#include "crypto/asn1.h"
+#include "asn1_local.h"
+
+static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
+                                 const ASN1_ITEM *it, int tag, int aclass);
+static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
+                            int skcontlen, const ASN1_ITEM *item,
+                            int do_sort, int iclass);
+static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+                                const ASN1_TEMPLATE *tt, int tag, int aclass);
+static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
+                               const ASN1_ITEM *it, int flags);
+static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
+                       const ASN1_ITEM *it);
+
+/*
+ * Top level i2d equivalents: the 'ndef' variant instructs the encoder to use
+ * indefinite length constructed encoding, where appropriate
+ */
+
+int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out,
+                       const ASN1_ITEM *it)
+{
+    return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF);
+}
+
+int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
+{
+    return asn1_item_flags_i2d(val, out, it, 0);
+}
+
+/*
+ * Encode an ASN1 item, this is use by the standard 'i2d' function. 'out'
+ * points to a buffer to output the data to. The new i2d has one additional
+ * feature. If the output buffer is NULL (i.e. *out == NULL) then a buffer is
+ * allocated and populated with the encoding.
+ */
+
+static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
+                               const ASN1_ITEM *it, int flags)
+{
+    if (out && !*out) {
+        unsigned char *p, *buf;
+        int len;
+
+        len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
+        if (len <= 0)
+            return len;
+        if ((buf = OPENSSL_malloc(len)) == NULL) {
+            ASN1err(ASN1_F_ASN1_ITEM_FLAGS_I2D, ERR_R_MALLOC_FAILURE);
+            return -1;
+        }
+        p = buf;
+        ASN1_item_ex_i2d(&val, &p, it, -1, flags);
+        *out = buf;
+        return len;
+    }
+
+    return ASN1_item_ex_i2d(&val, out, it, -1, flags);
+}
+
+/*
+ * Encode an item, taking care of IMPLICIT tagging (if any). This function
+ * performs the normal item handling: it can be used in external types.
+ */
+
+int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+                     const ASN1_ITEM *it, int tag, int aclass)
+{
+    const ASN1_TEMPLATE *tt = NULL;
+    int i, seqcontlen, seqlen, ndef = 1;
+    const ASN1_EXTERN_FUNCS *ef;
+    const ASN1_AUX *aux = it->funcs;
+    ASN1_aux_cb *asn1_cb = 0;
+
+    if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
+        return 0;
+
+    if (aux && aux->asn1_cb)
+        asn1_cb = aux->asn1_cb;
+
+    switch (it->itype) {
+
+    case ASN1_ITYPE_PRIMITIVE:
+        if (it->templates)
+            return asn1_template_ex_i2d(pval, out, it->templates,
+                                        tag, aclass);
+        return asn1_i2d_ex_primitive(pval, out, it, tag, aclass);
+
+    case ASN1_ITYPE_MSTRING:
+        /*
+         * It never makes sense for multi-strings to have implicit tagging, so
+         * if tag != -1, then this looks like an error in the template.
+         */
+        if (tag != -1) {
+            ASN1err(ASN1_F_ASN1_ITEM_EX_I2D, ASN1_R_BAD_TEMPLATE);
+            return -1;
+        }
+        return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
+
+    case ASN1_ITYPE_CHOICE:
+        /*
+         * It never makes sense for CHOICE types to have implicit tagging, so
+         * if tag != -1, then this looks like an error in the template.
+         */
+        if (tag != -1) {
+            ASN1err(ASN1_F_ASN1_ITEM_EX_I2D, ASN1_R_BAD_TEMPLATE);
+            return -1;
+        }
+        if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
+            return 0;
+        i = asn1_get_choice_selector(pval, it);
+        if ((i >= 0) && (i < it->tcount)) {
+            ASN1_VALUE **pchval;
+            const ASN1_TEMPLATE *chtt;
+            chtt = it->templates + i;
+            pchval = asn1_get_field_ptr(pval, chtt);
+            return asn1_template_ex_i2d(pchval, out, chtt, -1, aclass);
+        }
+        /* Fixme: error condition if selector out of range */
+        if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
+            return 0;
+        break;
+
+    case ASN1_ITYPE_EXTERN:
+        /* If new style i2d it does all the work */
+        ef = it->funcs;
+        return ef->asn1_ex_i2d(pval, out, it, tag, aclass);
+
+    case ASN1_ITYPE_NDEF_SEQUENCE:
+        /* Use indefinite length constructed if requested */
+        if (aclass & ASN1_TFLG_NDEF)
+            ndef = 2;
+        /* fall through */
+
+    case ASN1_ITYPE_SEQUENCE:
+        i = asn1_enc_restore(&seqcontlen, out, pval, it);
+        /* An error occurred */
+        if (i < 0)
+            return 0;
+        /* We have a valid cached encoding... */
+        if (i > 0)
+            return seqcontlen;
+        /* Otherwise carry on */
+        seqcontlen = 0;
+        /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
+        if (tag == -1) {
+            tag = V_ASN1_SEQUENCE;
+            /* Retain any other flags in aclass */
+            aclass = (aclass & ~ASN1_TFLG_TAG_CLASS)
+                | V_ASN1_UNIVERSAL;
+        }
+        if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
+            return 0;
+        /* First work out sequence content length */
+        for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
+            const ASN1_TEMPLATE *seqtt;
+            ASN1_VALUE **pseqval;
+            int tmplen;
+            seqtt = asn1_do_adb(pval, tt, 1);
+            if (!seqtt)
+                return 0;
+            pseqval = asn1_get_field_ptr(pval, seqtt);
+            tmplen = asn1_template_ex_i2d(pseqval, NULL, seqtt, -1, aclass);
+            if (tmplen == -1 || (tmplen > INT_MAX - seqcontlen))
+                return -1;
+            seqcontlen += tmplen;
+        }
+
+        seqlen = ASN1_object_size(ndef, seqcontlen, tag);
+        if (!out || seqlen == -1)
+            return seqlen;
+        /* Output SEQUENCE header */
+        ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
+        for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
+            const ASN1_TEMPLATE *seqtt;
+            ASN1_VALUE **pseqval;
+            seqtt = asn1_do_adb(pval, tt, 1);
+            if (!seqtt)
+                return 0;
+            pseqval = asn1_get_field_ptr(pval, seqtt);
+            /* FIXME: check for errors in enhanced version */
+            asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass);
+        }
+        if (ndef == 2)
+            ASN1_put_eoc(out);
+        if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
+            return 0;
+        return seqlen;
+
+    default:
+        return 0;
+
+    }
+    return 0;
+}
+
+static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+                                const ASN1_TEMPLATE *tt, int tag, int iclass)
+{
+    int i, ret, flags, ttag, tclass, ndef;
+    ASN1_VALUE *tval;
+    flags = tt->flags;
+
+    /*
+     * If field is embedded then val needs fixing so it is a pointer to
+     * a pointer to a field.
+     */
+    if (flags & ASN1_TFLG_EMBED) {
+        tval = (ASN1_VALUE *)pval;
+        pval = &tval;
+    }
+    /*
+     * Work out tag and class to use: tagging may come either from the
+     * template or the arguments, not both because this would create
+     * ambiguity. Additionally the iclass argument may contain some
+     * additional flags which should be noted and passed down to other
+     * levels.
+     */
+    if (flags & ASN1_TFLG_TAG_MASK) {
+        /* Error if argument and template tagging */
+        if (tag != -1)
+            /* FIXME: error code here */
+            return -1;
+        /* Get tagging from template */
+        ttag = tt->tag;
+        tclass = flags & ASN1_TFLG_TAG_CLASS;
+    } else if (tag != -1) {
+        /* No template tagging, get from arguments */
+        ttag = tag;
+        tclass = iclass & ASN1_TFLG_TAG_CLASS;
+    } else {
+        ttag = -1;
+        tclass = 0;
+    }
+    /*
+     * Remove any class mask from iflag.
+     */
+    iclass &= ~ASN1_TFLG_TAG_CLASS;
+
+    /*
+     * At this point 'ttag' contains the outer tag to use, 'tclass' is the
+     * class and iclass is any flags passed to this function.
+     */
+
+    /* if template and arguments require ndef, use it */
+    if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF))
+        ndef = 2;
+    else
+        ndef = 1;
+
+    if (flags & ASN1_TFLG_SK_MASK) {
+        /* SET OF, SEQUENCE OF */
+        STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
+        int isset, sktag, skaclass;
+        int skcontlen, sklen;
+        ASN1_VALUE *skitem;
+
+        if (!*pval)
+            return 0;
+
+        if (flags & ASN1_TFLG_SET_OF) {
+            isset = 1;
+            /* 2 means we reorder */
+            if (flags & ASN1_TFLG_SEQUENCE_OF)
+                isset = 2;
+        } else
+            isset = 0;
+
+        /*
+         * Work out inner tag value: if EXPLICIT or no tagging use underlying
+         * type.
+         */
+        if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) {
+            sktag = ttag;
+            skaclass = tclass;
+        } else {
+            skaclass = V_ASN1_UNIVERSAL;
+            if (isset)
+                sktag = V_ASN1_SET;
+            else
+                sktag = V_ASN1_SEQUENCE;
+        }
+
+        /* Determine total length of items */
+        skcontlen = 0;
+        for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
+            int tmplen;
+            skitem = sk_ASN1_VALUE_value(sk, i);
+            tmplen = ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item),
+                                      -1, iclass);
+            if (tmplen == -1 || (skcontlen > INT_MAX - tmplen))
+                return -1;
+            skcontlen += tmplen;
+        }
+        sklen = ASN1_object_size(ndef, skcontlen, sktag);
+        if (sklen == -1)
+            return -1;
+        /* If EXPLICIT need length of surrounding tag */
+        if (flags & ASN1_TFLG_EXPTAG)
+            ret = ASN1_object_size(ndef, sklen, ttag);
+        else
+            ret = sklen;
+
+        if (!out || ret == -1)
+            return ret;
+
+        /* Now encode this lot... */
+        /* EXPLICIT tag */
+        if (flags & ASN1_TFLG_EXPTAG)
+            ASN1_put_object(out, ndef, sklen, ttag, tclass);
+        /* SET or SEQUENCE and IMPLICIT tag */
+        ASN1_put_object(out, ndef, skcontlen, sktag, skaclass);
+        /* And the stuff itself */
+        asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item),
+                         isset, iclass);
+        if (ndef == 2) {
+            ASN1_put_eoc(out);
+            if (flags & ASN1_TFLG_EXPTAG)
+                ASN1_put_eoc(out);
+        }
+
+        return ret;
+    }
+
+    if (flags & ASN1_TFLG_EXPTAG) {
+        /* EXPLICIT tagging */
+        /* Find length of tagged item */
+        i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, iclass);
+        if (!i)
+            return 0;
+        /* Find length of EXPLICIT tag */
+        ret = ASN1_object_size(ndef, i, ttag);
+        if (out && ret != -1) {
+            /* Output tag and item */
+            ASN1_put_object(out, ndef, i, ttag, tclass);
+            ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, iclass);
+            if (ndef == 2)
+                ASN1_put_eoc(out);
+        }
+        return ret;
+    }
+
+    /* Either normal or IMPLICIT tagging: combine class and flags */
+    return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
+                            ttag, tclass | iclass);
+
+}
+
+/* Temporary structure used to hold DER encoding of items for SET OF */
+
+typedef struct {
+    unsigned char *data;
+    int length;
+    ASN1_VALUE *field;
+} DER_ENC;
+
+static int der_cmp(const void *a, const void *b)
+{
+    const DER_ENC *d1 = a, *d2 = b;
+    int cmplen, i;
+    cmplen = (d1->length < d2->length) ? d1->length : d2->length;
+    i = memcmp(d1->data, d2->data, cmplen);
+    if (i)
+        return i;
+    return d1->length - d2->length;
+}
+
+/* Output the content octets of SET OF or SEQUENCE OF */
+
+static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
+                            int skcontlen, const ASN1_ITEM *item,
+                            int do_sort, int iclass)
+{
+    int i;
+    ASN1_VALUE *skitem;
+    unsigned char *tmpdat = NULL, *p = NULL;
+    DER_ENC *derlst = NULL, *tder;
+    if (do_sort) {
+        /* Don't need to sort less than 2 items */
+        if (sk_ASN1_VALUE_num(sk) < 2)
+            do_sort = 0;
+        else {
+            derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk)
+                                    * sizeof(*derlst));
+            if (derlst == NULL)
+                return 0;
+            tmpdat = OPENSSL_malloc(skcontlen);
+            if (tmpdat == NULL) {
+                OPENSSL_free(derlst);
+                return 0;
+            }
+        }
+    }
+    /* If not sorting just output each item */
+    if (!do_sort) {
+        for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
+            skitem = sk_ASN1_VALUE_value(sk, i);
+            ASN1_item_ex_i2d(&skitem, out, item, -1, iclass);
+        }
+        return 1;
+    }
+    p = tmpdat;
+
+    /* Doing sort: build up a list of each member's DER encoding */
+    for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
+        skitem = sk_ASN1_VALUE_value(sk, i);
+        tder->data = p;
+        tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass);
+        tder->field = skitem;
+    }
+
+    /* Now sort them */
+    qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp);
+    /* Output sorted DER encoding */
+    p = *out;
+    for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
+        memcpy(p, tder->data, tder->length);
+        p += tder->length;
+    }
+    *out = p;
+    /* If do_sort is 2 then reorder the STACK */
+    if (do_sort == 2) {
+        for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
+            (void)sk_ASN1_VALUE_set(sk, i, tder->field);
+    }
+    OPENSSL_free(derlst);
+    OPENSSL_free(tmpdat);
+    return 1;
+}
+
+static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
+                                 const ASN1_ITEM *it, int tag, int aclass)
+{
+    int len;
+    int utype;
+    int usetag;
+    int ndef = 0;
+
+    utype = it->utype;
+
+    /*
+     * Get length of content octets and maybe find out the underlying type.
+     */
+
+    len = asn1_ex_i2c(pval, NULL, &utype, it);
+
+    /*
+     * If SEQUENCE, SET or OTHER then header is included in pseudo content
+     * octets so don't include tag+length. We need to check here because the
+     * call to asn1_ex_i2c() could change utype.
+     */
+    if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) ||
+        (utype == V_ASN1_OTHER))
+        usetag = 0;
+    else
+        usetag = 1;
+
+    /* -1 means omit type */
+
+    if (len == -1)
+        return 0;
+
+    /* -2 return is special meaning use ndef */
+    if (len == -2) {
+        ndef = 2;
+        len = 0;
+    }
+
+    /* If not implicitly tagged get tag from underlying type */
+    if (tag == -1)
+        tag = utype;
+
+    /* Output tag+length followed by content octets */
+    if (out) {
+        if (usetag)
+            ASN1_put_object(out, ndef, len, tag, aclass);
+        asn1_ex_i2c(pval, *out, &utype, it);
+        if (ndef)
+            ASN1_put_eoc(out);
+        else
+            *out += len;
+    }
+
+    if (usetag)
+        return ASN1_object_size(ndef, len, tag);
+    return len;
+}
+
+/* Produce content octets from a structure */
+
+static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
+                       const ASN1_ITEM *it)
+{
+    ASN1_BOOLEAN *tbool = NULL;
+    ASN1_STRING *strtmp;
+    ASN1_OBJECT *otmp;
+    int utype;
+    const unsigned char *cont;
+    unsigned char c;
+    int len;
+    const ASN1_PRIMITIVE_FUNCS *pf;
+    pf = it->funcs;
+    if (pf && pf->prim_i2c)
+        return pf->prim_i2c(pval, cout, putype, it);
+
+    /* Should type be omitted? */
+    if ((it->itype != ASN1_ITYPE_PRIMITIVE)
+        || (it->utype != V_ASN1_BOOLEAN)) {
+        if (!*pval)
+            return -1;
+    }
+
+    if (it->itype == ASN1_ITYPE_MSTRING) {
+        /* If MSTRING type set the underlying type */
+        strtmp = (ASN1_STRING *)*pval;
+        utype = strtmp->type;
+        *putype = utype;
+    } else if (it->utype == V_ASN1_ANY) {
+        /* If ANY set type and pointer to value */
+        ASN1_TYPE *typ;
+        typ = (ASN1_TYPE *)*pval;
+        utype = typ->type;
+        *putype = utype;
+        pval = &typ->value.asn1_value;
+    } else
+        utype = *putype;
+
+    switch (utype) {
+    case V_ASN1_OBJECT:
+        otmp = (ASN1_OBJECT *)*pval;
+        cont = otmp->data;
+        len = otmp->length;
+        if (cont == NULL || len == 0)
+            return -1;
+        break;
+
+    case V_ASN1_NULL:
+        cont = NULL;
+        len = 0;
+        break;
+
+    case V_ASN1_BOOLEAN:
+        tbool = (ASN1_BOOLEAN *)pval;
+        if (*tbool == -1)
+            return -1;
+        if (it->utype != V_ASN1_ANY) {
+            /*
+             * Default handling if value == size field then omit
+             */
+            if (*tbool && (it->size > 0))
+                return -1;
+            if (!*tbool && !it->size)
+                return -1;
+        }
+        c = (unsigned char)*tbool;
+        cont = &c;
+        len = 1;
+        break;
+
+    case V_ASN1_BIT_STRING:
+        return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval,
+                                   cout ? &cout : NULL);
+
+    case V_ASN1_INTEGER:
+    case V_ASN1_ENUMERATED:
+        /*
+         * These are all have the same content format as ASN1_INTEGER
+         */
+        return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL);
+
+    case V_ASN1_OCTET_STRING:
+    case V_ASN1_NUMERICSTRING:
+    case V_ASN1_PRINTABLESTRING:
+    case V_ASN1_T61STRING:
+    case V_ASN1_VIDEOTEXSTRING:
+    case V_ASN1_IA5STRING:
+    case V_ASN1_UTCTIME:
+    case V_ASN1_GENERALIZEDTIME:
+    case V_ASN1_GRAPHICSTRING:
+    case V_ASN1_VISIBLESTRING:
+    case V_ASN1_GENERALSTRING:
+    case V_ASN1_UNIVERSALSTRING:
+    case V_ASN1_BMPSTRING:
+    case V_ASN1_UTF8STRING:
+    case V_ASN1_SEQUENCE:
+    case V_ASN1_SET:
+    default:
+        /* All based on ASN1_STRING and handled the same */
+        strtmp = (ASN1_STRING *)*pval;
+        /* Special handling for NDEF */
+        if ((it->size == ASN1_TFLG_NDEF)
+            && (strtmp->flags & ASN1_STRING_FLAG_NDEF)) {
+            if (cout) {
+                strtmp->data = cout;
+                strtmp->length = 0;
+            }
+            /* Special return code */
+            return -2;
+        }
+        cont = strtmp->data;
+        len = strtmp->length;
+
+        break;
+
+    }
+    if (cout && len)
+        memcpy(cout, cont, len);
+    return len;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_fre.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_fre.c
new file mode 100644
index 0000000..2916bef
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_fre.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2000-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stddef.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+#include "asn1_local.h"
+
+/* Free up an ASN1 structure */
+
+void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it)
+{
+    asn1_item_embed_free(&val, it, 0);
+}
+
+void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    asn1_item_embed_free(pval, it, 0);
+}
+
+void asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
+{
+    const ASN1_TEMPLATE *tt = NULL, *seqtt;
+    const ASN1_EXTERN_FUNCS *ef;
+    const ASN1_AUX *aux = it->funcs;
+    ASN1_aux_cb *asn1_cb;
+    int i;
+
+    if (!pval)
+        return;
+    if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
+        return;
+    if (aux && aux->asn1_cb)
+        asn1_cb = aux->asn1_cb;
+    else
+        asn1_cb = 0;
+
+    switch (it->itype) {
+
+    case ASN1_ITYPE_PRIMITIVE:
+        if (it->templates)
+            asn1_template_free(pval, it->templates);
+        else
+            asn1_primitive_free(pval, it, embed);
+        break;
+
+    case ASN1_ITYPE_MSTRING:
+        asn1_primitive_free(pval, it, embed);
+        break;
+
+    case ASN1_ITYPE_CHOICE:
+        if (asn1_cb) {
+            i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
+            if (i == 2)
+                return;
+        }
+        i = asn1_get_choice_selector(pval, it);
+        if ((i >= 0) && (i < it->tcount)) {
+            ASN1_VALUE **pchval;
+
+            tt = it->templates + i;
+            pchval = asn1_get_field_ptr(pval, tt);
+            asn1_template_free(pchval, tt);
+        }
+        if (asn1_cb)
+            asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
+        if (embed == 0) {
+            OPENSSL_free(*pval);
+            *pval = NULL;
+        }
+        break;
+
+    case ASN1_ITYPE_EXTERN:
+        ef = it->funcs;
+        if (ef && ef->asn1_ex_free)
+            ef->asn1_ex_free(pval, it);
+        break;
+
+    case ASN1_ITYPE_NDEF_SEQUENCE:
+    case ASN1_ITYPE_SEQUENCE:
+        if (asn1_do_lock(pval, -1, it) != 0) /* if error or ref-counter > 0 */
+            return;
+        if (asn1_cb) {
+            i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
+            if (i == 2)
+                return;
+        }
+        asn1_enc_free(pval, it);
+        /*
+         * If we free up as normal we will invalidate any ANY DEFINED BY
+         * field and we won't be able to determine the type of the field it
+         * defines. So free up in reverse order.
+         */
+        tt = it->templates + it->tcount;
+        for (i = 0; i < it->tcount; i++) {
+            ASN1_VALUE **pseqval;
+
+            tt--;
+            seqtt = asn1_do_adb(pval, tt, 0);
+            if (!seqtt)
+                continue;
+            pseqval = asn1_get_field_ptr(pval, seqtt);
+            asn1_template_free(pseqval, seqtt);
+        }
+        if (asn1_cb)
+            asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
+        if (embed == 0) {
+            OPENSSL_free(*pval);
+            *pval = NULL;
+        }
+        break;
+    }
+}
+
+void asn1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
+{
+    int embed = tt->flags & ASN1_TFLG_EMBED;
+    ASN1_VALUE *tval;
+    if (embed) {
+        tval = (ASN1_VALUE *)pval;
+        pval = &tval;
+    }
+    if (tt->flags & ASN1_TFLG_SK_MASK) {
+        STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
+        int i;
+
+        for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
+            ASN1_VALUE *vtmp = sk_ASN1_VALUE_value(sk, i);
+
+            asn1_item_embed_free(&vtmp, ASN1_ITEM_ptr(tt->item), embed);
+        }
+        sk_ASN1_VALUE_free(sk);
+        *pval = NULL;
+    } else {
+        asn1_item_embed_free(pval, ASN1_ITEM_ptr(tt->item), embed);
+    }
+}
+
+void asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
+{
+    int utype;
+
+    /* Special case: if 'it' is a primitive with a free_func, use that. */
+    if (it) {
+        const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
+
+        if (embed) {
+            if (pf && pf->prim_clear) {
+                pf->prim_clear(pval, it);
+                return;
+            }
+        } else if (pf && pf->prim_free) {
+            pf->prim_free(pval, it);
+            return;
+        }
+    }
+
+    /* Special case: if 'it' is NULL, free contents of ASN1_TYPE */
+    if (!it) {
+        ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
+
+        utype = typ->type;
+        pval = &typ->value.asn1_value;
+        if (!*pval)
+            return;
+    } else if (it->itype == ASN1_ITYPE_MSTRING) {
+        utype = -1;
+        if (!*pval)
+            return;
+    } else {
+        utype = it->utype;
+        if ((utype != V_ASN1_BOOLEAN) && !*pval)
+            return;
+    }
+
+    switch (utype) {
+    case V_ASN1_OBJECT:
+        ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
+        break;
+
+    case V_ASN1_BOOLEAN:
+        if (it)
+            *(ASN1_BOOLEAN *)pval = it->size;
+        else
+            *(ASN1_BOOLEAN *)pval = -1;
+        return;
+
+    case V_ASN1_NULL:
+        break;
+
+    case V_ASN1_ANY:
+        asn1_primitive_free(pval, NULL, 0);
+        OPENSSL_free(*pval);
+        break;
+
+    default:
+        asn1_string_embed_free((ASN1_STRING *)*pval, embed);
+        break;
+    }
+    *pval = NULL;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_new.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_new.c
new file mode 100644
index 0000000..287f2af
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_new.c
@@ -0,0 +1,349 @@
+/*
+ * Copyright 2000-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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stddef.h>
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/err.h>
+#include <openssl/asn1t.h>
+#include <string.h>
+#include "asn1_local.h"
+
+static int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
+                               int embed);
+static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
+                              int embed);
+static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
+static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
+{
+    ASN1_VALUE *ret = NULL;
+    if (ASN1_item_ex_new(&ret, it) > 0)
+        return ret;
+    return NULL;
+}
+
+/* Allocate an ASN1 structure */
+
+int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    return asn1_item_embed_new(pval, it, 0);
+}
+
+int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
+{
+    const ASN1_TEMPLATE *tt = NULL;
+    const ASN1_EXTERN_FUNCS *ef;
+    const ASN1_AUX *aux = it->funcs;
+    ASN1_aux_cb *asn1_cb;
+    ASN1_VALUE **pseqval;
+    int i;
+    if (aux && aux->asn1_cb)
+        asn1_cb = aux->asn1_cb;
+    else
+        asn1_cb = 0;
+
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+    OPENSSL_mem_debug_push(it->sname ? it->sname : "asn1_item_embed_new");
+#endif
+
+    switch (it->itype) {
+
+    case ASN1_ITYPE_EXTERN:
+        ef = it->funcs;
+        if (ef && ef->asn1_ex_new) {
+            if (!ef->asn1_ex_new(pval, it))
+                goto memerr;
+        }
+        break;
+
+    case ASN1_ITYPE_PRIMITIVE:
+        if (it->templates) {
+            if (!asn1_template_new(pval, it->templates))
+                goto memerr;
+        } else if (!asn1_primitive_new(pval, it, embed))
+            goto memerr;
+        break;
+
+    case ASN1_ITYPE_MSTRING:
+        if (!asn1_primitive_new(pval, it, embed))
+            goto memerr;
+        break;
+
+    case ASN1_ITYPE_CHOICE:
+        if (asn1_cb) {
+            i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
+            if (!i)
+                goto auxerr;
+            if (i == 2) {
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+                OPENSSL_mem_debug_pop();
+#endif
+                return 1;
+            }
+        }
+        if (embed) {
+            memset(*pval, 0, it->size);
+        } else {
+            *pval = OPENSSL_zalloc(it->size);
+            if (*pval == NULL)
+                goto memerr;
+        }
+        asn1_set_choice_selector(pval, -1, it);
+        if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
+            goto auxerr2;
+        break;
+
+    case ASN1_ITYPE_NDEF_SEQUENCE:
+    case ASN1_ITYPE_SEQUENCE:
+        if (asn1_cb) {
+            i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
+            if (!i)
+                goto auxerr;
+            if (i == 2) {
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+                OPENSSL_mem_debug_pop();
+#endif
+                return 1;
+            }
+        }
+        if (embed) {
+            memset(*pval, 0, it->size);
+        } else {
+            *pval = OPENSSL_zalloc(it->size);
+            if (*pval == NULL)
+                goto memerr;
+        }
+        /* 0 : init. lock */
+        if (asn1_do_lock(pval, 0, it) < 0) {
+            if (!embed) {
+                OPENSSL_free(*pval);
+                *pval = NULL;
+            }
+            goto memerr;
+        }
+        asn1_enc_init(pval, it);
+        for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
+            pseqval = asn1_get_field_ptr(pval, tt);
+            if (!asn1_template_new(pseqval, tt))
+                goto memerr2;
+        }
+        if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
+            goto auxerr2;
+        break;
+    }
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+    OPENSSL_mem_debug_pop();
+#endif
+    return 1;
+
+ memerr2:
+    asn1_item_embed_free(pval, it, embed);
+ memerr:
+    ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ERR_R_MALLOC_FAILURE);
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+    OPENSSL_mem_debug_pop();
+#endif
+    return 0;
+
+ auxerr2:
+    asn1_item_embed_free(pval, it, embed);
+ auxerr:
+    ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ASN1_R_AUX_ERROR);
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+    OPENSSL_mem_debug_pop();
+#endif
+    return 0;
+
+}
+
+static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    const ASN1_EXTERN_FUNCS *ef;
+
+    switch (it->itype) {
+
+    case ASN1_ITYPE_EXTERN:
+        ef = it->funcs;
+        if (ef && ef->asn1_ex_clear)
+            ef->asn1_ex_clear(pval, it);
+        else
+            *pval = NULL;
+        break;
+
+    case ASN1_ITYPE_PRIMITIVE:
+        if (it->templates)
+            asn1_template_clear(pval, it->templates);
+        else
+            asn1_primitive_clear(pval, it);
+        break;
+
+    case ASN1_ITYPE_MSTRING:
+        asn1_primitive_clear(pval, it);
+        break;
+
+    case ASN1_ITYPE_CHOICE:
+    case ASN1_ITYPE_SEQUENCE:
+    case ASN1_ITYPE_NDEF_SEQUENCE:
+        *pval = NULL;
+        break;
+    }
+}
+
+static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
+{
+    const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
+    int embed = tt->flags & ASN1_TFLG_EMBED;
+    ASN1_VALUE *tval;
+    int ret;
+    if (embed) {
+        tval = (ASN1_VALUE *)pval;
+        pval = &tval;
+    }
+    if (tt->flags & ASN1_TFLG_OPTIONAL) {
+        asn1_template_clear(pval, tt);
+        return 1;
+    }
+    /* If ANY DEFINED BY nothing to do */
+
+    if (tt->flags & ASN1_TFLG_ADB_MASK) {
+        *pval = NULL;
+        return 1;
+    }
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+    OPENSSL_mem_debug_push(tt->field_name
+            ? tt->field_name : "asn1_template_new");
+#endif
+    /* If SET OF or SEQUENCE OF, its a STACK */
+    if (tt->flags & ASN1_TFLG_SK_MASK) {
+        STACK_OF(ASN1_VALUE) *skval;
+        skval = sk_ASN1_VALUE_new_null();
+        if (!skval) {
+            ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE);
+            ret = 0;
+            goto done;
+        }
+        *pval = (ASN1_VALUE *)skval;
+        ret = 1;
+        goto done;
+    }
+    /* Otherwise pass it back to the item routine */
+    ret = asn1_item_embed_new(pval, it, embed);
+ done:
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+    OPENSSL_mem_debug_pop();
+#endif
+    return ret;
+}
+
+static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
+{
+    /* If ADB or STACK just NULL the field */
+    if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK))
+        *pval = NULL;
+    else
+        asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
+}
+
+/*
+ * NB: could probably combine most of the real XXX_new() behaviour and junk
+ * all the old functions.
+ */
+
+static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
+                              int embed)
+{
+    ASN1_TYPE *typ;
+    ASN1_STRING *str;
+    int utype;
+
+    if (!it)
+        return 0;
+
+    if (it->funcs) {
+        const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
+        if (embed) {
+            if (pf->prim_clear) {
+                pf->prim_clear(pval, it);
+                return 1;
+            }
+        } else if (pf->prim_new) {
+            return pf->prim_new(pval, it);
+        }
+    }
+
+    if (it->itype == ASN1_ITYPE_MSTRING)
+        utype = -1;
+    else
+        utype = it->utype;
+    switch (utype) {
+    case V_ASN1_OBJECT:
+        *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
+        return 1;
+
+    case V_ASN1_BOOLEAN:
+        *(ASN1_BOOLEAN *)pval = it->size;
+        return 1;
+
+    case V_ASN1_NULL:
+        *pval = (ASN1_VALUE *)1;
+        return 1;
+
+    case V_ASN1_ANY:
+        if ((typ = OPENSSL_malloc(sizeof(*typ))) == NULL) {
+            ASN1err(ASN1_F_ASN1_PRIMITIVE_NEW, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        typ->value.ptr = NULL;
+        typ->type = -1;
+        *pval = (ASN1_VALUE *)typ;
+        break;
+
+    default:
+        if (embed) {
+            str = *(ASN1_STRING **)pval;
+            memset(str, 0, sizeof(*str));
+            str->type = utype;
+            str->flags = ASN1_STRING_FLAG_EMBED;
+        } else {
+            str = ASN1_STRING_type_new(utype);
+            *pval = (ASN1_VALUE *)str;
+        }
+        if (it->itype == ASN1_ITYPE_MSTRING && str)
+            str->flags |= ASN1_STRING_FLAG_MSTRING;
+        break;
+    }
+    if (*pval)
+        return 1;
+    return 0;
+}
+
+static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    int utype;
+    if (it && it->funcs) {
+        const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
+        if (pf->prim_clear)
+            pf->prim_clear(pval, it);
+        else
+            *pval = NULL;
+        return;
+    }
+    if (!it || (it->itype == ASN1_ITYPE_MSTRING))
+        utype = -1;
+    else
+        utype = it->utype;
+    if (utype == V_ASN1_BOOLEAN)
+        *(ASN1_BOOLEAN *)pval = it->size;
+    else
+        *pval = NULL;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_prn.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_prn.c
new file mode 100644
index 0000000..56d5ea0
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_prn.c
@@ -0,0 +1,539 @@
+/*
+ * Copyright 2000-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stddef.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+#include "crypto/asn1.h"
+#include "asn1_local.h"
+
+/*
+ * Print routines.
+ */
+
+/* ASN1_PCTX routines */
+
+static ASN1_PCTX default_pctx = {
+    ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */
+    0,                          /* nm_flags */
+    0,                          /* cert_flags */
+    0,                          /* oid_flags */
+    0                           /* str_flags */
+};
+
+ASN1_PCTX *ASN1_PCTX_new(void)
+{
+    ASN1_PCTX *ret;
+
+    ret = OPENSSL_zalloc(sizeof(*ret));
+    if (ret == NULL) {
+        ASN1err(ASN1_F_ASN1_PCTX_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    return ret;
+}
+
+void ASN1_PCTX_free(ASN1_PCTX *p)
+{
+    OPENSSL_free(p);
+}
+
+unsigned long ASN1_PCTX_get_flags(const ASN1_PCTX *p)
+{
+    return p->flags;
+}
+
+void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags)
+{
+    p->flags = flags;
+}
+
+unsigned long ASN1_PCTX_get_nm_flags(const ASN1_PCTX *p)
+{
+    return p->nm_flags;
+}
+
+void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags)
+{
+    p->nm_flags = flags;
+}
+
+unsigned long ASN1_PCTX_get_cert_flags(const ASN1_PCTX *p)
+{
+    return p->cert_flags;
+}
+
+void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags)
+{
+    p->cert_flags = flags;
+}
+
+unsigned long ASN1_PCTX_get_oid_flags(const ASN1_PCTX *p)
+{
+    return p->oid_flags;
+}
+
+void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags)
+{
+    p->oid_flags = flags;
+}
+
+unsigned long ASN1_PCTX_get_str_flags(const ASN1_PCTX *p)
+{
+    return p->str_flags;
+}
+
+void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags)
+{
+    p->str_flags = flags;
+}
+
+/* Main print routines */
+
+static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+                               const ASN1_ITEM *it,
+                               const char *fname, const char *sname,
+                               int nohdr, const ASN1_PCTX *pctx);
+
+static int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+                            const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx);
+
+static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
+                                const ASN1_ITEM *it, int indent,
+                                const char *fname, const char *sname,
+                                const ASN1_PCTX *pctx);
+
+static int asn1_print_fsname(BIO *out, int indent,
+                             const char *fname, const char *sname,
+                             const ASN1_PCTX *pctx);
+
+int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
+                    const ASN1_ITEM *it, const ASN1_PCTX *pctx)
+{
+    const char *sname;
+    if (pctx == NULL)
+        pctx = &default_pctx;
+    if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
+        sname = NULL;
+    else
+        sname = it->sname;
+    return asn1_item_print_ctx(out, &ifld, indent, it, NULL, sname, 0, pctx);
+}
+
+static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+                               const ASN1_ITEM *it,
+                               const char *fname, const char *sname,
+                               int nohdr, const ASN1_PCTX *pctx)
+{
+    const ASN1_TEMPLATE *tt;
+    const ASN1_EXTERN_FUNCS *ef;
+    ASN1_VALUE **tmpfld;
+    const ASN1_AUX *aux = it->funcs;
+    ASN1_aux_cb *asn1_cb;
+    ASN1_PRINT_ARG parg;
+    int i;
+    if (aux && aux->asn1_cb) {
+        parg.out = out;
+        parg.indent = indent;
+        parg.pctx = pctx;
+        asn1_cb = aux->asn1_cb;
+    } else
+        asn1_cb = 0;
+
+   if (((it->itype != ASN1_ITYPE_PRIMITIVE)
+       || (it->utype != V_ASN1_BOOLEAN)) && *fld == NULL) {
+        if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT) {
+            if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+                return 0;
+            if (BIO_puts(out, "<ABSENT>\n") <= 0)
+                return 0;
+        }
+        return 1;
+    }
+
+    switch (it->itype) {
+    case ASN1_ITYPE_PRIMITIVE:
+        if (it->templates) {
+            if (!asn1_template_print_ctx(out, fld, indent,
+                                         it->templates, pctx))
+                return 0;
+            break;
+        }
+        /* fall through */
+    case ASN1_ITYPE_MSTRING:
+        if (!asn1_primitive_print(out, fld, it, indent, fname, sname, pctx))
+            return 0;
+        break;
+
+    case ASN1_ITYPE_EXTERN:
+        if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+            return 0;
+        /* Use new style print routine if possible */
+        ef = it->funcs;
+        if (ef && ef->asn1_ex_print) {
+            i = ef->asn1_ex_print(out, fld, indent, "", pctx);
+            if (!i)
+                return 0;
+            if ((i == 2) && (BIO_puts(out, "\n") <= 0))
+                return 0;
+            return 1;
+        } else if (sname &&
+                   BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0)
+            return 0;
+        break;
+
+    case ASN1_ITYPE_CHOICE:
+        /* CHOICE type, get selector */
+        i = asn1_get_choice_selector(fld, it);
+        /* This should never happen... */
+        if ((i < 0) || (i >= it->tcount)) {
+            if (BIO_printf(out, "ERROR: selector [%d] invalid\n", i) <= 0)
+                return 0;
+            return 1;
+        }
+        tt = it->templates + i;
+        tmpfld = asn1_get_field_ptr(fld, tt);
+        if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
+            return 0;
+        break;
+
+    case ASN1_ITYPE_SEQUENCE:
+    case ASN1_ITYPE_NDEF_SEQUENCE:
+        if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+            return 0;
+        if (fname || sname) {
+            if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
+                if (BIO_puts(out, " {\n") <= 0)
+                    return 0;
+            } else {
+                if (BIO_puts(out, "\n") <= 0)
+                    return 0;
+            }
+        }
+
+        if (asn1_cb) {
+            i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
+            if (i == 0)
+                return 0;
+            if (i == 2)
+                return 1;
+        }
+
+        /* Print each field entry */
+        for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+            const ASN1_TEMPLATE *seqtt;
+            seqtt = asn1_do_adb(fld, tt, 1);
+            if (!seqtt)
+                return 0;
+            tmpfld = asn1_get_field_ptr(fld, seqtt);
+            if (!asn1_template_print_ctx(out, tmpfld,
+                                         indent + 2, seqtt, pctx))
+                return 0;
+        }
+        if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
+            if (BIO_printf(out, "%*s}\n", indent, "") < 0)
+                return 0;
+        }
+
+        if (asn1_cb) {
+            i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
+            if (i == 0)
+                return 0;
+        }
+        break;
+
+    default:
+        BIO_printf(out, "Unprocessed type %d\n", it->itype);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+                            const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
+{
+    int i, flags;
+    const char *sname, *fname;
+    ASN1_VALUE *tfld;
+    flags = tt->flags;
+    if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME)
+        sname = ASN1_ITEM_ptr(tt->item)->sname;
+    else
+        sname = NULL;
+    if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
+        fname = NULL;
+    else
+        fname = tt->field_name;
+
+    /*
+     * If field is embedded then fld needs fixing so it is a pointer to
+     * a pointer to a field.
+     */
+    if (flags & ASN1_TFLG_EMBED) {
+        tfld = (ASN1_VALUE *)fld;
+        fld = &tfld;
+    }
+
+    if (flags & ASN1_TFLG_SK_MASK) {
+        char *tname;
+        ASN1_VALUE *skitem;
+        STACK_OF(ASN1_VALUE) *stack;
+
+        /* SET OF, SEQUENCE OF */
+        if (fname) {
+            if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF) {
+                if (flags & ASN1_TFLG_SET_OF)
+                    tname = "SET";
+                else
+                    tname = "SEQUENCE";
+                if (BIO_printf(out, "%*s%s OF %s {\n",
+                               indent, "", tname, tt->field_name) <= 0)
+                    return 0;
+            } else if (BIO_printf(out, "%*s%s:\n", indent, "", fname) <= 0)
+                return 0;
+        }
+        stack = (STACK_OF(ASN1_VALUE) *)*fld;
+        for (i = 0; i < sk_ASN1_VALUE_num(stack); i++) {
+            if ((i > 0) && (BIO_puts(out, "\n") <= 0))
+                return 0;
+
+            skitem = sk_ASN1_VALUE_value(stack, i);
+            if (!asn1_item_print_ctx(out, &skitem, indent + 2,
+                                     ASN1_ITEM_ptr(tt->item), NULL, NULL, 1,
+                                     pctx))
+                return 0;
+        }
+        if (i == 0 && BIO_printf(out, "%*s<%s>\n", indent + 2, "",
+                                 stack == NULL ? "ABSENT" : "EMPTY") <= 0)
+            return 0;
+        if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
+            if (BIO_printf(out, "%*s}\n", indent, "") <= 0)
+                return 0;
+        }
+        return 1;
+    }
+    return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item),
+                               fname, sname, 0, pctx);
+}
+
+static int asn1_print_fsname(BIO *out, int indent,
+                             const char *fname, const char *sname,
+                             const ASN1_PCTX *pctx)
+{
+    static const char spaces[] = "                    ";
+    static const int nspaces = sizeof(spaces) - 1;
+
+    while (indent > nspaces) {
+        if (BIO_write(out, spaces, nspaces) != nspaces)
+            return 0;
+        indent -= nspaces;
+    }
+    if (BIO_write(out, spaces, indent) != indent)
+        return 0;
+    if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
+        sname = NULL;
+    if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
+        fname = NULL;
+    if (!sname && !fname)
+        return 1;
+    if (fname) {
+        if (BIO_puts(out, fname) <= 0)
+            return 0;
+    }
+    if (sname) {
+        if (fname) {
+            if (BIO_printf(out, " (%s)", sname) <= 0)
+                return 0;
+        } else {
+            if (BIO_puts(out, sname) <= 0)
+                return 0;
+        }
+    }
+    if (BIO_write(out, ": ", 2) != 2)
+        return 0;
+    return 1;
+}
+
+static int asn1_print_boolean(BIO *out, int boolval)
+{
+    const char *str;
+    switch (boolval) {
+    case -1:
+        str = "BOOL ABSENT";
+        break;
+
+    case 0:
+        str = "FALSE";
+        break;
+
+    default:
+        str = "TRUE";
+        break;
+
+    }
+
+    if (BIO_puts(out, str) <= 0)
+        return 0;
+    return 1;
+
+}
+
+static int asn1_print_integer(BIO *out, const ASN1_INTEGER *str)
+{
+    char *s;
+    int ret = 1;
+    s = i2s_ASN1_INTEGER(NULL, str);
+    if (s == NULL)
+        return 0;
+    if (BIO_puts(out, s) <= 0)
+        ret = 0;
+    OPENSSL_free(s);
+    return ret;
+}
+
+static int asn1_print_oid(BIO *out, const ASN1_OBJECT *oid)
+{
+    char objbuf[80];
+    const char *ln;
+    ln = OBJ_nid2ln(OBJ_obj2nid(oid));
+    if (!ln)
+        ln = "";
+    OBJ_obj2txt(objbuf, sizeof(objbuf), oid, 1);
+    if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0)
+        return 0;
+    return 1;
+}
+
+static int asn1_print_obstring(BIO *out, const ASN1_STRING *str, int indent)
+{
+    if (str->type == V_ASN1_BIT_STRING) {
+        if (BIO_printf(out, " (%ld unused bits)\n", str->flags & 0x7) <= 0)
+            return 0;
+    } else if (BIO_puts(out, "\n") <= 0)
+        return 0;
+    if ((str->length > 0)
+        && BIO_dump_indent(out, (const char *)str->data, str->length,
+                           indent + 2) <= 0)
+        return 0;
+    return 1;
+}
+
+static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
+                                const ASN1_ITEM *it, int indent,
+                                const char *fname, const char *sname,
+                                const ASN1_PCTX *pctx)
+{
+    long utype;
+    ASN1_STRING *str;
+    int ret = 1, needlf = 1;
+    const char *pname;
+    const ASN1_PRIMITIVE_FUNCS *pf;
+    pf = it->funcs;
+    if (!asn1_print_fsname(out, indent, fname, sname, pctx))
+        return 0;
+    if (pf && pf->prim_print)
+        return pf->prim_print(out, fld, it, indent, pctx);
+    if (it->itype == ASN1_ITYPE_MSTRING) {
+        str = (ASN1_STRING *)*fld;
+        utype = str->type & ~V_ASN1_NEG;
+    } else {
+        utype = it->utype;
+        if (utype == V_ASN1_BOOLEAN)
+            str = NULL;
+        else
+            str = (ASN1_STRING *)*fld;
+    }
+    if (utype == V_ASN1_ANY) {
+        ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
+        utype = atype->type;
+        fld = &atype->value.asn1_value;
+        str = (ASN1_STRING *)*fld;
+        if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
+            pname = NULL;
+        else
+            pname = ASN1_tag2str(utype);
+    } else {
+        if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE)
+            pname = ASN1_tag2str(utype);
+        else
+            pname = NULL;
+    }
+
+    if (utype == V_ASN1_NULL) {
+        if (BIO_puts(out, "NULL\n") <= 0)
+            return 0;
+        return 1;
+    }
+
+    if (pname) {
+        if (BIO_puts(out, pname) <= 0)
+            return 0;
+        if (BIO_puts(out, ":") <= 0)
+            return 0;
+    }
+
+    switch (utype) {
+    case V_ASN1_BOOLEAN:
+        {
+            int boolval = *(int *)fld;
+            if (boolval == -1)
+                boolval = it->size;
+            ret = asn1_print_boolean(out, boolval);
+        }
+        break;
+
+    case V_ASN1_INTEGER:
+    case V_ASN1_ENUMERATED:
+        ret = asn1_print_integer(out, str);
+        break;
+
+    case V_ASN1_UTCTIME:
+        ret = ASN1_UTCTIME_print(out, str);
+        break;
+
+    case V_ASN1_GENERALIZEDTIME:
+        ret = ASN1_GENERALIZEDTIME_print(out, str);
+        break;
+
+    case V_ASN1_OBJECT:
+        ret = asn1_print_oid(out, (const ASN1_OBJECT *)*fld);
+        break;
+
+    case V_ASN1_OCTET_STRING:
+    case V_ASN1_BIT_STRING:
+        ret = asn1_print_obstring(out, str, indent);
+        needlf = 0;
+        break;
+
+    case V_ASN1_SEQUENCE:
+    case V_ASN1_SET:
+    case V_ASN1_OTHER:
+        if (BIO_puts(out, "\n") <= 0)
+            return 0;
+        if (ASN1_parse_dump(out, str->data, str->length, indent, 0) <= 0)
+            ret = 0;
+        needlf = 0;
+        break;
+
+    default:
+        ret = ASN1_STRING_print_ex(out, str, pctx->str_flags);
+
+    }
+    if (!ret)
+        return 0;
+    if (needlf && BIO_puts(out, "\n") <= 0)
+        return 0;
+    return 1;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_scn.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_scn.c
new file mode 100644
index 0000000..f0f218a
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_scn.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2010-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stddef.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+#include "asn1_local.h"
+
+/*
+ * General ASN1 structure recursive scanner: iterate through all fields
+ * passing details to a callback.
+ */
+
+ASN1_SCTX *ASN1_SCTX_new(int (*scan_cb) (ASN1_SCTX *ctx))
+{
+    ASN1_SCTX *ret = OPENSSL_zalloc(sizeof(*ret));
+
+    if (ret == NULL) {
+        ASN1err(ASN1_F_ASN1_SCTX_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    ret->scan_cb = scan_cb;
+    return ret;
+}
+
+void ASN1_SCTX_free(ASN1_SCTX *p)
+{
+    OPENSSL_free(p);
+}
+
+const ASN1_ITEM *ASN1_SCTX_get_item(ASN1_SCTX *p)
+{
+    return p->it;
+}
+
+const ASN1_TEMPLATE *ASN1_SCTX_get_template(ASN1_SCTX *p)
+{
+    return p->tt;
+}
+
+unsigned long ASN1_SCTX_get_flags(ASN1_SCTX *p)
+{
+    return p->flags;
+}
+
+void ASN1_SCTX_set_app_data(ASN1_SCTX *p, void *data)
+{
+    p->app_data = data;
+}
+
+void *ASN1_SCTX_get_app_data(ASN1_SCTX *p)
+{
+    return p->app_data;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_typ.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_typ.c
new file mode 100644
index 0000000..98d9879
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_typ.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2000-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+
+/* Declarations for string types */
+
+#define IMPLEMENT_ASN1_STRING_FUNCTIONS(sname) \
+    IMPLEMENT_ASN1_TYPE(sname) \
+    IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(sname, sname, sname) \
+sname *sname##_new(void) \
+{ \
+    return ASN1_STRING_type_new(V_##sname); \
+} \
+void sname##_free(sname *x) \
+{ \
+    ASN1_STRING_free(x); \
+}
+
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_OCTET_STRING)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_INTEGER)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_ENUMERATED)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_BIT_STRING)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UTF8STRING)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_PRINTABLESTRING)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_T61STRING)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_IA5STRING)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_GENERALSTRING)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UTCTIME)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_GENERALIZEDTIME)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_VISIBLESTRING)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UNIVERSALSTRING)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_BMPSTRING)
+
+IMPLEMENT_ASN1_TYPE(ASN1_NULL)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_NULL)
+
+IMPLEMENT_ASN1_TYPE(ASN1_OBJECT)
+
+IMPLEMENT_ASN1_TYPE(ASN1_ANY)
+
+/* Just swallow an ASN1_SEQUENCE in an ASN1_STRING */
+IMPLEMENT_ASN1_TYPE(ASN1_SEQUENCE)
+
+IMPLEMENT_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
+
+/* Multistring types */
+
+IMPLEMENT_ASN1_MSTRING(ASN1_PRINTABLE, B_ASN1_PRINTABLE)
+IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE)
+
+IMPLEMENT_ASN1_MSTRING(DISPLAYTEXT, B_ASN1_DISPLAYTEXT)
+IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT)
+
+IMPLEMENT_ASN1_MSTRING(DIRECTORYSTRING, B_ASN1_DIRECTORYSTRING)
+IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING)
+
+/* Three separate BOOLEAN type: normal, DEFAULT TRUE and DEFAULT FALSE */
+IMPLEMENT_ASN1_TYPE_ex(ASN1_BOOLEAN, ASN1_BOOLEAN, -1)
+IMPLEMENT_ASN1_TYPE_ex(ASN1_TBOOLEAN, ASN1_BOOLEAN, 1)
+IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0)
+
+/* Special, OCTET STRING with indefinite length constructed support */
+
+IMPLEMENT_ASN1_TYPE_ex(ASN1_OCTET_STRING_NDEF, ASN1_OCTET_STRING, ASN1_TFLG_NDEF)
+
+ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY, ASN1_ANY)
+ASN1_ITEM_TEMPLATE_END(ASN1_SEQUENCE_ANY)
+
+ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, ASN1_SET_ANY, ASN1_ANY)
+ASN1_ITEM_TEMPLATE_END(ASN1_SET_ANY)
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY, ASN1_SET_ANY)
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_utl.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_utl.c
new file mode 100644
index 0000000..a448685
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tasn_utl.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2000-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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stddef.h>
+#include <string.h>
+#include "internal/cryptlib.h"
+#include "internal/refcount.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+#include <openssl/err.h>
+#include "asn1_local.h"
+
+/* Utility functions for manipulating fields and offsets */
+
+/* Add 'offset' to 'addr' */
+#define offset2ptr(addr, offset) (void *)(((char *) addr) + offset)
+
+/*
+ * Given an ASN1_ITEM CHOICE type return the selector value
+ */
+
+int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    int *sel = offset2ptr(*pval, it->utype);
+    return *sel;
+}
+
+/*
+ * Given an ASN1_ITEM CHOICE type set the selector value, return old value.
+ */
+
+int asn1_set_choice_selector(ASN1_VALUE **pval, int value,
+                             const ASN1_ITEM *it)
+{
+    int *sel, ret;
+    sel = offset2ptr(*pval, it->utype);
+    ret = *sel;
+    *sel = value;
+    return ret;
+}
+
+/*
+ * Do atomic reference counting. The value 'op' decides what to do.
+ * If it is +1 then the count is incremented.
+ * If |op| is 0, lock is initialised and count is set to 1.
+ * If |op| is -1, count is decremented and the return value is the current
+ * reference count or 0 if no reference count is active.
+ * It returns -1 on initialisation error.
+ * Used by ASN1_SEQUENCE construct of X509, X509_REQ, X509_CRL objects
+ */
+int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it)
+{
+    const ASN1_AUX *aux;
+    CRYPTO_REF_COUNT *lck;
+    CRYPTO_RWLOCK **lock;
+    int ret = -1;
+
+    if ((it->itype != ASN1_ITYPE_SEQUENCE)
+        && (it->itype != ASN1_ITYPE_NDEF_SEQUENCE))
+        return 0;
+    aux = it->funcs;
+    if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT))
+        return 0;
+    lck = offset2ptr(*pval, aux->ref_offset);
+    lock = offset2ptr(*pval, aux->ref_lock);
+
+    switch (op) {
+    case 0:
+        *lck = ret = 1;
+        *lock = CRYPTO_THREAD_lock_new();
+        if (*lock == NULL) {
+            ASN1err(ASN1_F_ASN1_DO_LOCK, ERR_R_MALLOC_FAILURE);
+            return -1;
+        }
+        break;
+    case 1:
+        if (!CRYPTO_UP_REF(lck, &ret, *lock))
+            return -1;
+        break;
+    case -1:
+        if (!CRYPTO_DOWN_REF(lck, &ret, *lock))
+            return -1;  /* failed */
+#ifdef REF_PRINT
+        fprintf(stderr, "%p:%4d:%s\n", it, ret, it->sname);
+#endif
+        REF_ASSERT_ISNT(ret < 0);
+        if (ret == 0) {
+            CRYPTO_THREAD_lock_free(*lock);
+            *lock = NULL;
+        }
+        break;
+    }
+
+    return ret;
+}
+
+static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    const ASN1_AUX *aux;
+    if (!pval || !*pval)
+        return NULL;
+    aux = it->funcs;
+    if (!aux || !(aux->flags & ASN1_AFLG_ENCODING))
+        return NULL;
+    return offset2ptr(*pval, aux->enc_offset);
+}
+
+void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    ASN1_ENCODING *enc;
+    enc = asn1_get_enc_ptr(pval, it);
+    if (enc) {
+        enc->enc = NULL;
+        enc->len = 0;
+        enc->modified = 1;
+    }
+}
+
+void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    ASN1_ENCODING *enc;
+    enc = asn1_get_enc_ptr(pval, it);
+    if (enc) {
+        OPENSSL_free(enc->enc);
+        enc->enc = NULL;
+        enc->len = 0;
+        enc->modified = 1;
+    }
+}
+
+int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
+                  const ASN1_ITEM *it)
+{
+    ASN1_ENCODING *enc;
+    enc = asn1_get_enc_ptr(pval, it);
+    if (!enc)
+        return 1;
+
+    OPENSSL_free(enc->enc);
+    if ((enc->enc = OPENSSL_malloc(inlen)) == NULL) {
+        ASN1err(ASN1_F_ASN1_ENC_SAVE, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    memcpy(enc->enc, in, inlen);
+    enc->len = inlen;
+    enc->modified = 0;
+
+    return 1;
+}
+
+int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
+                     const ASN1_ITEM *it)
+{
+    ASN1_ENCODING *enc;
+    enc = asn1_get_enc_ptr(pval, it);
+    if (!enc || enc->modified)
+        return 0;
+    if (out) {
+        memcpy(*out, enc->enc, enc->len);
+        *out += enc->len;
+    }
+    if (len)
+        *len = enc->len;
+    return 1;
+}
+
+/* Given an ASN1_TEMPLATE get a pointer to a field */
+ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
+{
+    ASN1_VALUE **pvaltmp;
+    pvaltmp = offset2ptr(*pval, tt->offset);
+    /*
+     * NOTE for BOOLEAN types the field is just a plain int so we can't
+     * return int **, so settle for (int *).
+     */
+    return pvaltmp;
+}
+
+/*
+ * Handle ANY DEFINED BY template, find the selector, look up the relevant
+ * ASN1_TEMPLATE in the table and return it.
+ */
+
+const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
+                                 int nullerr)
+{
+    const ASN1_ADB *adb;
+    const ASN1_ADB_TABLE *atbl;
+    long selector;
+    ASN1_VALUE **sfld;
+    int i;
+    if (!(tt->flags & ASN1_TFLG_ADB_MASK))
+        return tt;
+
+    /* Else ANY DEFINED BY ... get the table */
+    adb = ASN1_ADB_ptr(tt->item);
+
+    /* Get the selector field */
+    sfld = offset2ptr(*pval, adb->offset);
+
+    /* Check if NULL */
+    if (*sfld == NULL) {
+        if (!adb->null_tt)
+            goto err;
+        return adb->null_tt;
+    }
+
+    /*
+     * Convert type to a long: NB: don't check for NID_undef here because it
+     * might be a legitimate value in the table
+     */
+    if (tt->flags & ASN1_TFLG_ADB_OID)
+        selector = OBJ_obj2nid((ASN1_OBJECT *)*sfld);
+    else
+        selector = ASN1_INTEGER_get((ASN1_INTEGER *)*sfld);
+
+    /* Let application callback translate value */
+    if (adb->adb_cb != NULL && adb->adb_cb(&selector) == 0) {
+        ASN1err(ASN1_F_ASN1_DO_ADB, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
+        return NULL;
+    }
+
+    /*
+     * Try to find matching entry in table Maybe should check application
+     * types first to allow application override? Might also be useful to
+     * have a flag which indicates table is sorted and we can do a binary
+     * search. For now stick to a linear search.
+     */
+
+    for (atbl = adb->tbl, i = 0; i < adb->tblcount; i++, atbl++)
+        if (atbl->value == selector)
+            return &atbl->tt;
+
+    /* FIXME: need to search application table too */
+
+    /* No match, return default type */
+    if (!adb->default_tt)
+        goto err;
+    return adb->default_tt;
+
+ err:
+    /* FIXME: should log the value or OID of unsupported type */
+    if (nullerr)
+        ASN1err(ASN1_F_ASN1_DO_ADB, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
+    return NULL;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tbl_standard.h b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tbl_standard.h
new file mode 100644
index 0000000..777a734
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/tbl_standard.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 1999-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/* size limits: this stuff is taken straight from RFC3280 */
+
+#define ub_name                         32768
+#define ub_common_name                  64
+#define ub_locality_name                128
+#define ub_state_name                   128
+#define ub_organization_name            64
+#define ub_organization_unit_name       64
+#define ub_title                        64
+#define ub_email_address                128
+#define ub_serial_number                64
+
+/* From RFC4524 */
+
+#define ub_rfc822_mailbox               256
+
+/* This table must be kept in NID order */
+
+static const ASN1_STRING_TABLE tbl_standard[] = {
+    {NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0},
+    {NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
+    {NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0},
+    {NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0},
+    {NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0},
+    {NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE,
+     0},
+    {NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING,
+     STABLE_NO_MASK},
+    {NID_pkcs9_unstructuredName, 1, -1, PKCS9STRING_TYPE, 0},
+    {NID_pkcs9_challengePassword, 1, -1, PKCS9STRING_TYPE, 0},
+    {NID_pkcs9_unstructuredAddress, 1, -1, DIRSTRING_TYPE, 0},
+    {NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0},
+    {NID_surname, 1, ub_name, DIRSTRING_TYPE, 0},
+    {NID_initials, 1, ub_name, DIRSTRING_TYPE, 0},
+    {NID_serialNumber, 1, ub_serial_number, B_ASN1_PRINTABLESTRING,
+     STABLE_NO_MASK},
+    {NID_friendlyName, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
+    {NID_name, 1, ub_name, DIRSTRING_TYPE, 0},
+    {NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
+    {NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK},
+    {NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
+    {NID_rfc822Mailbox, 1, ub_rfc822_mailbox, B_ASN1_IA5STRING,
+     STABLE_NO_MASK},
+    {NID_jurisdictionCountryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
+    {NID_INN, 1, 12, B_ASN1_NUMERICSTRING, STABLE_NO_MASK},
+    {NID_OGRN, 1, 13, B_ASN1_NUMERICSTRING, STABLE_NO_MASK},
+    {NID_SNILS, 1, 11, B_ASN1_NUMERICSTRING, STABLE_NO_MASK},
+    {NID_countryCode3c, 3, 3, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
+    {NID_countryCode3n, 3, 3, B_ASN1_NUMERICSTRING, STABLE_NO_MASK},
+    {NID_dnsName, 0, -1, B_ASN1_UTF8STRING, STABLE_NO_MASK}
+};
+
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_algor.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_algor.c
new file mode 100644
index 0000000..c9a8f1e
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_algor.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright 1998-2020 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stddef.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include "crypto/evp.h"
+
+ASN1_SEQUENCE(X509_ALGOR) = {
+        ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT),
+        ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY)
+} ASN1_SEQUENCE_END(X509_ALGOR)
+
+ASN1_ITEM_TEMPLATE(X509_ALGORS) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, algorithms, X509_ALGOR)
+ASN1_ITEM_TEMPLATE_END(X509_ALGORS)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_ALGOR)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_ALGORS, X509_ALGORS, X509_ALGORS)
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_ALGOR)
+
+int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval)
+{
+    if (alg == NULL)
+        return 0;
+
+    if (ptype != V_ASN1_UNDEF) {
+        if (alg->parameter == NULL)
+            alg->parameter = ASN1_TYPE_new();
+        if (alg->parameter == NULL)
+            return 0;
+    }
+
+    ASN1_OBJECT_free(alg->algorithm);
+    alg->algorithm = aobj;
+
+    if (ptype == 0)
+        return 1;
+    if (ptype == V_ASN1_UNDEF) {
+        ASN1_TYPE_free(alg->parameter);
+        alg->parameter = NULL;
+    } else
+        ASN1_TYPE_set(alg->parameter, ptype, pval);
+    return 1;
+}
+
+void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype,
+                     const void **ppval, const X509_ALGOR *algor)
+{
+    if (paobj)
+        *paobj = algor->algorithm;
+    if (pptype) {
+        if (algor->parameter == NULL) {
+            *pptype = V_ASN1_UNDEF;
+            return;
+        } else
+            *pptype = algor->parameter->type;
+        if (ppval)
+            *ppval = algor->parameter->value.ptr;
+    }
+}
+
+/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
+
+void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md)
+{
+    int param_type;
+
+    if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
+        param_type = V_ASN1_UNDEF;
+    else
+        param_type = V_ASN1_NULL;
+
+    X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
+
+}
+
+int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
+{
+    int rv;
+    rv = OBJ_cmp(a->algorithm, b->algorithm);
+    if (rv)
+        return rv;
+    if (!a->parameter && !b->parameter)
+        return 0;
+    return ASN1_TYPE_cmp(a->parameter, b->parameter);
+}
+
+int X509_ALGOR_copy(X509_ALGOR *dest, const X509_ALGOR *src)
+{
+    if (src == NULL || dest == NULL)
+	return 0;
+
+    if (dest->algorithm)
+         ASN1_OBJECT_free(dest->algorithm);
+    dest->algorithm = NULL;
+
+    if (dest->parameter)
+        ASN1_TYPE_free(dest->parameter);
+    dest->parameter = NULL;
+
+    if (src->algorithm)
+        if ((dest->algorithm = OBJ_dup(src->algorithm)) == NULL)
+	    return 0;
+
+    if (src->parameter) {
+        dest->parameter = ASN1_TYPE_new();
+        if (dest->parameter == NULL)
+            return 0;
+
+        /* Assuming this is also correct for a BOOL.
+         * set does copy as a side effect.
+         */
+        if (ASN1_TYPE_set1(dest->parameter, 
+                src->parameter->type, src->parameter->value.ptr) == 0)
+            return 0;
+    }
+    return 1;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_bignum.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_bignum.c
new file mode 100644
index 0000000..c6b3acc
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_bignum.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2000-2019 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/bn.h>
+
+/*
+ * Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER
+ * as a BIGNUM directly. Currently it ignores the sign which isn't a problem
+ * since all BIGNUMs used are non negative and anything that looks negative
+ * is normally due to an encoding error.
+ */
+
+#define BN_SENSITIVE    1
+
+static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+static int bn_secure_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+                  const ASN1_ITEM *it);
+static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+                  int utype, char *free_cont, const ASN1_ITEM *it);
+static int bn_secure_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+                         int utype, char *free_cont, const ASN1_ITEM *it);
+static int bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                    int indent, const ASN1_PCTX *pctx);
+
+static ASN1_PRIMITIVE_FUNCS bignum_pf = {
+    NULL, 0,
+    bn_new,
+    bn_free,
+    0,
+    bn_c2i,
+    bn_i2c,
+    bn_print
+};
+
+static ASN1_PRIMITIVE_FUNCS cbignum_pf = {
+    NULL, 0,
+    bn_secure_new,
+    bn_free,
+    0,
+    bn_secure_c2i,
+    bn_i2c,
+    bn_print
+};
+
+ASN1_ITEM_start(BIGNUM)
+        ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM"
+ASN1_ITEM_end(BIGNUM)
+
+ASN1_ITEM_start(CBIGNUM)
+        ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &cbignum_pf, BN_SENSITIVE, "CBIGNUM"
+ASN1_ITEM_end(CBIGNUM)
+
+static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    *pval = (ASN1_VALUE *)BN_new();
+    if (*pval != NULL)
+        return 1;
+    else
+        return 0;
+}
+
+static int bn_secure_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    *pval = (ASN1_VALUE *)BN_secure_new();
+    if (*pval != NULL)
+        return 1;
+    else
+        return 0;
+}
+
+static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    if (*pval == NULL)
+        return;
+    if (it->size & BN_SENSITIVE)
+        BN_clear_free((BIGNUM *)*pval);
+    else
+        BN_free((BIGNUM *)*pval);
+    *pval = NULL;
+}
+
+static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+                  const ASN1_ITEM *it)
+{
+    BIGNUM *bn;
+    int pad;
+    if (*pval == NULL)
+        return -1;
+    bn = (BIGNUM *)*pval;
+    /* If MSB set in an octet we need a padding byte */
+    if (BN_num_bits(bn) & 0x7)
+        pad = 0;
+    else
+        pad = 1;
+    if (cont) {
+        if (pad)
+            *cont++ = 0;
+        BN_bn2bin(bn, cont);
+    }
+    return pad + BN_num_bytes(bn);
+}
+
+static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+                  int utype, char *free_cont, const ASN1_ITEM *it)
+{
+    BIGNUM *bn;
+
+    if (*pval == NULL && !bn_new(pval, it))
+        return 0;
+    bn = (BIGNUM *)*pval;
+    if (!BN_bin2bn(cont, len, bn)) {
+        bn_free(pval, it);
+        return 0;
+    }
+    return 1;
+}
+
+static int bn_secure_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+                         int utype, char *free_cont, const ASN1_ITEM *it)
+{
+    int ret;
+    BIGNUM *bn;
+
+    if (*pval == NULL && !bn_secure_new(pval, it))
+        return 0;
+
+    ret = bn_c2i(pval, cont, len, utype, free_cont, it);
+    if (!ret)
+        return 0;
+
+    /* Set constant-time flag for all secure BIGNUMS */
+    bn = (BIGNUM *)*pval;
+    BN_set_flags(bn, BN_FLG_CONSTTIME);
+    return ret;
+}
+
+static int bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                    int indent, const ASN1_PCTX *pctx)
+{
+    if (!BN_print(out, *(BIGNUM **)pval))
+        return 0;
+    if (BIO_puts(out, "\n") <= 0)
+        return 0;
+    return 1;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_info.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_info.c
new file mode 100644
index 0000000..8d99f07
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_info.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1995-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+
+X509_INFO *X509_INFO_new(void)
+{
+    X509_INFO *ret;
+
+    ret = OPENSSL_zalloc(sizeof(*ret));
+    if (ret == NULL) {
+        ASN1err(ASN1_F_X509_INFO_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    return ret;
+}
+
+void X509_INFO_free(X509_INFO *x)
+{
+    if (x == NULL)
+        return;
+
+    X509_free(x->x509);
+    X509_CRL_free(x->crl);
+    X509_PKEY_free(x->x_pkey);
+    OPENSSL_free(x->enc_data);
+    OPENSSL_free(x);
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_int64.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_int64.c
new file mode 100644
index 0000000..96c1a25
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_int64.c
@@ -0,0 +1,291 @@
+/*
+ * Copyright 2017-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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include "internal/numbers.h"
+#include <openssl/asn1t.h>
+#include <openssl/bn.h>
+#include "asn1_local.h"
+
+/*
+ * Custom primitive types for handling int32_t, int64_t, uint32_t, uint64_t.
+ * This converts between an ASN1_INTEGER and those types directly.
+ * This is preferred to using the LONG / ZLONG primitives.
+ */
+
+/*
+ * We abuse the ASN1_ITEM fields |size| as a flags field
+ */
+#define INTxx_FLAG_ZERO_DEFAULT (1<<0)
+#define INTxx_FLAG_SIGNED       (1<<1)
+
+static int uint64_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    if ((*pval = (ASN1_VALUE *)OPENSSL_zalloc(sizeof(uint64_t))) == NULL) {
+        ASN1err(ASN1_F_UINT64_NEW, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    return 1;
+}
+
+static void uint64_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    OPENSSL_free(*pval);
+    *pval = NULL;
+}
+
+static void uint64_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    **(uint64_t **)pval = 0;
+}
+
+static int uint64_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+                    const ASN1_ITEM *it)
+{
+    uint64_t utmp;
+    int neg = 0;
+    /* this exists to bypass broken gcc optimization */
+    char *cp = (char *)*pval;
+
+    /* use memcpy, because we may not be uint64_t aligned */
+    memcpy(&utmp, cp, sizeof(utmp));
+
+    if ((it->size & INTxx_FLAG_ZERO_DEFAULT) == INTxx_FLAG_ZERO_DEFAULT
+        && utmp == 0)
+        return -1;
+    if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED
+        && (int64_t)utmp < 0) {
+        /* i2c_uint64_int() assumes positive values */
+        utmp = 0 - utmp;
+        neg = 1;
+    }
+
+    return i2c_uint64_int(cont, utmp, neg);
+}
+
+static int uint64_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+                    int utype, char *free_cont, const ASN1_ITEM *it)
+{
+    uint64_t utmp = 0;
+    char *cp;
+    int neg = 0;
+
+    if (*pval == NULL && !uint64_new(pval, it))
+        return 0;
+
+    cp = (char *)*pval;
+
+    /*
+     * Strictly speaking, zero length is malformed.  However, long_c2i
+     * (x_long.c) encodes 0 as a zero length INTEGER (wrongly, of course),
+     * so for the sake of backward compatibility, we still decode zero
+     * length INTEGERs as the number zero.
+     */
+    if (len == 0)
+        goto long_compat;
+
+    if (!c2i_uint64_int(&utmp, &neg, &cont, len))
+        return 0;
+    if ((it->size & INTxx_FLAG_SIGNED) == 0 && neg) {
+        ASN1err(ASN1_F_UINT64_C2I, ASN1_R_ILLEGAL_NEGATIVE_VALUE);
+        return 0;
+    }
+    if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED
+            && !neg && utmp > INT64_MAX) {
+        ASN1err(ASN1_F_UINT64_C2I, ASN1_R_TOO_LARGE);
+        return 0;
+    }
+    if (neg)
+        /* c2i_uint64_int() returns positive values */
+        utmp = 0 - utmp;
+
+ long_compat:
+    memcpy(cp, &utmp, sizeof(utmp));
+    return 1;
+}
+
+static int uint64_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                        int indent, const ASN1_PCTX *pctx)
+{
+    if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED)
+        return BIO_printf(out, "%jd\n", **(int64_t **)pval);
+    return BIO_printf(out, "%ju\n", **(uint64_t **)pval);
+}
+
+/* 32-bit variants */
+
+static int uint32_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    if ((*pval = (ASN1_VALUE *)OPENSSL_zalloc(sizeof(uint32_t))) == NULL) {
+        ASN1err(ASN1_F_UINT32_NEW, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    return 1;
+}
+
+static void uint32_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    OPENSSL_free(*pval);
+    *pval = NULL;
+}
+
+static void uint32_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    **(uint32_t **)pval = 0;
+}
+
+static int uint32_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+                    const ASN1_ITEM *it)
+{
+    uint32_t utmp;
+    int neg = 0;
+    /* this exists to bypass broken gcc optimization */
+    char *cp = (char *)*pval;
+
+    /* use memcpy, because we may not be uint32_t aligned */
+    memcpy(&utmp, cp, sizeof(utmp));
+
+    if ((it->size & INTxx_FLAG_ZERO_DEFAULT) == INTxx_FLAG_ZERO_DEFAULT
+        && utmp == 0)
+        return -1;
+    if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED
+        && (int32_t)utmp < 0) {
+        /* i2c_uint64_int() assumes positive values */
+        utmp = 0 - utmp;
+        neg = 1;
+    }
+
+    return i2c_uint64_int(cont, (uint64_t)utmp, neg);
+}
+
+/*
+ * Absolute value of INT32_MIN: we can't just use -INT32_MIN as it produces
+ * overflow warnings.
+ */
+
+#define ABS_INT32_MIN ((uint32_t)INT32_MAX + 1)
+
+static int uint32_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+                    int utype, char *free_cont, const ASN1_ITEM *it)
+{
+    uint64_t utmp = 0;
+    uint32_t utmp2 = 0;
+    char *cp;
+    int neg = 0;
+
+    if (*pval == NULL && !uint64_new(pval, it))
+        return 0;
+
+    cp = (char *)*pval;
+
+    /*
+     * Strictly speaking, zero length is malformed.  However, long_c2i
+     * (x_long.c) encodes 0 as a zero length INTEGER (wrongly, of course),
+     * so for the sake of backward compatibility, we still decode zero
+     * length INTEGERs as the number zero.
+     */
+    if (len == 0)
+        goto long_compat;
+
+    if (!c2i_uint64_int(&utmp, &neg, &cont, len))
+        return 0;
+    if ((it->size & INTxx_FLAG_SIGNED) == 0 && neg) {
+        ASN1err(ASN1_F_UINT32_C2I, ASN1_R_ILLEGAL_NEGATIVE_VALUE);
+        return 0;
+    }
+    if (neg) {
+        if (utmp > ABS_INT32_MIN) {
+            ASN1err(ASN1_F_UINT32_C2I, ASN1_R_TOO_SMALL);
+            return 0;
+        }
+        utmp = 0 - utmp;
+    } else {
+        if (((it->size & INTxx_FLAG_SIGNED) != 0 && utmp > INT32_MAX)
+            || ((it->size & INTxx_FLAG_SIGNED) == 0 && utmp > UINT32_MAX)) {
+            ASN1err(ASN1_F_UINT32_C2I, ASN1_R_TOO_LARGE);
+            return 0;
+        }
+    }
+
+ long_compat:
+    utmp2 = (uint32_t)utmp;
+    memcpy(cp, &utmp2, sizeof(utmp2));
+    return 1;
+}
+
+static int uint32_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                        int indent, const ASN1_PCTX *pctx)
+{
+    if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED)
+        return BIO_printf(out, "%d\n", **(int32_t **)pval);
+    return BIO_printf(out, "%u\n", **(uint32_t **)pval);
+}
+
+
+/* Define the primitives themselves */
+
+static ASN1_PRIMITIVE_FUNCS uint32_pf = {
+    NULL, 0,
+    uint32_new,
+    uint32_free,
+    uint32_clear,
+    uint32_c2i,
+    uint32_i2c,
+    uint32_print
+};
+
+static ASN1_PRIMITIVE_FUNCS uint64_pf = {
+    NULL, 0,
+    uint64_new,
+    uint64_free,
+    uint64_clear,
+    uint64_c2i,
+    uint64_i2c,
+    uint64_print
+};
+
+ASN1_ITEM_start(INT32)
+    ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf,
+    INTxx_FLAG_SIGNED, "INT32"
+ASN1_ITEM_end(INT32)
+
+ASN1_ITEM_start(UINT32)
+    ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf, 0, "UINT32"
+ASN1_ITEM_end(UINT32)
+
+ASN1_ITEM_start(INT64)
+    ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf,
+    INTxx_FLAG_SIGNED, "INT64"
+ASN1_ITEM_end(INT64)
+
+ASN1_ITEM_start(UINT64)
+    ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf, 0, "UINT64"
+ASN1_ITEM_end(UINT64)
+
+ASN1_ITEM_start(ZINT32)
+    ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf,
+    INTxx_FLAG_ZERO_DEFAULT|INTxx_FLAG_SIGNED, "ZINT32"
+ASN1_ITEM_end(ZINT32)
+
+ASN1_ITEM_start(ZUINT32)
+    ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf,
+    INTxx_FLAG_ZERO_DEFAULT, "ZUINT32"
+ASN1_ITEM_end(ZUINT32)
+
+ASN1_ITEM_start(ZINT64)
+    ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf,
+    INTxx_FLAG_ZERO_DEFAULT|INTxx_FLAG_SIGNED, "ZINT64"
+ASN1_ITEM_end(ZINT64)
+
+ASN1_ITEM_start(ZUINT64)
+    ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf,
+    INTxx_FLAG_ZERO_DEFAULT, "ZUINT64"
+ASN1_ITEM_end(ZUINT64)
+
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_long.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_long.c
new file mode 100644
index 0000000..bf9371e
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_long.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2000-2017 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+
+#if !(OPENSSL_API_COMPAT < 0x10200000L)
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+#define COPY_SIZE(a, b) (sizeof(a) < sizeof(b) ? sizeof(a) : sizeof(b))
+
+/*
+ * Custom primitive type for long handling. This converts between an
+ * ASN1_INTEGER and a long directly.
+ */
+
+static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+                    const ASN1_ITEM *it);
+static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+                    int utype, char *free_cont, const ASN1_ITEM *it);
+static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                      int indent, const ASN1_PCTX *pctx);
+
+static ASN1_PRIMITIVE_FUNCS long_pf = {
+    NULL, 0,
+    long_new,
+    long_free,
+    long_free,                  /* Clear should set to initial value */
+    long_c2i,
+    long_i2c,
+    long_print
+};
+
+ASN1_ITEM_start(LONG)
+        ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, ASN1_LONG_UNDEF, "LONG"
+ASN1_ITEM_end(LONG)
+
+ASN1_ITEM_start(ZLONG)
+        ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, 0, "ZLONG"
+ASN1_ITEM_end(ZLONG)
+
+static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    memcpy(pval, &it->size, COPY_SIZE(*pval, it->size));
+    return 1;
+}
+
+static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    memcpy(pval, &it->size, COPY_SIZE(*pval, it->size));
+}
+
+/*
+ * Originally BN_num_bits_word was called to perform this operation, but
+ * trouble is that there is no guarantee that sizeof(long) equals to
+ * sizeof(BN_ULONG). BN_ULONG is a configurable type that can be as wide
+ * as long, but also double or half...
+ */
+static int num_bits_ulong(unsigned long value)
+{
+    size_t i;
+    unsigned long ret = 0;
+
+    /*
+     * It is argued that *on average* constant counter loop performs
+     * not worse [if not better] than one with conditional break or
+     * mask-n-table-lookup-style, because of branch misprediction
+     * penalties.
+     */
+    for (i = 0; i < sizeof(value) * 8; i++) {
+        ret += (value != 0);
+        value >>= 1;
+    }
+
+    return (int)ret;
+}
+
+static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+                    const ASN1_ITEM *it)
+{
+    long ltmp;
+    unsigned long utmp, sign;
+    int clen, pad, i;
+
+    memcpy(&ltmp, pval, COPY_SIZE(*pval, ltmp));
+    if (ltmp == it->size)
+        return -1;
+    /*
+     * Convert the long to positive: we subtract one if negative so we can
+     * cleanly handle the padding if only the MSB of the leading octet is
+     * set.
+     */
+    if (ltmp < 0) {
+        sign = 0xff;
+        utmp = 0 - (unsigned long)ltmp - 1;
+    } else {
+        sign = 0;
+        utmp = ltmp;
+    }
+    clen = num_bits_ulong(utmp);
+    /* If MSB of leading octet set we need to pad */
+    if (!(clen & 0x7))
+        pad = 1;
+    else
+        pad = 0;
+
+    /* Convert number of bits to number of octets */
+    clen = (clen + 7) >> 3;
+
+    if (cont != NULL) {
+        if (pad)
+            *cont++ = (unsigned char)sign;
+        for (i = clen - 1; i >= 0; i--) {
+            cont[i] = (unsigned char)(utmp ^ sign);
+            utmp >>= 8;
+        }
+    }
+    return clen + pad;
+}
+
+static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+                    int utype, char *free_cont, const ASN1_ITEM *it)
+{
+    int i;
+    long ltmp;
+    unsigned long utmp = 0, sign = 0x100;
+
+    if (len > 1) {
+        /*
+         * Check possible pad byte.  Worst case, we're skipping past actual
+         * content, but since that's only with 0x00 and 0xff and we set neg
+         * accordingly, the result will be correct in the end anyway.
+         */
+        switch (cont[0]) {
+        case 0xff:
+            cont++;
+            len--;
+            sign = 0xff;
+            break;
+        case 0:
+            cont++;
+            len--;
+            sign = 0;
+            break;
+        }
+    }
+    if (len > (int)sizeof(long)) {
+        ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
+        return 0;
+    }
+
+    if (sign == 0x100) {
+        /* Is it negative? */
+        if (len && (cont[0] & 0x80))
+            sign = 0xff;
+        else
+            sign = 0;
+    } else if (((sign ^ cont[0]) & 0x80) == 0) { /* same sign bit? */
+        ASN1err(ASN1_F_LONG_C2I, ASN1_R_ILLEGAL_PADDING);
+        return 0;
+    }
+    utmp = 0;
+    for (i = 0; i < len; i++) {
+        utmp <<= 8;
+        utmp |= cont[i] ^ sign;
+    }
+    ltmp = (long)utmp;
+    if (ltmp < 0) {
+        ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
+        return 0;
+    }
+    if (sign)
+        ltmp = -ltmp - 1;
+    if (ltmp == it->size) {
+        ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
+        return 0;
+    }
+    memcpy(pval, &ltmp, COPY_SIZE(*pval, ltmp));
+    return 1;
+}
+
+static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                      int indent, const ASN1_PCTX *pctx)
+{
+    long l;
+
+    memcpy(&l, pval, COPY_SIZE(*pval, l));
+    return BIO_printf(out, "%ld\n", l);
+}
+#endif
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_pkey.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_pkey.c
new file mode 100644
index 0000000..593049f
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_pkey.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright 1995-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+X509_PKEY *X509_PKEY_new(void)
+{
+    X509_PKEY *ret = NULL;
+
+    ret = OPENSSL_zalloc(sizeof(*ret));
+    if (ret == NULL)
+        goto err;
+
+    ret->enc_algor = X509_ALGOR_new();
+    ret->enc_pkey = ASN1_OCTET_STRING_new();
+    if (ret->enc_algor == NULL || ret->enc_pkey == NULL)
+        goto err;
+
+    return ret;
+err:
+    X509_PKEY_free(ret);
+    ASN1err(ASN1_F_X509_PKEY_NEW, ERR_R_MALLOC_FAILURE);
+    return NULL;
+}
+
+void X509_PKEY_free(X509_PKEY *x)
+{
+    if (x == NULL)
+        return;
+
+    X509_ALGOR_free(x->enc_algor);
+    ASN1_OCTET_STRING_free(x->enc_pkey);
+    EVP_PKEY_free(x->dec_pkey);
+    if (x->key_free)
+        OPENSSL_free(x->key_data);
+    OPENSSL_free(x);
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_sig.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_sig.c
new file mode 100644
index 0000000..fb24e24
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_sig.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1995-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "crypto/x509.h"
+
+ASN1_SEQUENCE(X509_SIG) = {
+        ASN1_SIMPLE(X509_SIG, algor, X509_ALGOR),
+        ASN1_SIMPLE(X509_SIG, digest, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(X509_SIG)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_SIG)
+
+void X509_SIG_get0(const X509_SIG *sig, const X509_ALGOR **palg,
+                   const ASN1_OCTET_STRING **pdigest)
+{
+    if (palg)
+        *palg = sig->algor;
+    if (pdigest)
+        *pdigest = sig->digest;
+}
+
+void X509_SIG_getm(X509_SIG *sig, X509_ALGOR **palg,
+                   ASN1_OCTET_STRING **pdigest)
+{
+    if (palg)
+        *palg = sig->algor;
+    if (pdigest)
+        *pdigest = sig->digest;
+}
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_spki.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_spki.c
new file mode 100644
index 0000000..0d72a3f
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_spki.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright 1995-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/asn1t.h>
+
+ASN1_SEQUENCE(NETSCAPE_SPKAC) = {
+        ASN1_SIMPLE(NETSCAPE_SPKAC, pubkey, X509_PUBKEY),
+        ASN1_SIMPLE(NETSCAPE_SPKAC, challenge, ASN1_IA5STRING)
+} ASN1_SEQUENCE_END(NETSCAPE_SPKAC)
+
+IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKAC)
+
+ASN1_SEQUENCE(NETSCAPE_SPKI) = {
+        ASN1_SIMPLE(NETSCAPE_SPKI, spkac, NETSCAPE_SPKAC),
+        ASN1_EMBED(NETSCAPE_SPKI, sig_algor, X509_ALGOR),
+        ASN1_SIMPLE(NETSCAPE_SPKI, signature, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END(NETSCAPE_SPKI)
+
+IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKI)
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_val.c b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_val.c
new file mode 100644
index 0000000..d1f1d3b
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/asn1/x_val.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright 1995-2016 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+
+ASN1_SEQUENCE(X509_VAL) = {
+        ASN1_SIMPLE(X509_VAL, notBefore, ASN1_TIME),
+        ASN1_SIMPLE(X509_VAL, notAfter, ASN1_TIME)
+} ASN1_SEQUENCE_END(X509_VAL)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_VAL)