@@ -210,6 +210,18 @@ const BIO_TYPE_SOURCE_SINK = 0x0400
210210 #
211211 BIO_TYPE_START = 128 )
212212
213+ """
214+ These are used in the following macros and are passed to BIO_ctrl().
215+ """
216+ # @enum(BIOFlags::Cint,
217+ #
218+ # );
219+ const BIO_FLAGS_SHOULD_RETRY = 0x08
220+ const BIO_FLAGS_READ = 0x01
221+ const BIO_FLAGS_WRITE = 0x02
222+ const BIO_FLAGS_IO_SPECIAL = 0x04
223+
224+
213225# Some values are reserved until OpenSSL 3.0.0 because they were previously
214226# included in SSL_OP_ALL in a 1.1.x release.
215227@bitflag SSLOptions:: Culong begin
@@ -1544,7 +1556,7 @@ mutable struct BIO
15441556 Creates a BIO object using IO stream method.
15451557 The BIO object is not registered with the finalizer.
15461558 """
1547- function BIO (data = nothing ; finalize:: Bool = true )
1559+ function BIO (io :: T ; finalize:: Bool = true ) where {T <: IO }
15481560 bio = ccall (
15491561 (:BIO_new , libcrypto),
15501562 Ptr{Cvoid},
@@ -1557,7 +1569,7 @@ mutable struct BIO
15571569 bio = new (bio)
15581570 finalize && finalizer (free, bio)
15591571
1560- # note that `data ` must be held as a reference somewhere else
1572+ # note that `io ` must be held as a reference somewhere else
15611573 # since it is not referenced by the BIO directly
15621574 # e.g. in SSLStream, we keep the `io` reference that is passed to
15631575 # the read/write BIOs
@@ -1566,7 +1578,7 @@ mutable struct BIO
15661578 Cvoid,
15671579 (BIO, Ptr{Cvoid}),
15681580 bio,
1569- data === nothing ? C_NULL : pointer_from_objref (data ))
1581+ pointer_from_objref (io ))
15701582
15711583 # Set BIO as non-blocking
15721584 ccall (
@@ -1577,6 +1589,7 @@ mutable struct BIO
15771589 102 ,
15781590 1 ,
15791591 C_NULL )
1592+
15801593 # Mark BIO as initalized.
15811594 ccall (
15821595 (:BIO_set_init , libcrypto),
@@ -1674,7 +1687,6 @@ end
16741687"""
16751688 BIO write.
16761689"""
1677- # # throw error here
16781690function Base. unsafe_write (bio:: BIO , out_buffer:: Ptr{UInt8} , out_length:: Int )
16791691 result = ccall (
16801692 (:BIO_write , libcrypto),
@@ -1690,6 +1702,139 @@ end
16901702
16911703Base. write (bio:: BIO , out_data) = return unsafe_write (bio, pointer (out_data), length (out_data))
16921704
1705+ """
1706+ BIOStream.
1707+ BIO with IO.
1708+ """
1709+ mutable struct BIOStream{T<: IO }
1710+ bio:: Ptr{Cvoid}
1711+ end
1712+
1713+ function bio_stream_get_io (bio_stream:: BIOStream{T} ):: T where {T<: IO }
1714+ data = ccall (
1715+ (:BIO_get_data , libcrypto),
1716+ Ptr{Cvoid},
1717+ (BIOStream{T},),
1718+ bio_stream)
1719+ return unsafe_pointer_to_objref (data):: T
1720+ end
1721+
1722+ """
1723+ BIOStream callbacks.
1724+ """
1725+
1726+ """
1727+ Called to initialize new BIO Stream object.
1728+ """
1729+ on_bio_stream_create (:: BIOStream{T} ) where {T<: IO } = Cint (1 )
1730+ on_bio_stream_destroy (:: BIOStream{T} ) where {T<: IO } = Cint (0 )
1731+
1732+ # function bio_get_data(bio::BIO)
1733+ # data = ccall(
1734+ # (:BIO_get_data, libcrypto),
1735+ # Ptr{Cvoid},
1736+ # (BIO,),
1737+ # bio)
1738+ # return unsafe_pointer_to_objref(data)
1739+ # end
1740+
1741+ function bio_set_flags (bio_stream:: BIOStream{T} , flags) where {T<: IO }
1742+ return ccall (
1743+ (:BIO_set_flags , libcrypto),
1744+ Cint,
1745+ (BIOStream{T}, Cint),
1746+ bio_stream, flags)
1747+ end
1748+
1749+ bio_set_read_retry (bio_stream:: BIOStream{T} ) where {T<: IO } = bio_set_flags (bio_stream, BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY)
1750+ bio_clear_flags (bio_stream:: BIOStream{T} ) where {T<: IO } = bio_set_flags (bio_stream, 0x00 )
1751+
1752+ """
1753+ static int fd_read(BIO *b, char *out, int outl)
1754+ {
1755+ int ret = 0;
1756+
1757+ if (out != NULL) {
1758+ clear_sys_error();
1759+ ret = UP_read(b->num, out, outl);
1760+ BIO_clear_retry_flags(b);
1761+ if (ret <= 0) {
1762+ if (BIO_fd_should_retry(ret))
1763+ BIO_set_retry_read(b);
1764+ else if (ret == 0)
1765+ b->flags |= BIO_FLAGS_IN_EOF;
1766+ }
1767+ }
1768+ return ret;
1769+ }
1770+ """
1771+
1772+ function on_bio_stream_read (bio_stream:: BIOStream{T} , out:: Ptr{Cchar} , outlen:: Cint ) where {T<: IO }
1773+ try
1774+ bio_clear_flags (bio_stream)
1775+ io:: T = bio_stream_get_io (bio_stream)
1776+ n = bytesavailable (io)
1777+ if n == 0
1778+ eof (io)
1779+ n = bytesavailable (io)
1780+ end
1781+
1782+ if n == 0
1783+ bio_set_read_retry (bio_stream)
1784+ return Cint (0 )
1785+ end
1786+ unsafe_read (io, out, min (UInt (n), outlen))
1787+ return Cint (min (n, outlen))
1788+ catch e
1789+ # we don't want to throw a Julia exception from a C callback
1790+ return Cint (- 1 )
1791+ end
1792+ end
1793+
1794+ function on_bio_stream_write (bio_stream:: BIOStream{T} , in:: Ptr{Cchar} , inlen:: Cint ):: Cint where {T<: IO }
1795+ try
1796+ io:: T = bio_stream_get_io (bio_stream)
1797+ written = unsafe_write (io, in, inlen)
1798+ return Cint (written)
1799+ catch e
1800+ # we don't want to throw a Julia exception from a C callback
1801+ return Cint (- 1 )
1802+ end
1803+ end
1804+
1805+ on_bio_stream_puts (bio_stream:: BIOStream{T} , in:: Ptr{Cchar} ) where {T<: IO } = Cint (0 )
1806+
1807+ on_bio_stream_ctrl (bio_stream:: BIOStream{T} , cmd:: BIOCtrl , num:: Clong , ptr:: Ptr{Cvoid} ) where {T<: IO } = Clong (1 )
1808+
1809+ """
1810+ BIO Stream callbacks.
1811+ """
1812+ struct BIOStreamCallbacks
1813+ on_bio_create_ptr:: Ptr{Nothing}
1814+ on_bio_destroy_ptr:: Ptr{Nothing}
1815+ on_bio_read_ptr:: Ptr{Nothing}
1816+ on_bio_write_ptr:: Ptr{Nothing}
1817+ on_bio_puts_ptr:: Ptr{Nothing}
1818+ on_bio_ctrl_ptr:: Ptr{Nothing}
1819+
1820+ function BIOStreamCallbacks ()
1821+ on_bio_create_ptr = @cfunction on_bio_stream_create Cint (BIOStream{IO},)
1822+ on_bio_destroy_ptr = @cfunction on_bio_stream_destroy Cint (BIOStream{IO},)
1823+ on_bio_read_ptr = @cfunction on_bio_stream_read Cint (BIOStream{IO}, Ptr{Cchar}, Cint)
1824+ on_bio_write_ptr = @cfunction on_bio_stream_write Cint (BIOStream{IO}, Ptr{Cchar}, Cint)
1825+ on_bio_puts_ptr = @cfunction on_bio_stream_puts Cint (BIOStream{IO}, Ptr{Cchar})
1826+ on_bio_ctrl_ptr = @cfunction on_bio_stream_ctrl Clong (BIOStream{IO}, BIOCtrl, Clong, Ptr{Cvoid})
1827+
1828+ return new (
1829+ on_bio_create_ptr,
1830+ on_bio_destroy_ptr,
1831+ on_bio_read_ptr,
1832+ on_bio_write_ptr,
1833+ on_bio_puts_ptr,
1834+ on_bio_ctrl_ptr)
1835+ end
1836+ end
1837+
16931838"""
16941839 ASN1_TIME.
16951840"""
@@ -2944,8 +3089,6 @@ function Base.String(x509_ext::X509Extension)
29443089 return " C_NULL"
29453090 end
29463091
2947- io = IOBuffer ()
2948-
29493092 bio = BIO (BIOMethodMemory ())
29503093
29513094 _ = ccall (
0 commit comments