__attribute__((visibility("default"))) int openssl_generate_keypair(
    const keymaster0_device_t*, const keymaster_keypair_t key_type, const void* key_params,
    uint8_t** keyBlob, size_t* keyBlobLength) {
    Unique_EVP_PKEY pkey(EVP_PKEY_new());
    if (pkey.get() == NULL) {
        logOpenSSLError("openssl_generate_keypair");
        return -1;
    }

    if (key_params == NULL) {
        ALOGW("key_params == null");
        return -1;
    } else if (key_type == TYPE_DSA) {
        const keymaster_dsa_keygen_params_t* dsa_params =
            (const keymaster_dsa_keygen_params_t*)key_params;
        generate_dsa_keypair(pkey.get(), dsa_params);
    } else if (key_type == TYPE_EC) {
        const keymaster_ec_keygen_params_t* ec_params =
            (const keymaster_ec_keygen_params_t*)key_params;
        generate_ec_keypair(pkey.get(), ec_params);
    } else if (key_type == TYPE_RSA) {
        const keymaster_rsa_keygen_params_t* rsa_params =
            (const keymaster_rsa_keygen_params_t*)key_params;
        generate_rsa_keypair(pkey.get(), rsa_params);
    } else {
        ALOGW("Unsupported key type %d", key_type);
        return -1;
    }

    if (wrap_key(pkey.get(), EVP_PKEY_type(pkey->type), keyBlob, keyBlobLength)) {
        return -1;
    }

    return 0;
}
int main(int argc, const char * argv[])
{
    //expect 4 args : email, user name, plain password (10 to 20 chars), days. String controls have been made before calling this program.
    if (argc != 5) exit(EXIT_FAILURE);
    
    newUser_t *user;
    char *local;
    char *rsapriv;
    char rsapriv_key[33];
    size_t pwd_size;
    
    user = malloc(sizeof(newUser_t));
    user->email = strdup(argv[1]);
    user->name = strdup(argv[2]);
    user->days = strdup(argv[4]);

    
    //passphrase & aeskey
    pwd_size = strlen(argv[3]);
    if ( pwd_size < 10 || pwd_size > 20 ) {
        fprintf(stderr, "incorrect password length : %zu chars.", pwd_size);
        exit(EXIT_FAILURE);
    }
    user->passphrase = random_string(32);
    memcpy(rsapriv_key, argv[3], pwd_size);
    memcpy(rsapriv_key + pwd_size, user->passphrase + pwd_size, 32 - pwd_size);
    rsapriv_key[32] = '\0';
    
    libgcrypt_initialize();
    
    //rsa keys
    generate_rsa_keypair( &user->rsapub, &rsapriv);
    cipher_key(rsapriv, rsapriv_key, &user->rsapriv_crypt);
   
    //hash password
    char *settings;
    settings = crypt_gensalt_ra("$2a$", 7, random_string(16), 16);
    user->pwd = string_new();
    string_ajout(user->pwd, "{BLF-CRYPT}");
    string_ajout(user->pwd, crypt(argv[3], settings));

    //build maildir string
    user->maildir = string_new();
    string_ajout(user->maildir, "/");
    local = strtok(strdup(argv[1]), "@");
    string_ajout(user->maildir, strtok(NULL, "@"));
    string_ajout(user->maildir, "/");
    string_ajout(user->maildir, local);
    string_ajout(user->maildir, "/");
    
    //insert user in 2 tables : users & aliases
    if (pg_creer_utilisateur(user) != -1) {
        printf("OK 1/2 : Utilisateur ajouté dans la table users.\n");
        if (pg_creer_alias(user->email) != -1) {
            printf("OK 2/2 : Alias créé.\n");
         } else {
            fprintf(stderr, "Erreur lors de la création de l'alias.");
            exit(EXIT_FAILURE);
        }
    } else {
        fprintf(stderr, "Erreur lors de l'insertion de l'utilisateur dans la base users.");
        exit(EXIT_FAILURE);
    }
    
    exit(EXIT_SUCCESS);
}