Adding Languages

Our initial support for other languages is through the use of SWIG.

So far, this means we have simple bindings for C, Java, PHP, python, and Ruby.

If you want to add new language bindings, this is a good place to start.

The SWIG specification for libpasta reveals the simplicity of the API, and a few important caveats:

# in pasta.h

#include <stdbool.h>
extern char * hash_password(const char *password);
extern bool verify_password(const char* hash, const char *password);
extern void free_string(const char *);
extern char * read_password(const char *prompt);

These bind to the functions exported by the libpasta-ffi crate.

# in pasta.i

%module pasta
%{
#include <pasta.h>
%}

%typemap(newfree) char * "free_string($1);";
%newobject hash_password;
%newobject read_password;


%pragma(java) jniclasscode=%{
  static {
    try {
        System.loadLibrary("pasta_jni");
    } catch (UnsatisfiedLinkError e) {
      System.err.println("Native code library failed to load. \n" + e);
      System.exit(1);
    }
  }
%}

#include <pasta.h>

An important caveat, and reason why these bindings should be preferred, is that the values returned by hash_password and read_password are technically still Rust CStrings. Although these are in the correct layout to be read as string pointers in C, we must take care to return the pointer to Rust so that it can handle freeing the CString. Otherwise we are left with a memory leak.

Notice that the SWIG bindings have handled this: on returning a CString, the bindings create a new object, and then call free_string on the pointer.