xref: /openssl/test/bio_addr_test.c (revision 581c87b0)
1 /*
2  * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (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 <openssl/bio.h>
11 #include "internal/e_os.h"
12 #include "internal/sockets.h"
13 #include "testutil.h"
14 
15 static int families[] = {
16     AF_INET,
17 #if OPENSSL_USE_IPV6
18     AF_INET6,
19 #endif
20 #ifndef OPENSSL_NO_UNIX_SOCK
21     AF_UNIX
22 #endif
23 };
24 
make_dummy_addr(int family)25 static BIO_ADDR *make_dummy_addr(int family)
26 {
27     BIO_ADDR *addr;
28     union {
29         struct sockaddr_in sin;
30 #if OPENSSL_USE_IPV6
31         struct sockaddr_in6 sin6;
32 #endif
33 #ifndef OPENSSL_NO_UNIX_SOCK
34         struct sockaddr_un sunaddr;
35 #endif
36     } sa;
37     void *where;
38     size_t wherelen;
39 
40     /* Fill with a dummy address */
41     switch(family) {
42     case AF_INET:
43         where = &(sa.sin.sin_addr);
44         wherelen = sizeof(sa.sin.sin_addr);
45         break;
46 #if OPENSSL_USE_IPV6
47     case AF_INET6:
48         where = &(sa.sin6.sin6_addr);
49         wherelen = sizeof(sa.sin6.sin6_addr);
50         break;
51 #endif
52 #ifndef OPENSSL_NO_UNIX_SOCK
53     case AF_UNIX:
54         where = &(sa.sunaddr.sun_path);
55         /* BIO_ADDR_rawmake needs an extra byte for a NUL-terminator*/
56         wherelen = sizeof(sa.sunaddr.sun_path) - 1;
57         break;
58 #endif
59     default:
60         TEST_error("Unsupported address family");
61         return 0;
62     }
63     /*
64      * Could be any data, but we make it printable because BIO_ADDR_rawmake
65      * expects the AF_UNIX address to be a string.
66      */
67     memset(where, 'a', wherelen);
68 
69     addr = BIO_ADDR_new();
70     if (!TEST_ptr(addr))
71         return NULL;
72 
73     if (!TEST_true(BIO_ADDR_rawmake(addr, family, where, wherelen, 1000))) {
74         BIO_ADDR_free(addr);
75         return NULL;
76     }
77 
78     return addr;
79 }
80 
bio_addr_is_eq(const BIO_ADDR * a,const BIO_ADDR * b)81 static int bio_addr_is_eq(const BIO_ADDR *a, const BIO_ADDR *b)
82 {
83     unsigned char *adata = NULL, *bdata = NULL;
84     size_t alen, blen;
85     int ret = 0;
86 
87     /* True even if a and b are NULL */
88     if (a == b)
89         return 1;
90 
91     /* If one is NULL the other cannot be due to the test above */
92     if (a == NULL || b == NULL)
93         return 0;
94 
95     if (BIO_ADDR_family(a) != BIO_ADDR_family(b))
96         return 0;
97 
98     /* Works even with AF_UNIX/AF_UNSPEC which just returns 0 */
99     if (BIO_ADDR_rawport(a) != BIO_ADDR_rawport(b))
100         return 0;
101 
102     if (!BIO_ADDR_rawaddress(a, NULL, &alen))
103         return 0;
104 
105     if (!BIO_ADDR_rawaddress(b, NULL, &blen))
106         goto err;
107 
108     if (alen != blen)
109         return 0;
110 
111     if (alen == 0)
112         return 1;
113 
114     adata = OPENSSL_malloc(alen);
115     if (!TEST_ptr(adata)
116             || !BIO_ADDR_rawaddress(a, adata, &alen))
117         goto err;
118 
119     bdata = OPENSSL_malloc(blen);
120     if (!TEST_ptr(bdata)
121             || !BIO_ADDR_rawaddress(b, bdata, &blen))
122         goto err;
123 
124     ret = (memcmp(adata, bdata, alen) == 0);
125 
126  err:
127     OPENSSL_free(adata);
128     OPENSSL_free(bdata);
129     return ret;
130 }
131 
test_bio_addr_copy_dup(int idx)132 static int test_bio_addr_copy_dup(int idx)
133 {
134     BIO_ADDR *src = NULL, *dst = NULL;
135     int ret = 0;
136     int docopy = idx & 1;
137 
138     idx >>= 1;
139 
140     src = make_dummy_addr(families[idx]);
141     if (!TEST_ptr(src))
142         return 0;
143 
144     if (docopy) {
145         dst = BIO_ADDR_new();
146         if (!TEST_ptr(dst))
147             goto err;
148 
149         if (!TEST_true(BIO_ADDR_copy(dst, src)))
150             goto err;
151     } else {
152         dst = BIO_ADDR_dup(src);
153         if (!TEST_ptr(dst))
154             goto err;
155     }
156 
157     if (!TEST_true(bio_addr_is_eq(src, dst)))
158         goto err;
159 
160     ret = 1;
161  err:
162     BIO_ADDR_free(src);
163     BIO_ADDR_free(dst);
164     return ret;
165 }
166 
setup_tests(void)167 int setup_tests(void)
168 {
169     if (!test_skip_common_options()) {
170         TEST_error("Error parsing test options\n");
171         return 0;
172     }
173 
174     ADD_ALL_TESTS(test_bio_addr_copy_dup, OSSL_NELEM(families) * 2);
175     return 1;
176 }
177