@@ -1466,5 +1466,214 @@ int test_wolfSSL_BIO_BIO_ring_read(void)
14661466 return EXPECT_RESULT ();
14671467}
14681468
1469+ /* Custom BIO backing store for test_wolfSSL_BIO_custom_method */
1470+ #if defined(OPENSSL_EXTRA )
1471+
1472+ struct custom_bio_data {
1473+ char buf [256 ];
1474+ int len ;
1475+ byte createCalled :1 ;
1476+ byte destroyCalled :1 ;
1477+ byte writeCalled :1 ;
1478+ byte readCalled :1 ;
1479+ byte putsCalled :1 ;
1480+ byte getsCalled :1 ;
1481+ byte ctrlCalled :1 ;
1482+ };
1483+
1484+ static int custom_bio_createCb (WOLFSSL_BIO * bio )
1485+ {
1486+ struct custom_bio_data * data ;
1487+ data = (struct custom_bio_data * )XMALLOC (sizeof (* data ), NULL ,
1488+ DYNAMIC_TYPE_TMP_BUFFER );
1489+ if (data == NULL )
1490+ return 0 ;
1491+ XMEMSET (data , 0 , sizeof (* data ));
1492+ data -> createCalled = 1 ;
1493+ BIO_set_data (bio , data );
1494+ BIO_set_init (bio , 1 );
1495+ return 1 ;
1496+ }
1497+
1498+ static int custom_bio_destroyCb (WOLFSSL_BIO * bio )
1499+ {
1500+ struct custom_bio_data * data = (struct custom_bio_data * )BIO_get_data (bio );
1501+ if (data != NULL ) {
1502+ data -> destroyCalled = 1 ;
1503+ XFREE (data , NULL , DYNAMIC_TYPE_TMP_BUFFER );
1504+ }
1505+ BIO_set_data (bio , NULL );
1506+ return 1 ;
1507+ }
1508+
1509+ static int custom_bio_writeCb (WOLFSSL_BIO * bio , const char * in , int len )
1510+ {
1511+ struct custom_bio_data * data = (struct custom_bio_data * )BIO_get_data (bio );
1512+ int avail ;
1513+ if (data == NULL || in == NULL || len <= 0 )
1514+ return -1 ;
1515+ data -> writeCalled = 1 ;
1516+ avail = (int )sizeof (data -> buf ) - data -> len ;
1517+ if (len > avail )
1518+ len = avail ;
1519+ XMEMCPY (data -> buf + data -> len , in , (size_t )len );
1520+ data -> len += len ;
1521+ return len ;
1522+ }
1523+
1524+ static int custom_bio_readCb (WOLFSSL_BIO * bio , char * out , int len )
1525+ {
1526+ struct custom_bio_data * data = (struct custom_bio_data * )BIO_get_data (bio );
1527+ if (data == NULL || out == NULL || len <= 0 )
1528+ return -1 ;
1529+ data -> readCalled = 1 ;
1530+ if (data -> len == 0 )
1531+ return 0 ;
1532+ if (len > data -> len )
1533+ len = data -> len ;
1534+ XMEMCPY (out , data -> buf , (size_t )len );
1535+ /* shift remaining data */
1536+ data -> len -= len ;
1537+ if (data -> len > 0 )
1538+ XMEMMOVE (data -> buf , data -> buf + len , (size_t )data -> len );
1539+ return len ;
1540+ }
1541+
1542+ static int custom_bio_putsCb (WOLFSSL_BIO * bio , const char * str )
1543+ {
1544+ struct custom_bio_data * data = (struct custom_bio_data * )BIO_get_data (bio );
1545+ if (str == NULL || data == NULL )
1546+ return -1 ;
1547+ data -> putsCalled = 1 ;
1548+ return custom_bio_writeCb (bio , str , (int )XSTRLEN (str ));
1549+ }
1550+
1551+ static int custom_bio_getsCb (WOLFSSL_BIO * bio , char * buf , int sz )
1552+ {
1553+ struct custom_bio_data * data = (struct custom_bio_data * )BIO_get_data (bio );
1554+ int i ;
1555+ int readLen ;
1556+ if (data == NULL || buf == NULL || sz <= 1 )
1557+ return -1 ;
1558+ data -> getsCalled = 1 ;
1559+ if (data -> len == 0 )
1560+ return 0 ;
1561+ /* read up to newline or sz-1 bytes */
1562+ readLen = (sz - 1 < data -> len ) ? sz - 1 : data -> len ;
1563+ for (i = 0 ; i < readLen ; i ++ ) {
1564+ buf [i ] = data -> buf [i ];
1565+ if (data -> buf [i ] == '\n' ) {
1566+ i ++ ;
1567+ break ;
1568+ }
1569+ }
1570+ buf [i ] = '\0' ;
1571+ /* shift remaining data */
1572+ data -> len -= i ;
1573+ if (data -> len > 0 )
1574+ XMEMMOVE (data -> buf , data -> buf + i , (size_t )data -> len );
1575+ return i ;
1576+ }
1577+
1578+ static long custom_bio_ctrlCb (WOLFSSL_BIO * bio , int cmd , long larg , void * parg )
1579+ {
1580+ struct custom_bio_data * data = (struct custom_bio_data * )BIO_get_data (bio );
1581+ (void )larg ;
1582+ if (data == NULL )
1583+ return -1 ;
1584+ data -> ctrlCalled = 1 ;
1585+ switch (cmd ) {
1586+ case BIO_CTRL_PENDING :
1587+ return (long )data -> len ;
1588+ case BIO_CTRL_RESET :
1589+ data -> len = 0 ;
1590+ return WOLFSSL_SUCCESS ;
1591+ case BIO_CTRL_FLUSH :
1592+ return 1 ;
1593+ case BIO_CTRL_INFO :
1594+ if (parg != NULL )
1595+ * (char * * )parg = data -> buf ;
1596+ return (long )data -> len ;
1597+ default :
1598+ return 0 ;
1599+ }
1600+ }
1601+
1602+ #endif /* OPENSSL_EXTRA */
1603+
1604+ int test_wolfSSL_BIO_custom_method (void )
1605+ {
1606+ EXPECT_DECLS ;
1607+ #if defined(OPENSSL_EXTRA )
1608+ BIO_METHOD * method = NULL ;
1609+ BIO * bio = NULL ;
1610+ struct custom_bio_data * data = NULL ;
1611+ char buf [256 ];
1612+ char * memPtr = NULL ;
1613+
1614+ /* Create custom method and set all callbacks */
1615+ ExpectNotNull (method = BIO_meth_new (WOLFSSL_BIO_UNDEF , "custom_test" ));
1616+ ExpectIntEQ (BIO_meth_set_create (method , custom_bio_createCb ),
1617+ WOLFSSL_SUCCESS );
1618+ ExpectIntEQ (BIO_meth_set_destroy (method , custom_bio_destroyCb ),
1619+ WOLFSSL_SUCCESS );
1620+ ExpectIntEQ (BIO_meth_set_write (method , custom_bio_writeCb ),
1621+ WOLFSSL_SUCCESS );
1622+ ExpectIntEQ (BIO_meth_set_read (method , custom_bio_readCb ),
1623+ WOLFSSL_SUCCESS );
1624+ ExpectIntEQ (BIO_meth_set_puts (method , custom_bio_putsCb ),
1625+ WOLFSSL_SUCCESS );
1626+ ExpectIntEQ (BIO_meth_set_gets (method , custom_bio_getsCb ),
1627+ WOLFSSL_SUCCESS );
1628+ ExpectIntEQ (BIO_meth_set_ctrl (method , custom_bio_ctrlCb ),
1629+ WOLFSSL_SUCCESS );
1630+
1631+ /* Create BIO - should invoke createCb */
1632+ ExpectNotNull (bio = BIO_new (method ));
1633+ ExpectNotNull (data = (struct custom_bio_data * )BIO_get_data (bio ));
1634+ ExpectTrue (data -> createCalled );
1635+
1636+ /* write */
1637+ ExpectIntEQ (BIO_write (bio , "hello" , 5 ), 5 );
1638+ ExpectTrue (data -> writeCalled );
1639+
1640+ /* ctrl_pending via ctrlCb */
1641+ ExpectIntEQ ((int )BIO_ctrl_pending (bio ), 5 );
1642+ ExpectTrue (data -> ctrlCalled );
1643+
1644+ /* read */
1645+ XMEMSET (buf , 0 , sizeof (buf ));
1646+ ExpectIntEQ (BIO_read (bio , buf , 5 ), 5 );
1647+ ExpectBufEQ (buf , "hello" , 5 );
1648+ ExpectTrue (data -> readCalled );
1649+ ExpectIntEQ ((int )BIO_ctrl_pending (bio ), 0 );
1650+
1651+ /* puts */
1652+ ExpectIntEQ (BIO_puts (bio , "world\nfoo" ), 9 );
1653+ ExpectTrue (data -> putsCalled );
1654+ ExpectIntEQ ((int )BIO_ctrl_pending (bio ), 9 );
1655+
1656+ /* gets - should read up to and including first newline */
1657+ XMEMSET (buf , 0 , sizeof (buf ));
1658+ ExpectIntEQ (BIO_gets (bio , buf , (int )sizeof (buf )), 6 );
1659+ ExpectStrEQ (buf , "world\n" );
1660+ ExpectTrue (data -> getsCalled );
1661+ ExpectIntEQ ((int )BIO_ctrl_pending (bio ), 3 );
1662+
1663+ /* get_mem_data via BIO_CTRL_INFO */
1664+ ExpectIntEQ (BIO_get_mem_data (bio , & memPtr ), 3 );
1665+ ExpectNotNull (memPtr );
1666+
1667+ /* reset via ctrlCb */
1668+ ExpectIntEQ (BIO_reset (bio ), WOLFSSL_SUCCESS );
1669+ ExpectIntEQ ((int )BIO_ctrl_pending (bio ), 0 );
1670+
1671+ /* free - should invoke destroyCb */
1672+ BIO_free (bio );
1673+ BIO_meth_free (method );
1674+ #endif
1675+ return EXPECT_RESULT ();
1676+ }
1677+
14691678#endif /* !NO_BIO */
14701679
0 commit comments