Home | History | Annotate | Line # | Download | only in test
      1 /*
      2  * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the OpenSSL license (the "License").  You may not use
      5  * this file except in compliance with the License.  You can obtain a copy
      6  * in the file LICENSE in the source distribution or at
      7  * https://www.openssl.org/source/license.html
      8  */
      9 
     10 #include <stdio.h>
     11 #include <string.h>
     12 #include <stdlib.h>
     13 #include <openssl/crypto.h>
     14 
     15 #include "testutil.h"
     16 
     17 static long saved_argl;
     18 static void *saved_argp;
     19 static int saved_idx;
     20 static int saved_idx2;
     21 static int gbl_result;
     22 
     23 /*
     24  * SIMPLE EX_DATA IMPLEMENTATION
     25  * Apps explicitly set/get ex_data as needed
     26  */
     27 
     28 static void exnew(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
     29           int idx, long argl, void *argp)
     30 {
     31     if (!TEST_int_eq(idx, saved_idx)
     32         || !TEST_long_eq(argl, saved_argl)
     33         || !TEST_ptr_eq(argp, saved_argp)
     34         || !TEST_ptr_null(ptr))
     35         gbl_result = 0;
     36 }
     37 
     38 static int exdup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
     39           void *from_d, int idx, long argl, void *argp)
     40 {
     41     if (!TEST_int_eq(idx, saved_idx)
     42         || !TEST_long_eq(argl, saved_argl)
     43         || !TEST_ptr_eq(argp, saved_argp)
     44         || !TEST_ptr(from_d))
     45         gbl_result = 0;
     46     return 1;
     47 }
     48 
     49 static void exfree(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
     50             int idx, long argl, void *argp)
     51 {
     52     if (!TEST_int_eq(idx, saved_idx)
     53         || !TEST_long_eq(argl, saved_argl)
     54         || !TEST_ptr_eq(argp, saved_argp))
     55         gbl_result = 0;
     56 }
     57 
     58 /*
     59  * PRE-ALLOCATED EX_DATA IMPLEMENTATION
     60  * Extended data structure is allocated in exnew2/freed in exfree2
     61  * Data is stored inside extended data structure
     62  */
     63 
     64 typedef struct myobj_ex_data_st {
     65     char *hello;
     66     int new;
     67     int dup;
     68 } MYOBJ_EX_DATA;
     69 
     70 static void exnew2(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
     71           int idx, long argl, void *argp)
     72 {
     73     MYOBJ_EX_DATA *ex_data = OPENSSL_zalloc(sizeof(*ex_data));
     74     if (!TEST_int_eq(idx, saved_idx2)
     75         || !TEST_long_eq(argl, saved_argl)
     76         || !TEST_ptr_eq(argp, saved_argp)
     77         || !TEST_ptr_null(ptr)
     78         || !TEST_ptr(ex_data)
     79         || !TEST_true(CRYPTO_set_ex_data(ad, saved_idx2, ex_data))) {
     80         gbl_result = 0;
     81         OPENSSL_free(ex_data);
     82     } else {
     83         ex_data->new = 1;
     84     }
     85 }
     86 
     87 static int exdup2(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
     88           void *from_d, int idx, long argl, void *argp)
     89 {
     90     MYOBJ_EX_DATA **update_ex_data = (MYOBJ_EX_DATA**)from_d;
     91     MYOBJ_EX_DATA *ex_data = CRYPTO_get_ex_data(to, saved_idx2);
     92     if (!TEST_int_eq(idx, saved_idx2)
     93         || !TEST_long_eq(argl, saved_argl)
     94         || !TEST_ptr_eq(argp, saved_argp)
     95         || !TEST_ptr(from_d)
     96         || !TEST_ptr(*update_ex_data)
     97         || !TEST_ptr(ex_data)
     98         || !TEST_true(ex_data->new)) {
     99         gbl_result = 0;
    100     } else {
    101         /* Copy hello over */
    102         ex_data->hello = (*update_ex_data)->hello;
    103         /* indicate this is a dup */
    104         ex_data->dup = 1;
    105         /* Keep my original ex_data */
    106         *update_ex_data = ex_data;
    107     }
    108     return 1;
    109 }
    110 
    111 static void exfree2(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
    112             int idx, long argl, void *argp)
    113 {
    114     MYOBJ_EX_DATA *ex_data = CRYPTO_get_ex_data(ad, saved_idx2);
    115     OPENSSL_free(ex_data);
    116     if (!TEST_int_eq(idx, saved_idx2)
    117         || !TEST_long_eq(argl, saved_argl)
    118         || !TEST_ptr_eq(argp, saved_argp)
    119         || !TEST_ptr(ex_data)
    120         || !TEST_true(CRYPTO_set_ex_data(ad, saved_idx2, NULL)))
    121         gbl_result = 0;
    122 }
    123 
    124 typedef struct myobj_st {
    125     CRYPTO_EX_DATA ex_data;
    126     int id;
    127     int st;
    128 } MYOBJ;
    129 
    130 static MYOBJ *MYOBJ_new(void)
    131 {
    132     static int count = 0;
    133     MYOBJ *obj = OPENSSL_malloc(sizeof(*obj));
    134 
    135     obj->id = ++count;
    136     obj->st = CRYPTO_new_ex_data(CRYPTO_EX_INDEX_APP, obj, &obj->ex_data);
    137     return obj;
    138 }
    139 
    140 static void MYOBJ_sethello(MYOBJ *obj, char *cp)
    141 {
    142     obj->st = CRYPTO_set_ex_data(&obj->ex_data, saved_idx, cp);
    143     if (!TEST_int_eq(obj->st, 1))
    144         gbl_result = 0;
    145 }
    146 
    147 static char *MYOBJ_gethello(MYOBJ *obj)
    148 {
    149     return CRYPTO_get_ex_data(&obj->ex_data, saved_idx);
    150 }
    151 
    152 static void MYOBJ_sethello2(MYOBJ *obj, char *cp)
    153 {
    154     MYOBJ_EX_DATA* ex_data = CRYPTO_get_ex_data(&obj->ex_data, saved_idx2);
    155     if (TEST_ptr(ex_data))
    156         ex_data->hello = cp;
    157     else
    158         obj->st = gbl_result = 0;
    159 }
    160 
    161 static char *MYOBJ_gethello2(MYOBJ *obj)
    162 {
    163     MYOBJ_EX_DATA* ex_data = CRYPTO_get_ex_data(&obj->ex_data, saved_idx2);
    164     if (TEST_ptr(ex_data))
    165         return ex_data->hello;
    166 
    167     obj->st = gbl_result = 0;
    168     return NULL;
    169 }
    170 
    171 static void MYOBJ_free(MYOBJ *obj)
    172 {
    173     CRYPTO_free_ex_data(CRYPTO_EX_INDEX_APP, obj, &obj->ex_data);
    174     OPENSSL_free(obj);
    175 }
    176 
    177 static MYOBJ *MYOBJ_dup(MYOBJ *in)
    178 {
    179     MYOBJ *obj = MYOBJ_new();
    180 
    181     obj->st |= CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_APP, &obj->ex_data,
    182                                  &in->ex_data);
    183     return obj;
    184 }
    185 
    186 static int test_exdata(void)
    187 {
    188     MYOBJ *t1, *t2, *t3;
    189     MYOBJ_EX_DATA *ex_data;
    190     const char *cp;
    191     char *p;
    192 
    193     gbl_result = 1;
    194 
    195     p = OPENSSL_strdup("hello world");
    196     saved_argl = 21;
    197     saved_argp = OPENSSL_malloc(1);
    198     saved_idx = CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_APP,
    199                                         saved_argl, saved_argp,
    200                                         exnew, exdup, exfree);
    201     saved_idx2 = CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_APP,
    202                                          saved_argl, saved_argp,
    203                                          exnew2, exdup2, exfree2);
    204     t1 = MYOBJ_new();
    205     t2 = MYOBJ_new();
    206     if (!TEST_int_eq(t1->st, 1) || !TEST_int_eq(t2->st, 1))
    207         return 0;
    208     if (!TEST_ptr(CRYPTO_get_ex_data(&t1->ex_data, saved_idx2)))
    209         return 0;
    210     if (!TEST_ptr(CRYPTO_get_ex_data(&t2->ex_data, saved_idx2)))
    211         return 0;
    212 
    213     MYOBJ_sethello(t1, p);
    214     cp = MYOBJ_gethello(t1);
    215     if (!TEST_ptr_eq(cp, p))
    216         return 0;
    217 
    218     MYOBJ_sethello2(t1, p);
    219     cp = MYOBJ_gethello2(t1);
    220     if (!TEST_ptr_eq(cp, p))
    221         return 0;
    222 
    223     cp = MYOBJ_gethello(t2);
    224     if (!TEST_ptr_null(cp))
    225         return 0;
    226 
    227     cp = MYOBJ_gethello2(t2);
    228     if (!TEST_ptr_null(cp))
    229         return 0;
    230 
    231     t3 = MYOBJ_dup(t1);
    232     if (!TEST_int_eq(t3->st, 1))
    233         return 0;
    234 
    235     ex_data = CRYPTO_get_ex_data(&t3->ex_data, saved_idx2);
    236     if (!TEST_ptr(ex_data))
    237         return 0;
    238     if (!TEST_int_eq(ex_data->dup, 1))
    239         return 0;
    240 
    241     cp = MYOBJ_gethello(t3);
    242     if (!TEST_ptr_eq(cp, p))
    243         return 0;
    244 
    245     cp = MYOBJ_gethello2(t3);
    246     if (!TEST_ptr_eq(cp, p))
    247         return 0;
    248 
    249     MYOBJ_free(t1);
    250     MYOBJ_free(t2);
    251     MYOBJ_free(t3);
    252     OPENSSL_free(saved_argp);
    253     OPENSSL_free(p);
    254 
    255     if (gbl_result)
    256       return 1;
    257     else
    258       return 0;
    259 }
    260 
    261 int setup_tests(void)
    262 {
    263     ADD_TEST(test_exdata);
    264     return 1;
    265 }
    266