Ccall help

Hi all,

I’m trying to get OnlinePackage to be able to post a package on github, but also set up the necessary SSH keys to get documenter building. I had it working on travis, but now I’m trying to get it work with github actions.

The new wrinkle is the github actions API requires “secrets” be uploaded via libsodium. Julia has a Sodium.jl wrapper library but it is very out of date…

Anyway, I used binary builder to build libsodium so you can download it now using libsodium_jll. Now I’m trying to call its functions via ccall. I’ve never used ccall before, so I’m not sure if I’m doing it right…

The relevant part of the function is here:

 sodium_key_id = json_string(talk_to(HTTP.get, github_remote,
        "/repos/$username/$repo_name/actions/secrets/public-key"
    ))

    sodium_key = base64decode(sodium_key_id["key"])
    raw_encoded = Vector{UInt8}(undef,
        length(private_key) +
        ccall((:crypto_box_sealbytes, libsodium), Cint, ())
    )
    error_code = ccall(
        (:crypto_box_seal, libsodium),
        Int32,
        (Ptr{UInt8}, Cstring, Cint, Ptr{UInt8}),
        raw_encoded, private_key, length(private_key), sodium_key
    )
    if error_code != 0
        error("Error using libsodium.crypto_box_seal")
    end
    talk_to(
        HTTP.put, github_remote, "/repos/$username/$repo_name/actions/secrets/$key_name",
        encrypted_value = base64encode(unsafe_string(pointer(raw_encoded), length(raw_encoded))),
        key_id = sodium_key_id["key_id"]
    )

Unfortunately, it doesn’t seem to be enough to get documenter building. I’m getting the error:

Load key "/home/runner/work/JuliennedArrays.jl/JuliennedArrays.jl/docs/.documenter": invalid format
git@github.com: Permission denied (publickey).

The full function is on the github repo here:

You can see a failing documenter build here:

https://github.com/bramtayl/JuliennedArrays.jl/runs/451494597

The github secrets api documentation is here:

and the libsodium sealed box documentation is here:

Can anyone give some advice about what to do next?

X-ref: Macro help · Issue #255 · JuliaInterop/Clang.jl · GitHub

the C language function signature:

int
crypto_box_seal( 
    unsigned char *c, const unsigned char *m,
    unsigned long long mlen, const unsigned char *pk)

here is the example from the doc “sealed_boxes”

#define MESSAGE (const unsigned char *) "Message"
#define MESSAGE_LEN 7
#define CIPHERTEXT_LEN (crypto_box_SEALBYTES + MESSAGE_LEN)

/* Recipient creates a long-term key pair */
unsigned char recipient_pk[crypto_box_PUBLICKEYBYTES];
unsigned char recipient_sk[crypto_box_SECRETKEYBYTES];

crypto_box_keypair(recipient_pk, recipient_sk);

/* Anonymous sender encrypts a message using an ephemeral key pair
 * and the recipient's public key */
unsigned char ciphertext[CIPHERTEXT_LEN];

crypto_box_seal(ciphertext, MESSAGE, MESSAGE_LEN, recipient_pk);

Here’s a MWE:

using Base64
using libsodium_jll

ssh_private_key = base64encode('A' ^ 3512)
downloaded_key = base64decode('A' ^ 44)
raw_encoded = Vector{UInt8}(undef,
    length(ssh_private_key) +
    ccall((:crypto_box_sealbytes, libsodium), Cint, ())
)
init_error_code = ccall((:sodium_init, libsodium), Int32, ())
seal_error_code = ccall(
    (:crypto_box_seal, libsodium),
    Int32,
    (Ptr{UInt8}, Cstring, Cint, Ptr{UInt8}),
    raw_encoded, private_key, length(private_key), sodium_key
)
base64encode(raw_encoded)

Unfortunately, I think the only way to validate whether the encoding actually worked is to download and checkout OnlinePackage and try to use it on one of your own packages with docs hosted on githubpages.

I’m doing the same GitHub secrets stuff, you may be interested in SodiumSeal.jl which has a nice Julian API and is 1.0-compatible.

@christopher-dG you might want to look at Macro help · Issue #255 · JuliaInterop/Clang.jl · GitHub

@Gnimuc has cooked up GitHub - Gnimuc/Sodium.jl: Julia wrapper for libsodium

I figured out the problem with my code. It wasn’t to do with ccall. Instead it was the chomp in the private key line: formerly was necessary to remove the newline at the end, but now I guess the newline is required?

@christopher-dG OnlinePackage is now updated to work with github actions. Let me know if/when you want to move it into PkgTemplates and I can deprecate OnlinePackage

Might be good to coordinate with @mortenpi who can update the hosting docs on Documenter to point users to the best way to programmatically submit SSH keys

Yeah that’s an SSH thing, I ran into that too.

2 Likes