diff --git a/src/OpenSSL.jl b/src/OpenSSL.jl index 7c89e7c..8b1fbc0 100644 --- a/src/OpenSSL.jl +++ b/src/OpenSSL.jl @@ -2010,6 +2010,41 @@ function Base.write(io::IO, evp_pkey::EvpPKey, evp_cipher::EvpCipher=EvpCipher(C end end +function write_pubkey(io::IO, evp_pkey::EvpPKey) + bio = BIO(BIOMethodMemory()) + + GC.@preserve bio begin + if ccall( + (:PEM_write_bio_PUBKEY, libcrypto), + Cint, + (BIO, EvpPKey), + bio, + evp_pkey) != 1 + throw(OpenSSLError()) + end + return write(io, bio_get_mem_data(bio)) + end +end + +function read_pubkey(in_string::AbstractString)::EvpPKey + bio = BIO(BIOMethodMemory()) + write(bio, in_string) + + evp_pkey = ccall( + (:PEM_read_bio_PUBKEY, libcrypto), + Ptr{Cvoid}, + (BIO, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}), + bio, + C_NULL, + C_NULL, + C_NULL) + if evp_pkey == C_NULL + throw(OpenSSLError()) + end + free(bio) + return EvpPKey(evp_pkey) +end + function get_key_type(evp_pkey::EvpPKey)::EvpPKeyType pkey_type = ccall( (EVP_PKEY_base_id, libcrypto), diff --git a/test/runtests.jl b/test/runtests.jl index 69e3399..c039c3c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -671,6 +671,22 @@ end free(_evp_pkey) end + +@testset "SerializePublicKey" begin + evp_pkey = EvpPKey(rsa_generate_key()) + + io = IOBuffer() + n = OpenSSL.write_pubkey(io, evp_pkey) + pubkey_pem = String(take!(io)) + @test n == sizeof(pubkey_pem) + + @test startswith(pubkey_pem, "-----BEGIN PUBLIC KEY-----") + + _evp_pkey = OpenSSL.read_pubkey(pubkey_pem) + + @test _evp_pkey == evp_pkey +end + @testset "DSA" begin evp_pkey = EvpPKey(dsa_generate_key()) @test occursin("priv:", String(evp_pkey))