Test an overlong ChaCha20-Poly1305 nonce
[openssl.git] / test / exdatatest.c
1 /*
2  * Copyright 2015-2017 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 static long saved_argl;
16 static void *saved_argp;
17 static int saved_idx;
18 static int saved_idx2;
19
20 /*
21  * SIMPLE EX_DATA IMPLEMENTATION
22  * Apps explicitly set/get ex_data as needed
23  */
24
25 static void exnew(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
26           int idx, long argl, void *argp)
27 {
28     OPENSSL_assert(idx == saved_idx);
29     OPENSSL_assert(argl == saved_argl);
30     OPENSSL_assert(argp == saved_argp);
31     OPENSSL_assert(ptr == NULL);
32 }
33
34 static int exdup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
35           void *from_d, int idx, long argl, void *argp)
36 {
37     OPENSSL_assert(idx == saved_idx);
38     OPENSSL_assert(argl == saved_argl);
39     OPENSSL_assert(argp == saved_argp);
40     OPENSSL_assert(from_d != NULL);
41     return 1;
42 }
43
44 static void exfree(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
45             int idx, long argl, void *argp)
46 {
47     OPENSSL_assert(idx == saved_idx);
48     OPENSSL_assert(argl == saved_argl);
49     OPENSSL_assert(argp == saved_argp);
50 }
51
52 /*
53  * PRE-ALLOCATED EX_DATA IMPLEMENTATION
54  * Extended data structure is allocated in exnew2/freed in exfree2
55  * Data is stored inside extended data structure
56  */
57
58 typedef struct myobj_ex_data_st {
59     char *hello;
60     int new;
61     int dup;
62 } MYOBJ_EX_DATA;
63
64 static void exnew2(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
65           int idx, long argl, void *argp)
66 {
67     int ret;
68     MYOBJ_EX_DATA *ex_data;
69
70     OPENSSL_assert(idx == saved_idx2);
71     OPENSSL_assert(argl == saved_argl);
72     OPENSSL_assert(argp == saved_argp);
73     OPENSSL_assert(ptr == NULL);
74
75     ex_data = OPENSSL_zalloc(sizeof(*ex_data));
76     OPENSSL_assert(ex_data != NULL);
77     ret = CRYPTO_set_ex_data(ad, saved_idx2, ex_data);
78     OPENSSL_assert(ret);
79
80     ex_data->new = 1;
81 }
82
83 static int exdup2(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
84           void *from_d, int idx, long argl, void *argp)
85 {
86     MYOBJ_EX_DATA **update_ex_data = (MYOBJ_EX_DATA**)from_d;
87     MYOBJ_EX_DATA *ex_data = CRYPTO_get_ex_data(to, saved_idx2);
88
89     OPENSSL_assert(idx == saved_idx2);
90     OPENSSL_assert(argl == saved_argl);
91     OPENSSL_assert(argp == saved_argp);
92     OPENSSL_assert(from_d != NULL);
93     OPENSSL_assert(*update_ex_data != NULL);
94     OPENSSL_assert(ex_data != NULL);
95     OPENSSL_assert(ex_data->new);
96
97     /* Copy hello over */
98     ex_data->hello = (*update_ex_data)->hello;
99     /* indicate this is a dup */
100     ex_data->dup = 1;
101     /* Keep my original ex_data */
102     *update_ex_data = ex_data;
103     return 1;
104 }
105
106 static void exfree2(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
107             int idx, long argl, void *argp)
108 {
109     MYOBJ_EX_DATA *ex_data = CRYPTO_get_ex_data(ad, saved_idx2);
110     int ret;
111
112     OPENSSL_assert(ex_data != NULL);
113     OPENSSL_free(ex_data);
114     OPENSSL_assert(idx == saved_idx2);
115     OPENSSL_assert(argl == saved_argl);
116     OPENSSL_assert(argp == saved_argp);
117     ret = CRYPTO_set_ex_data(ad, saved_idx2, NULL);
118     OPENSSL_assert(ret);
119 }
120
121 typedef struct myobj_st {
122     CRYPTO_EX_DATA ex_data;
123     int id;
124     int st;
125 } MYOBJ;
126
127 static MYOBJ *MYOBJ_new()
128 {
129     static int count = 0;
130     MYOBJ *obj = OPENSSL_malloc(sizeof(*obj));
131
132     obj->id = ++count;
133     obj->st = CRYPTO_new_ex_data(CRYPTO_EX_INDEX_APP, obj, &obj->ex_data);
134     OPENSSL_assert(obj->st != 0);
135     return obj;
136 }
137
138 static void MYOBJ_sethello(MYOBJ *obj, char *cp)
139 {
140     obj->st = CRYPTO_set_ex_data(&obj->ex_data, saved_idx, cp);
141     OPENSSL_assert(obj->st != 0);
142 }
143
144 static char *MYOBJ_gethello(MYOBJ *obj)
145 {
146     return CRYPTO_get_ex_data(&obj->ex_data, saved_idx);
147 }
148
149 static void MYOBJ_sethello2(MYOBJ *obj, char *cp)
150 {
151     MYOBJ_EX_DATA* ex_data = CRYPTO_get_ex_data(&obj->ex_data, saved_idx2);
152     if (ex_data != NULL)
153         ex_data->hello = cp;
154     else
155         obj->st = 0;
156 }
157
158 static char *MYOBJ_gethello2(MYOBJ *obj)
159 {
160     MYOBJ_EX_DATA* ex_data = CRYPTO_get_ex_data(&obj->ex_data, saved_idx2);
161     if (ex_data != NULL)
162         return ex_data->hello;
163
164     obj->st = 0;
165     return NULL;
166 }
167
168 static void MYOBJ_free(MYOBJ *obj)
169 {
170     CRYPTO_free_ex_data(CRYPTO_EX_INDEX_APP, obj, &obj->ex_data);
171     OPENSSL_free(obj);
172 }
173
174 static MYOBJ *MYOBJ_dup(MYOBJ *in)
175 {
176     MYOBJ *obj = MYOBJ_new();
177
178     obj->st = CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_APP, &obj->ex_data,
179                                  &in->ex_data);
180     OPENSSL_assert(obj->st != 0);
181     return obj;
182 }
183
184 int main()
185 {
186     MYOBJ *t1, *t2, *t3;
187     MYOBJ_EX_DATA *ex_data;
188     const char *cp;
189     char *p;
190
191     p = OPENSSL_strdup("hello world");
192     saved_argl = 21;
193     saved_argp = OPENSSL_malloc(1);
194     saved_idx = CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_APP,
195                                         saved_argl, saved_argp,
196                                         exnew, exdup, exfree);
197     saved_idx2 = CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_APP,
198                                          saved_argl, saved_argp,
199                                          exnew2, exdup2, exfree2);
200     t1 = MYOBJ_new();
201     t2 = MYOBJ_new();
202     OPENSSL_assert(t1->st && t2->st);
203     ex_data = CRYPTO_get_ex_data(&t1->ex_data, saved_idx2);
204     OPENSSL_assert(ex_data != NULL);
205     ex_data = CRYPTO_get_ex_data(&t2->ex_data, saved_idx2);
206     OPENSSL_assert(ex_data != NULL);
207     MYOBJ_sethello(t1, p);
208     cp = MYOBJ_gethello(t1);
209     OPENSSL_assert(cp == p);
210     cp = MYOBJ_gethello(t2);
211     OPENSSL_assert(cp == NULL);
212     MYOBJ_sethello2(t1, p);
213     cp = MYOBJ_gethello2(t1);
214     OPENSSL_assert(cp == p);
215     OPENSSL_assert(t1->st);
216     cp = MYOBJ_gethello2(t2);
217     OPENSSL_assert(cp == NULL);
218     OPENSSL_assert(t2->st);
219     t3 = MYOBJ_dup(t1);
220     ex_data = CRYPTO_get_ex_data(&t3->ex_data, saved_idx2);
221     OPENSSL_assert(ex_data != NULL);
222     OPENSSL_assert(ex_data->dup);
223     cp = MYOBJ_gethello(t3);
224     OPENSSL_assert(cp == p);
225     cp = MYOBJ_gethello2(t3);
226     OPENSSL_assert(cp == p);
227     OPENSSL_assert(t3->st);
228     MYOBJ_free(t1);
229     MYOBJ_free(t2);
230     MYOBJ_free(t3);
231     OPENSSL_free(saved_argp);
232     OPENSSL_free(p);
233     return 0;
234 }