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 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 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 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 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