| 
									
										
										
										
											2023-09-21 23:28:58 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License 2.0 (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
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <openssl/bio.h>
 | 
					
						
							|  |  |  | #include "internal/e_os.h"
 | 
					
						
							|  |  |  | #include "internal/sockets.h"
 | 
					
						
							|  |  |  | #include "testutil.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int families[] = { | 
					
						
							|  |  |  |     AF_INET, | 
					
						
							|  |  |  | #if OPENSSL_USE_IPV6
 | 
					
						
							|  |  |  |     AF_INET6, | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifndef OPENSSL_NO_UNIX_SOCK
 | 
					
						
							|  |  |  |     AF_UNIX | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static BIO_ADDR *make_dummy_addr(int family) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     BIO_ADDR *addr; | 
					
						
							|  |  |  |     union { | 
					
						
							|  |  |  |         struct sockaddr_in sin; | 
					
						
							|  |  |  | #if OPENSSL_USE_IPV6
 | 
					
						
							|  |  |  |         struct sockaddr_in6 sin6; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifndef OPENSSL_NO_UNIX_SOCK
 | 
					
						
							| 
									
										
										
										
											2023-10-04 22:11:42 +08:00
										 |  |  |         struct sockaddr_un sunaddr; | 
					
						
							| 
									
										
										
										
											2023-09-21 23:28:58 +08:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |     } sa; | 
					
						
							|  |  |  |     void *where; | 
					
						
							|  |  |  |     size_t wherelen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Fill with a dummy address */ | 
					
						
							|  |  |  |     switch(family) { | 
					
						
							|  |  |  |     case AF_INET: | 
					
						
							|  |  |  |         where = &(sa.sin.sin_addr); | 
					
						
							|  |  |  |         wherelen = sizeof(sa.sin.sin_addr); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | #if OPENSSL_USE_IPV6
 | 
					
						
							|  |  |  |     case AF_INET6: | 
					
						
							|  |  |  |         where = &(sa.sin6.sin6_addr); | 
					
						
							|  |  |  |         wherelen = sizeof(sa.sin6.sin6_addr); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifndef OPENSSL_NO_UNIX_SOCK
 | 
					
						
							|  |  |  |     case AF_UNIX: | 
					
						
							| 
									
										
										
										
											2023-10-04 22:11:42 +08:00
										 |  |  |         where = &(sa.sunaddr.sun_path); | 
					
						
							| 
									
										
										
										
											2023-09-21 23:28:58 +08:00
										 |  |  |         /* BIO_ADDR_rawmake needs an extra byte for a NUL-terminator*/ | 
					
						
							| 
									
										
										
										
											2023-10-04 22:11:42 +08:00
										 |  |  |         wherelen = sizeof(sa.sunaddr.sun_path) - 1; | 
					
						
							| 
									
										
										
										
											2023-09-21 23:28:58 +08:00
										 |  |  |         break; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         TEST_error("Unsupported address family"); | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * Could be any data, but we make it printable because BIO_ADDR_rawmake | 
					
						
							|  |  |  |      * expects the AF_UNIX address to be a string. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     memset(where, 'a', wherelen); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     addr = BIO_ADDR_new(); | 
					
						
							|  |  |  |     if (!TEST_ptr(addr)) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!TEST_true(BIO_ADDR_rawmake(addr, family, where, wherelen, 1000))) { | 
					
						
							|  |  |  |         BIO_ADDR_free(addr); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return addr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int bio_addr_is_eq(const BIO_ADDR *a, const BIO_ADDR *b) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-10-06 00:11:25 +08:00
										 |  |  |     unsigned char *adata = NULL, *bdata = NULL; | 
					
						
							| 
									
										
										
										
											2023-09-21 23:28:58 +08:00
										 |  |  |     size_t alen, blen; | 
					
						
							| 
									
										
										
										
											2023-10-06 00:11:25 +08:00
										 |  |  |     int ret = 0; | 
					
						
							| 
									
										
										
										
											2023-09-21 23:28:58 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* True even if a and b are NULL */ | 
					
						
							|  |  |  |     if (a == b) | 
					
						
							|  |  |  |         return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* If one is NULL the other cannot be due to the test above */ | 
					
						
							|  |  |  |     if (a == NULL || b == NULL) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (BIO_ADDR_family(a) != BIO_ADDR_family(b)) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Works even with AF_UNIX/AF_UNSPEC which just returns 0 */ | 
					
						
							|  |  |  |     if (BIO_ADDR_rawport(a) != BIO_ADDR_rawport(b)) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-06 00:11:25 +08:00
										 |  |  |     if (!BIO_ADDR_rawaddress(a, NULL, &alen)) | 
					
						
							| 
									
										
										
										
											2023-09-21 23:28:58 +08:00
										 |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-06 00:11:25 +08:00
										 |  |  |     if (!BIO_ADDR_rawaddress(b, NULL, &blen)) | 
					
						
							|  |  |  |         goto err; | 
					
						
							| 
									
										
										
										
											2023-09-21 23:28:58 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (alen != blen) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (alen == 0) | 
					
						
							|  |  |  |         return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-06 00:11:25 +08:00
										 |  |  |     adata = OPENSSL_malloc(alen); | 
					
						
							|  |  |  |     if (!TEST_ptr(adata) | 
					
						
							|  |  |  |             || !BIO_ADDR_rawaddress(a, adata, &alen)) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bdata = OPENSSL_malloc(blen); | 
					
						
							|  |  |  |     if (!TEST_ptr(bdata) | 
					
						
							|  |  |  |             || !BIO_ADDR_rawaddress(b, bdata, &blen)) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ret = (memcmp(adata, bdata, alen) == 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  err: | 
					
						
							|  |  |  |     OPENSSL_free(adata); | 
					
						
							|  |  |  |     OPENSSL_free(bdata); | 
					
						
							|  |  |  |     return ret; | 
					
						
							| 
									
										
										
										
											2023-09-21 23:28:58 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int test_bio_addr_copy_dup(int idx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     BIO_ADDR *src = NULL, *dst = NULL; | 
					
						
							|  |  |  |     int ret = 0; | 
					
						
							|  |  |  |     int docopy = idx & 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     idx >>= 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     src = make_dummy_addr(families[idx]); | 
					
						
							|  |  |  |     if (!TEST_ptr(src)) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (docopy) { | 
					
						
							|  |  |  |         dst = BIO_ADDR_new(); | 
					
						
							|  |  |  |         if (!TEST_ptr(dst)) | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!TEST_true(BIO_ADDR_copy(dst, src))) | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         dst = BIO_ADDR_dup(src); | 
					
						
							|  |  |  |         if (!TEST_ptr(dst)) | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!TEST_true(bio_addr_is_eq(src, dst))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ret = 1; | 
					
						
							|  |  |  |  err: | 
					
						
							|  |  |  |     BIO_ADDR_free(src); | 
					
						
							|  |  |  |     BIO_ADDR_free(dst); | 
					
						
							|  |  |  |     return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int setup_tests(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!test_skip_common_options()) { | 
					
						
							|  |  |  |         TEST_error("Error parsing test options\n"); | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ADD_ALL_TESTS(test_bio_addr_copy_dup, OSSL_NELEM(families) * 2); | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } |