exdatatest.c 6.7 KB
Newer Older
R
Rich Salz 已提交
1
/*
R
Rich Salz 已提交
2
 * Copyright 2015-2017 The OpenSSL Project Authors. All Rights Reserved.
3
 *
R
Rich Salz 已提交
4 5 6 7
 * 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
8
 */
R
Rich Salz 已提交
9

10 11 12 13 14
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/crypto.h>

15 16
#include "testutil.h"

R
Rich Salz 已提交
17 18 19
static long saved_argl;
static void *saved_argp;
static int saved_idx;
T
Todd Short 已提交
20
static int saved_idx2;
21
static int gbl_result;
22

T
Todd Short 已提交
23 24 25 26 27
/*
 * SIMPLE EX_DATA IMPLEMENTATION
 * Apps explicitly set/get ex_data as needed
 */

28 29 30
static void exnew(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
          int idx, long argl, void *argp)
{
31 32 33 34 35
    if (!TEST_int_eq(idx, saved_idx)
        || !TEST_long_eq(argl, saved_argl)
        || !TEST_ptr_eq(argp, saved_argp)
        || !TEST_ptr_null(ptr))
        gbl_result = 0;
36 37
}

R
Rich Salz 已提交
38
static int exdup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
39 40
          void *from_d, int idx, long argl, void *argp)
{
41 42 43 44 45
    if (!TEST_int_eq(idx, saved_idx)
        || !TEST_long_eq(argl, saved_argl)
        || !TEST_ptr_eq(argp, saved_argp)
        || !TEST_ptr(from_d))
        gbl_result = 0;
46
    return 1;
47 48 49 50 51
}

static void exfree(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
            int idx, long argl, void *argp)
{
52 53 54 55
    if (!TEST_int_eq(idx, saved_idx)
        || !TEST_long_eq(argl, saved_argl)
        || !TEST_ptr_eq(argp, saved_argp))
        gbl_result = 0;
56 57
}

T
Todd Short 已提交
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
/*
 * PRE-ALLOCATED EX_DATA IMPLEMENTATION
 * Extended data structure is allocated in exnew2/freed in exfree2
 * Data is stored inside extended data structure
 */

typedef struct myobj_ex_data_st {
    char *hello;
    int new;
    int dup;
} MYOBJ_EX_DATA;

static void exnew2(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
          int idx, long argl, void *argp)
{
    MYOBJ_EX_DATA *ex_data = OPENSSL_zalloc(sizeof(*ex_data));
    if (!TEST_int_eq(idx, saved_idx2)
        || !TEST_long_eq(argl, saved_argl)
        || !TEST_ptr_eq(argp, saved_argp)
        || !TEST_ptr_null(ptr)
        || !TEST_ptr(ex_data)
        || !TEST_true(CRYPTO_set_ex_data(ad, saved_idx2, ex_data))) {
        gbl_result = 0;
        OPENSSL_free(ex_data);
    } else {
        ex_data->new = 1;
    }
}

static int exdup2(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
          void *from_d, int idx, long argl, void *argp)
{
    MYOBJ_EX_DATA **update_ex_data = (MYOBJ_EX_DATA**)from_d;
    MYOBJ_EX_DATA *ex_data = CRYPTO_get_ex_data(to, saved_idx2);
    if (!TEST_int_eq(idx, saved_idx2)
        || !TEST_long_eq(argl, saved_argl)
        || !TEST_ptr_eq(argp, saved_argp)
        || !TEST_ptr(from_d)
        || !TEST_ptr(*update_ex_data)
        || !TEST_ptr(ex_data)
        || !TEST_true(ex_data->new)) {
        gbl_result = 0;
    } else {
        /* Copy hello over */
        ex_data->hello = (*update_ex_data)->hello;
        /* indicate this is a dup */
        ex_data->dup = 1;
        /* Keep my original ex_data */
        *update_ex_data = ex_data;
    }
    return 1;
}

static void exfree2(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
            int idx, long argl, void *argp)
{
    MYOBJ_EX_DATA *ex_data = CRYPTO_get_ex_data(ad, saved_idx2);
    OPENSSL_free(ex_data);
    if (!TEST_int_eq(idx, saved_idx2)
        || !TEST_long_eq(argl, saved_argl)
        || !TEST_ptr_eq(argp, saved_argp)
        || !TEST_ptr(ex_data)
        || !TEST_true(CRYPTO_set_ex_data(ad, saved_idx2, NULL)))
        gbl_result = 0;
}

124 125 126
typedef struct myobj_st {
    CRYPTO_EX_DATA ex_data;
    int id;
R
Rich Salz 已提交
127
    int st;
128 129 130 131 132 133 134 135
} MYOBJ;

static MYOBJ *MYOBJ_new()
{
    static int count = 0;
    MYOBJ *obj = OPENSSL_malloc(sizeof(*obj));

    obj->id = ++count;
R
Rich Salz 已提交
136
    obj->st = CRYPTO_new_ex_data(CRYPTO_EX_INDEX_APP, obj, &obj->ex_data);
137 138 139 140 141
    return obj;
}

static void MYOBJ_sethello(MYOBJ *obj, char *cp)
{
R
Rich Salz 已提交
142
    obj->st = CRYPTO_set_ex_data(&obj->ex_data, saved_idx, cp);
143 144
    if (!TEST_int_eq(obj->st, 1))
        gbl_result = 0;
145 146 147 148
}

static char *MYOBJ_gethello(MYOBJ *obj)
{
R
Rich Salz 已提交
149
    return CRYPTO_get_ex_data(&obj->ex_data, saved_idx);
150 151
}

T
Todd Short 已提交
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
static void MYOBJ_sethello2(MYOBJ *obj, char *cp)
{
    MYOBJ_EX_DATA* ex_data = CRYPTO_get_ex_data(&obj->ex_data, saved_idx2);
    if (TEST_ptr(ex_data))
        ex_data->hello = cp;
    else
        obj->st = gbl_result = 0;
}

static char *MYOBJ_gethello2(MYOBJ *obj)
{
    MYOBJ_EX_DATA* ex_data = CRYPTO_get_ex_data(&obj->ex_data, saved_idx2);
    if (TEST_ptr(ex_data))
        return ex_data->hello;

    obj->st = gbl_result = 0;
    return NULL;
}

171 172 173 174 175 176
static void MYOBJ_free(MYOBJ *obj)
{
    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_APP, obj, &obj->ex_data);
    OPENSSL_free(obj);
}

177 178 179 180
static MYOBJ *MYOBJ_dup(MYOBJ *in)
{
    MYOBJ *obj = MYOBJ_new();

181
    obj->st |= CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_APP, &obj->ex_data,
182 183 184 185
                                 &in->ex_data);
    return obj;
}

186
static int test_exdata(void)
187
{
188
    MYOBJ *t1, *t2, *t3;
T
Todd Short 已提交
189
    MYOBJ_EX_DATA *ex_data;
190 191 192
    const char *cp;
    char *p;

193 194
    gbl_result = 1;

T
Todd Short 已提交
195
    p = OPENSSL_strdup("hello world");
R
Rich Salz 已提交
196
    saved_argl = 21;
T
Todd Short 已提交
197
    saved_argp = OPENSSL_malloc(1);
R
Rich Salz 已提交
198 199 200
    saved_idx = CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_APP,
                                        saved_argl, saved_argp,
                                        exnew, exdup, exfree);
T
Todd Short 已提交
201 202 203
    saved_idx2 = CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_APP,
                                         saved_argl, saved_argp,
                                         exnew2, exdup2, exfree2);
204 205
    t1 = MYOBJ_new();
    t2 = MYOBJ_new();
206 207
    if (!TEST_int_eq(t1->st, 1) || !TEST_int_eq(t2->st, 1))
        return 0;
T
Todd Short 已提交
208 209 210 211
    if (!TEST_ptr(CRYPTO_get_ex_data(&t1->ex_data, saved_idx2)))
        return 0;
    if (!TEST_ptr(CRYPTO_get_ex_data(&t2->ex_data, saved_idx2)))
        return 0;
212

213 214
    MYOBJ_sethello(t1, p);
    cp = MYOBJ_gethello(t1);
215 216 217
    if (!TEST_ptr_eq(cp, p))
        return 0;

T
Todd Short 已提交
218 219 220 221 222
    MYOBJ_sethello2(t1, p);
    cp = MYOBJ_gethello2(t1);
    if (!TEST_ptr_eq(cp, p))
        return 0;

223
    cp = MYOBJ_gethello(t2);
224 225 226
    if (!TEST_ptr_null(cp))
        return 0;

T
Todd Short 已提交
227 228 229 230
    cp = MYOBJ_gethello2(t2);
    if (!TEST_ptr_null(cp))
        return 0;

231
    t3 = MYOBJ_dup(t1);
232 233 234
    if (!TEST_int_eq(t3->st, 1))
        return 0;

T
Todd Short 已提交
235 236 237 238 239 240
    ex_data = CRYPTO_get_ex_data(&t3->ex_data, saved_idx2);
    if (!TEST_ptr(ex_data))
        return 0;
    if (!TEST_int_eq(ex_data->dup, 1))
        return 0;

241
    cp = MYOBJ_gethello(t3);
242 243 244
    if (!TEST_ptr_eq(cp, p))
        return 0;

T
Todd Short 已提交
245 246 247 248
    cp = MYOBJ_gethello2(t3);
    if (!TEST_ptr_eq(cp, p))
        return 0;

249 250
    MYOBJ_free(t1);
    MYOBJ_free(t2);
251
    MYOBJ_free(t3);
T
Todd Short 已提交
252 253
    OPENSSL_free(saved_argp);
    OPENSSL_free(p);
254 255 256 257 258 259 260 261 262 263

    if (gbl_result)
      return 1;
    else
      return 0;
}

void register_tests(void)
{
    ADD_TEST(test_exdata);
264
}