Home | History | Annotate | Line # | Download | only in test
      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