1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci#ifdef OPENSSL_NO_CT
11e1051a39Sopenharmony_ci# error "CT is disabled"
12e1051a39Sopenharmony_ci#endif
13e1051a39Sopenharmony_ci
14e1051a39Sopenharmony_ci#include <limits.h>
15e1051a39Sopenharmony_ci#include <string.h>
16e1051a39Sopenharmony_ci
17e1051a39Sopenharmony_ci#include <openssl/asn1.h>
18e1051a39Sopenharmony_ci#include <openssl/buffer.h>
19e1051a39Sopenharmony_ci#include <openssl/ct.h>
20e1051a39Sopenharmony_ci#include <openssl/err.h>
21e1051a39Sopenharmony_ci
22e1051a39Sopenharmony_ci#include "ct_local.h"
23e1051a39Sopenharmony_ci
24e1051a39Sopenharmony_ciint o2i_SCT_signature(SCT *sct, const unsigned char **in, size_t len)
25e1051a39Sopenharmony_ci{
26e1051a39Sopenharmony_ci    size_t siglen;
27e1051a39Sopenharmony_ci    size_t len_remaining = len;
28e1051a39Sopenharmony_ci    const unsigned char *p;
29e1051a39Sopenharmony_ci
30e1051a39Sopenharmony_ci    if (sct->version != SCT_VERSION_V1) {
31e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CT, CT_R_UNSUPPORTED_VERSION);
32e1051a39Sopenharmony_ci        return -1;
33e1051a39Sopenharmony_ci    }
34e1051a39Sopenharmony_ci    /*
35e1051a39Sopenharmony_ci     * digitally-signed struct header: (1 byte) Hash algorithm (1 byte)
36e1051a39Sopenharmony_ci     * Signature algorithm (2 bytes + ?) Signature
37e1051a39Sopenharmony_ci     *
38e1051a39Sopenharmony_ci     * This explicitly rejects empty signatures: they're invalid for
39e1051a39Sopenharmony_ci     * all supported algorithms.
40e1051a39Sopenharmony_ci     */
41e1051a39Sopenharmony_ci    if (len <= 4) {
42e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CT, CT_R_SCT_INVALID_SIGNATURE);
43e1051a39Sopenharmony_ci        return -1;
44e1051a39Sopenharmony_ci    }
45e1051a39Sopenharmony_ci
46e1051a39Sopenharmony_ci    p = *in;
47e1051a39Sopenharmony_ci    /* Get hash and signature algorithm */
48e1051a39Sopenharmony_ci    sct->hash_alg = *p++;
49e1051a39Sopenharmony_ci    sct->sig_alg = *p++;
50e1051a39Sopenharmony_ci    if (SCT_get_signature_nid(sct) == NID_undef) {
51e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CT, CT_R_SCT_INVALID_SIGNATURE);
52e1051a39Sopenharmony_ci        return -1;
53e1051a39Sopenharmony_ci    }
54e1051a39Sopenharmony_ci    /* Retrieve signature and check it is consistent with the buffer length */
55e1051a39Sopenharmony_ci    n2s(p, siglen);
56e1051a39Sopenharmony_ci    len_remaining -= (p - *in);
57e1051a39Sopenharmony_ci    if (siglen > len_remaining) {
58e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CT, CT_R_SCT_INVALID_SIGNATURE);
59e1051a39Sopenharmony_ci        return -1;
60e1051a39Sopenharmony_ci    }
61e1051a39Sopenharmony_ci
62e1051a39Sopenharmony_ci    if (SCT_set1_signature(sct, p, siglen) != 1)
63e1051a39Sopenharmony_ci        return -1;
64e1051a39Sopenharmony_ci    len_remaining -= siglen;
65e1051a39Sopenharmony_ci    *in = p + siglen;
66e1051a39Sopenharmony_ci
67e1051a39Sopenharmony_ci    return len - len_remaining;
68e1051a39Sopenharmony_ci}
69e1051a39Sopenharmony_ci
70e1051a39Sopenharmony_ciSCT *o2i_SCT(SCT **psct, const unsigned char **in, size_t len)
71e1051a39Sopenharmony_ci{
72e1051a39Sopenharmony_ci    SCT *sct = NULL;
73e1051a39Sopenharmony_ci    const unsigned char *p;
74e1051a39Sopenharmony_ci
75e1051a39Sopenharmony_ci    if (len == 0 || len > MAX_SCT_SIZE) {
76e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CT, CT_R_SCT_INVALID);
77e1051a39Sopenharmony_ci        goto err;
78e1051a39Sopenharmony_ci    }
79e1051a39Sopenharmony_ci
80e1051a39Sopenharmony_ci    if ((sct = SCT_new()) == NULL)
81e1051a39Sopenharmony_ci        goto err;
82e1051a39Sopenharmony_ci
83e1051a39Sopenharmony_ci    p = *in;
84e1051a39Sopenharmony_ci
85e1051a39Sopenharmony_ci    sct->version = *p;
86e1051a39Sopenharmony_ci    if (sct->version == SCT_VERSION_V1) {
87e1051a39Sopenharmony_ci        int sig_len;
88e1051a39Sopenharmony_ci        size_t len2;
89e1051a39Sopenharmony_ci        /*-
90e1051a39Sopenharmony_ci         * Fixed-length header:
91e1051a39Sopenharmony_ci         *   struct {
92e1051a39Sopenharmony_ci         *     Version sct_version;     (1 byte)
93e1051a39Sopenharmony_ci         *     log_id id;               (32 bytes)
94e1051a39Sopenharmony_ci         *     uint64 timestamp;        (8 bytes)
95e1051a39Sopenharmony_ci         *     CtExtensions extensions; (2 bytes + ?)
96e1051a39Sopenharmony_ci         *   }
97e1051a39Sopenharmony_ci         */
98e1051a39Sopenharmony_ci        if (len < 43) {
99e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_CT, CT_R_SCT_INVALID);
100e1051a39Sopenharmony_ci            goto err;
101e1051a39Sopenharmony_ci        }
102e1051a39Sopenharmony_ci        len -= 43;
103e1051a39Sopenharmony_ci        p++;
104e1051a39Sopenharmony_ci        sct->log_id = OPENSSL_memdup(p, CT_V1_HASHLEN);
105e1051a39Sopenharmony_ci        if (sct->log_id == NULL)
106e1051a39Sopenharmony_ci            goto err;
107e1051a39Sopenharmony_ci        sct->log_id_len = CT_V1_HASHLEN;
108e1051a39Sopenharmony_ci        p += CT_V1_HASHLEN;
109e1051a39Sopenharmony_ci
110e1051a39Sopenharmony_ci        n2l8(p, sct->timestamp);
111e1051a39Sopenharmony_ci
112e1051a39Sopenharmony_ci        n2s(p, len2);
113e1051a39Sopenharmony_ci        if (len < len2) {
114e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_CT, CT_R_SCT_INVALID);
115e1051a39Sopenharmony_ci            goto err;
116e1051a39Sopenharmony_ci        }
117e1051a39Sopenharmony_ci        if (len2 > 0) {
118e1051a39Sopenharmony_ci            sct->ext = OPENSSL_memdup(p, len2);
119e1051a39Sopenharmony_ci            if (sct->ext == NULL)
120e1051a39Sopenharmony_ci                goto err;
121e1051a39Sopenharmony_ci        }
122e1051a39Sopenharmony_ci        sct->ext_len = len2;
123e1051a39Sopenharmony_ci        p += len2;
124e1051a39Sopenharmony_ci        len -= len2;
125e1051a39Sopenharmony_ci
126e1051a39Sopenharmony_ci        sig_len = o2i_SCT_signature(sct, &p, len);
127e1051a39Sopenharmony_ci        if (sig_len <= 0) {
128e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_CT, CT_R_SCT_INVALID);
129e1051a39Sopenharmony_ci            goto err;
130e1051a39Sopenharmony_ci        }
131e1051a39Sopenharmony_ci        len -= sig_len;
132e1051a39Sopenharmony_ci        *in = p + len;
133e1051a39Sopenharmony_ci    } else {
134e1051a39Sopenharmony_ci        /* If not V1 just cache encoding */
135e1051a39Sopenharmony_ci        sct->sct = OPENSSL_memdup(p, len);
136e1051a39Sopenharmony_ci        if (sct->sct == NULL)
137e1051a39Sopenharmony_ci            goto err;
138e1051a39Sopenharmony_ci        sct->sct_len = len;
139e1051a39Sopenharmony_ci        *in = p + len;
140e1051a39Sopenharmony_ci    }
141e1051a39Sopenharmony_ci
142e1051a39Sopenharmony_ci    if (psct != NULL) {
143e1051a39Sopenharmony_ci        SCT_free(*psct);
144e1051a39Sopenharmony_ci        *psct = sct;
145e1051a39Sopenharmony_ci    }
146e1051a39Sopenharmony_ci
147e1051a39Sopenharmony_ci    return sct;
148e1051a39Sopenharmony_cierr:
149e1051a39Sopenharmony_ci    SCT_free(sct);
150e1051a39Sopenharmony_ci    return NULL;
151e1051a39Sopenharmony_ci}
152e1051a39Sopenharmony_ci
153e1051a39Sopenharmony_ciint i2o_SCT_signature(const SCT *sct, unsigned char **out)
154e1051a39Sopenharmony_ci{
155e1051a39Sopenharmony_ci    size_t len;
156e1051a39Sopenharmony_ci    unsigned char *p = NULL, *pstart = NULL;
157e1051a39Sopenharmony_ci
158e1051a39Sopenharmony_ci    if (!SCT_signature_is_complete(sct)) {
159e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CT, CT_R_SCT_INVALID_SIGNATURE);
160e1051a39Sopenharmony_ci        goto err;
161e1051a39Sopenharmony_ci    }
162e1051a39Sopenharmony_ci
163e1051a39Sopenharmony_ci    if (sct->version != SCT_VERSION_V1) {
164e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CT, CT_R_UNSUPPORTED_VERSION);
165e1051a39Sopenharmony_ci        goto err;
166e1051a39Sopenharmony_ci    }
167e1051a39Sopenharmony_ci
168e1051a39Sopenharmony_ci    /*
169e1051a39Sopenharmony_ci    * (1 byte) Hash algorithm
170e1051a39Sopenharmony_ci    * (1 byte) Signature algorithm
171e1051a39Sopenharmony_ci    * (2 bytes + ?) Signature
172e1051a39Sopenharmony_ci    */
173e1051a39Sopenharmony_ci    len = 4 + sct->sig_len;
174e1051a39Sopenharmony_ci
175e1051a39Sopenharmony_ci    if (out != NULL) {
176e1051a39Sopenharmony_ci        if (*out != NULL) {
177e1051a39Sopenharmony_ci            p = *out;
178e1051a39Sopenharmony_ci            *out += len;
179e1051a39Sopenharmony_ci        } else {
180e1051a39Sopenharmony_ci            pstart = p = OPENSSL_malloc(len);
181e1051a39Sopenharmony_ci            if (p == NULL) {
182e1051a39Sopenharmony_ci                ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE);
183e1051a39Sopenharmony_ci                goto err;
184e1051a39Sopenharmony_ci            }
185e1051a39Sopenharmony_ci            *out = p;
186e1051a39Sopenharmony_ci        }
187e1051a39Sopenharmony_ci
188e1051a39Sopenharmony_ci        *p++ = sct->hash_alg;
189e1051a39Sopenharmony_ci        *p++ = sct->sig_alg;
190e1051a39Sopenharmony_ci        s2n(sct->sig_len, p);
191e1051a39Sopenharmony_ci        memcpy(p, sct->sig, sct->sig_len);
192e1051a39Sopenharmony_ci    }
193e1051a39Sopenharmony_ci
194e1051a39Sopenharmony_ci    return len;
195e1051a39Sopenharmony_cierr:
196e1051a39Sopenharmony_ci    OPENSSL_free(pstart);
197e1051a39Sopenharmony_ci    return -1;
198e1051a39Sopenharmony_ci}
199e1051a39Sopenharmony_ci
200e1051a39Sopenharmony_ciint i2o_SCT(const SCT *sct, unsigned char **out)
201e1051a39Sopenharmony_ci{
202e1051a39Sopenharmony_ci    size_t len;
203e1051a39Sopenharmony_ci    unsigned char *p = NULL, *pstart = NULL;
204e1051a39Sopenharmony_ci
205e1051a39Sopenharmony_ci    if (!SCT_is_complete(sct)) {
206e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CT, CT_R_SCT_NOT_SET);
207e1051a39Sopenharmony_ci        goto err;
208e1051a39Sopenharmony_ci    }
209e1051a39Sopenharmony_ci    /*
210e1051a39Sopenharmony_ci     * Fixed-length header: struct { (1 byte) Version sct_version; (32 bytes)
211e1051a39Sopenharmony_ci     * log_id id; (8 bytes) uint64 timestamp; (2 bytes + ?) CtExtensions
212e1051a39Sopenharmony_ci     * extensions; (1 byte) Hash algorithm (1 byte) Signature algorithm (2
213e1051a39Sopenharmony_ci     * bytes + ?) Signature
214e1051a39Sopenharmony_ci     */
215e1051a39Sopenharmony_ci    if (sct->version == SCT_VERSION_V1)
216e1051a39Sopenharmony_ci        len = 43 + sct->ext_len + 4 + sct->sig_len;
217e1051a39Sopenharmony_ci    else
218e1051a39Sopenharmony_ci        len = sct->sct_len;
219e1051a39Sopenharmony_ci
220e1051a39Sopenharmony_ci    if (out == NULL)
221e1051a39Sopenharmony_ci        return len;
222e1051a39Sopenharmony_ci
223e1051a39Sopenharmony_ci    if (*out != NULL) {
224e1051a39Sopenharmony_ci        p = *out;
225e1051a39Sopenharmony_ci        *out += len;
226e1051a39Sopenharmony_ci    } else {
227e1051a39Sopenharmony_ci        pstart = p = OPENSSL_malloc(len);
228e1051a39Sopenharmony_ci        if (p == NULL) {
229e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE);
230e1051a39Sopenharmony_ci            goto err;
231e1051a39Sopenharmony_ci        }
232e1051a39Sopenharmony_ci        *out = p;
233e1051a39Sopenharmony_ci    }
234e1051a39Sopenharmony_ci
235e1051a39Sopenharmony_ci    if (sct->version == SCT_VERSION_V1) {
236e1051a39Sopenharmony_ci        *p++ = sct->version;
237e1051a39Sopenharmony_ci        memcpy(p, sct->log_id, CT_V1_HASHLEN);
238e1051a39Sopenharmony_ci        p += CT_V1_HASHLEN;
239e1051a39Sopenharmony_ci        l2n8(sct->timestamp, p);
240e1051a39Sopenharmony_ci        s2n(sct->ext_len, p);
241e1051a39Sopenharmony_ci        if (sct->ext_len > 0) {
242e1051a39Sopenharmony_ci            memcpy(p, sct->ext, sct->ext_len);
243e1051a39Sopenharmony_ci            p += sct->ext_len;
244e1051a39Sopenharmony_ci        }
245e1051a39Sopenharmony_ci        if (i2o_SCT_signature(sct, &p) <= 0)
246e1051a39Sopenharmony_ci            goto err;
247e1051a39Sopenharmony_ci    } else {
248e1051a39Sopenharmony_ci        memcpy(p, sct->sct, len);
249e1051a39Sopenharmony_ci    }
250e1051a39Sopenharmony_ci
251e1051a39Sopenharmony_ci    return len;
252e1051a39Sopenharmony_cierr:
253e1051a39Sopenharmony_ci    OPENSSL_free(pstart);
254e1051a39Sopenharmony_ci    return -1;
255e1051a39Sopenharmony_ci}
256e1051a39Sopenharmony_ci
257e1051a39Sopenharmony_ciSTACK_OF(SCT) *o2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp,
258e1051a39Sopenharmony_ci                            size_t len)
259e1051a39Sopenharmony_ci{
260e1051a39Sopenharmony_ci    STACK_OF(SCT) *sk = NULL;
261e1051a39Sopenharmony_ci    size_t list_len, sct_len;
262e1051a39Sopenharmony_ci
263e1051a39Sopenharmony_ci    if (len < 2 || len > MAX_SCT_LIST_SIZE) {
264e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CT, CT_R_SCT_LIST_INVALID);
265e1051a39Sopenharmony_ci        return NULL;
266e1051a39Sopenharmony_ci    }
267e1051a39Sopenharmony_ci
268e1051a39Sopenharmony_ci    n2s(*pp, list_len);
269e1051a39Sopenharmony_ci    if (list_len != len - 2) {
270e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CT, CT_R_SCT_LIST_INVALID);
271e1051a39Sopenharmony_ci        return NULL;
272e1051a39Sopenharmony_ci    }
273e1051a39Sopenharmony_ci
274e1051a39Sopenharmony_ci    if (a == NULL || *a == NULL) {
275e1051a39Sopenharmony_ci        sk = sk_SCT_new_null();
276e1051a39Sopenharmony_ci        if (sk == NULL)
277e1051a39Sopenharmony_ci            return NULL;
278e1051a39Sopenharmony_ci    } else {
279e1051a39Sopenharmony_ci        SCT *sct;
280e1051a39Sopenharmony_ci
281e1051a39Sopenharmony_ci        /* Use the given stack, but empty it first. */
282e1051a39Sopenharmony_ci        sk = *a;
283e1051a39Sopenharmony_ci        while ((sct = sk_SCT_pop(sk)) != NULL)
284e1051a39Sopenharmony_ci            SCT_free(sct);
285e1051a39Sopenharmony_ci    }
286e1051a39Sopenharmony_ci
287e1051a39Sopenharmony_ci    while (list_len > 0) {
288e1051a39Sopenharmony_ci        SCT *sct;
289e1051a39Sopenharmony_ci
290e1051a39Sopenharmony_ci        if (list_len < 2) {
291e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_CT, CT_R_SCT_LIST_INVALID);
292e1051a39Sopenharmony_ci            goto err;
293e1051a39Sopenharmony_ci        }
294e1051a39Sopenharmony_ci        n2s(*pp, sct_len);
295e1051a39Sopenharmony_ci        list_len -= 2;
296e1051a39Sopenharmony_ci
297e1051a39Sopenharmony_ci        if (sct_len == 0 || sct_len > list_len) {
298e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_CT, CT_R_SCT_LIST_INVALID);
299e1051a39Sopenharmony_ci            goto err;
300e1051a39Sopenharmony_ci        }
301e1051a39Sopenharmony_ci        list_len -= sct_len;
302e1051a39Sopenharmony_ci
303e1051a39Sopenharmony_ci        if ((sct = o2i_SCT(NULL, pp, sct_len)) == NULL)
304e1051a39Sopenharmony_ci            goto err;
305e1051a39Sopenharmony_ci        if (!sk_SCT_push(sk, sct)) {
306e1051a39Sopenharmony_ci            SCT_free(sct);
307e1051a39Sopenharmony_ci            goto err;
308e1051a39Sopenharmony_ci        }
309e1051a39Sopenharmony_ci    }
310e1051a39Sopenharmony_ci
311e1051a39Sopenharmony_ci    if (a != NULL && *a == NULL)
312e1051a39Sopenharmony_ci        *a = sk;
313e1051a39Sopenharmony_ci    return sk;
314e1051a39Sopenharmony_ci
315e1051a39Sopenharmony_ci err:
316e1051a39Sopenharmony_ci    if (a == NULL || *a == NULL)
317e1051a39Sopenharmony_ci        SCT_LIST_free(sk);
318e1051a39Sopenharmony_ci    return NULL;
319e1051a39Sopenharmony_ci}
320e1051a39Sopenharmony_ci
321e1051a39Sopenharmony_ciint i2o_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp)
322e1051a39Sopenharmony_ci{
323e1051a39Sopenharmony_ci    int len, sct_len, i, is_pp_new = 0;
324e1051a39Sopenharmony_ci    size_t len2;
325e1051a39Sopenharmony_ci    unsigned char *p = NULL, *p2;
326e1051a39Sopenharmony_ci
327e1051a39Sopenharmony_ci    if (pp != NULL) {
328e1051a39Sopenharmony_ci        if (*pp == NULL) {
329e1051a39Sopenharmony_ci            if ((len = i2o_SCT_LIST(a, NULL)) == -1) {
330e1051a39Sopenharmony_ci                ERR_raise(ERR_LIB_CT, CT_R_SCT_LIST_INVALID);
331e1051a39Sopenharmony_ci                return -1;
332e1051a39Sopenharmony_ci            }
333e1051a39Sopenharmony_ci            if ((*pp = OPENSSL_malloc(len)) == NULL) {
334e1051a39Sopenharmony_ci                ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE);
335e1051a39Sopenharmony_ci                return -1;
336e1051a39Sopenharmony_ci            }
337e1051a39Sopenharmony_ci            is_pp_new = 1;
338e1051a39Sopenharmony_ci        }
339e1051a39Sopenharmony_ci        p = *pp + 2;
340e1051a39Sopenharmony_ci    }
341e1051a39Sopenharmony_ci
342e1051a39Sopenharmony_ci    len2 = 2;
343e1051a39Sopenharmony_ci    for (i = 0; i < sk_SCT_num(a); i++) {
344e1051a39Sopenharmony_ci        if (pp != NULL) {
345e1051a39Sopenharmony_ci            p2 = p;
346e1051a39Sopenharmony_ci            p += 2;
347e1051a39Sopenharmony_ci            if ((sct_len = i2o_SCT(sk_SCT_value(a, i), &p)) == -1)
348e1051a39Sopenharmony_ci                goto err;
349e1051a39Sopenharmony_ci            s2n(sct_len, p2);
350e1051a39Sopenharmony_ci        } else {
351e1051a39Sopenharmony_ci          if ((sct_len = i2o_SCT(sk_SCT_value(a, i), NULL)) == -1)
352e1051a39Sopenharmony_ci              goto err;
353e1051a39Sopenharmony_ci        }
354e1051a39Sopenharmony_ci        len2 += 2 + sct_len;
355e1051a39Sopenharmony_ci    }
356e1051a39Sopenharmony_ci
357e1051a39Sopenharmony_ci    if (len2 > MAX_SCT_LIST_SIZE)
358e1051a39Sopenharmony_ci        goto err;
359e1051a39Sopenharmony_ci
360e1051a39Sopenharmony_ci    if (pp != NULL) {
361e1051a39Sopenharmony_ci        p = *pp;
362e1051a39Sopenharmony_ci        s2n(len2 - 2, p);
363e1051a39Sopenharmony_ci        if (!is_pp_new)
364e1051a39Sopenharmony_ci            *pp += len2;
365e1051a39Sopenharmony_ci    }
366e1051a39Sopenharmony_ci    return len2;
367e1051a39Sopenharmony_ci
368e1051a39Sopenharmony_ci err:
369e1051a39Sopenharmony_ci    if (is_pp_new) {
370e1051a39Sopenharmony_ci        OPENSSL_free(*pp);
371e1051a39Sopenharmony_ci        *pp = NULL;
372e1051a39Sopenharmony_ci    }
373e1051a39Sopenharmony_ci    return -1;
374e1051a39Sopenharmony_ci}
375e1051a39Sopenharmony_ci
376e1051a39Sopenharmony_ciSTACK_OF(SCT) *d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp,
377e1051a39Sopenharmony_ci                            long len)
378e1051a39Sopenharmony_ci{
379e1051a39Sopenharmony_ci    ASN1_OCTET_STRING *oct = NULL;
380e1051a39Sopenharmony_ci    STACK_OF(SCT) *sk = NULL;
381e1051a39Sopenharmony_ci    const unsigned char *p;
382e1051a39Sopenharmony_ci
383e1051a39Sopenharmony_ci    p = *pp;
384e1051a39Sopenharmony_ci    if (d2i_ASN1_OCTET_STRING(&oct, &p, len) == NULL)
385e1051a39Sopenharmony_ci        return NULL;
386e1051a39Sopenharmony_ci
387e1051a39Sopenharmony_ci    p = oct->data;
388e1051a39Sopenharmony_ci    if ((sk = o2i_SCT_LIST(a, &p, oct->length)) != NULL)
389e1051a39Sopenharmony_ci        *pp += len;
390e1051a39Sopenharmony_ci
391e1051a39Sopenharmony_ci    ASN1_OCTET_STRING_free(oct);
392e1051a39Sopenharmony_ci    return sk;
393e1051a39Sopenharmony_ci}
394e1051a39Sopenharmony_ci
395e1051a39Sopenharmony_ciint i2d_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **out)
396e1051a39Sopenharmony_ci{
397e1051a39Sopenharmony_ci    ASN1_OCTET_STRING oct;
398e1051a39Sopenharmony_ci    int len;
399e1051a39Sopenharmony_ci
400e1051a39Sopenharmony_ci    oct.data = NULL;
401e1051a39Sopenharmony_ci    if ((oct.length = i2o_SCT_LIST(a, &oct.data)) == -1)
402e1051a39Sopenharmony_ci        return -1;
403e1051a39Sopenharmony_ci
404e1051a39Sopenharmony_ci    len = i2d_ASN1_OCTET_STRING(&oct, out);
405e1051a39Sopenharmony_ci    OPENSSL_free(oct.data);
406e1051a39Sopenharmony_ci    return len;
407e1051a39Sopenharmony_ci}
408