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