1238384Sjkim#include <openssl/opensslconf.h> 2238384Sjkim#ifdef OPENSSL_NO_SRP 3238384Sjkim 4296341Sdelphij# include <stdio.h> 5238384Sjkim 6238384Sjkimint main(int argc, char *argv[]) 7296341Sdelphij{ 8296341Sdelphij printf("No SRP support\n"); 9296341Sdelphij return (0); 10296341Sdelphij} 11238384Sjkim 12238384Sjkim#else 13238384Sjkim 14296341Sdelphij# include <openssl/srp.h> 15296341Sdelphij# include <openssl/rand.h> 16296341Sdelphij# include <openssl/err.h> 17238384Sjkim 18238384Sjkimstatic void showbn(const char *name, const BIGNUM *bn) 19296341Sdelphij{ 20296341Sdelphij fputs(name, stdout); 21296341Sdelphij fputs(" = ", stdout); 22296341Sdelphij BN_print_fp(stdout, bn); 23296341Sdelphij putc('\n', stdout); 24296341Sdelphij} 25238384Sjkim 26296341Sdelphij# define RANDOM_SIZE 32 /* use 256 bits on each side */ 27238384Sjkim 28296341Sdelphijstatic int run_srp(const char *username, const char *client_pass, 29296341Sdelphij const char *server_pass) 30296341Sdelphij{ 31296341Sdelphij int ret = -1; 32296341Sdelphij BIGNUM *s = NULL; 33296341Sdelphij BIGNUM *v = NULL; 34296341Sdelphij BIGNUM *a = NULL; 35296341Sdelphij BIGNUM *b = NULL; 36296341Sdelphij BIGNUM *u = NULL; 37296341Sdelphij BIGNUM *x = NULL; 38296341Sdelphij BIGNUM *Apub = NULL; 39296341Sdelphij BIGNUM *Bpub = NULL; 40296341Sdelphij BIGNUM *Kclient = NULL; 41296341Sdelphij BIGNUM *Kserver = NULL; 42296341Sdelphij unsigned char rand_tmp[RANDOM_SIZE]; 43296341Sdelphij /* use builtin 1024-bit params */ 44296341Sdelphij SRP_gN *GN = SRP_get_default_gN("1024"); 45238384Sjkim 46296341Sdelphij if (GN == NULL) { 47296341Sdelphij fprintf(stderr, "Failed to get SRP parameters\n"); 48296341Sdelphij return -1; 49296341Sdelphij } 50296341Sdelphij /* Set up server's password entry */ 51296341Sdelphij if (!SRP_create_verifier_BN(username, server_pass, &s, &v, GN->N, GN->g)) { 52296341Sdelphij fprintf(stderr, "Failed to create SRP verifier\n"); 53296341Sdelphij return -1; 54296341Sdelphij } 55238384Sjkim 56296341Sdelphij showbn("N", GN->N); 57296341Sdelphij showbn("g", GN->g); 58296341Sdelphij showbn("Salt", s); 59296341Sdelphij showbn("Verifier", v); 60238384Sjkim 61296341Sdelphij /* Server random */ 62296341Sdelphij RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp)); 63296341Sdelphij b = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL); 64296341Sdelphij /* TODO - check b != 0 */ 65296341Sdelphij showbn("b", b); 66238384Sjkim 67296341Sdelphij /* Server's first message */ 68296341Sdelphij Bpub = SRP_Calc_B(b, GN->N, GN->g, v); 69296341Sdelphij showbn("B", Bpub); 70238384Sjkim 71296341Sdelphij if (!SRP_Verify_B_mod_N(Bpub, GN->N)) { 72296341Sdelphij fprintf(stderr, "Invalid B\n"); 73296341Sdelphij return -1; 74296341Sdelphij } 75238384Sjkim 76296341Sdelphij /* Client random */ 77296341Sdelphij RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp)); 78296341Sdelphij a = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL); 79296341Sdelphij /* TODO - check a != 0 */ 80296341Sdelphij showbn("a", a); 81238384Sjkim 82296341Sdelphij /* Client's response */ 83296341Sdelphij Apub = SRP_Calc_A(a, GN->N, GN->g); 84296341Sdelphij showbn("A", Apub); 85238384Sjkim 86296341Sdelphij if (!SRP_Verify_A_mod_N(Apub, GN->N)) { 87296341Sdelphij fprintf(stderr, "Invalid A\n"); 88296341Sdelphij return -1; 89296341Sdelphij } 90238384Sjkim 91296341Sdelphij /* Both sides calculate u */ 92296341Sdelphij u = SRP_Calc_u(Apub, Bpub, GN->N); 93238384Sjkim 94296341Sdelphij /* Client's key */ 95296341Sdelphij x = SRP_Calc_x(s, username, client_pass); 96296341Sdelphij Kclient = SRP_Calc_client_key(GN->N, Bpub, GN->g, x, a, u); 97296341Sdelphij showbn("Client's key", Kclient); 98238384Sjkim 99296341Sdelphij /* Server's key */ 100296341Sdelphij Kserver = SRP_Calc_server_key(Apub, v, u, b, GN->N); 101296341Sdelphij showbn("Server's key", Kserver); 102238384Sjkim 103296341Sdelphij if (BN_cmp(Kclient, Kserver) == 0) { 104296341Sdelphij ret = 0; 105296341Sdelphij } else { 106296341Sdelphij fprintf(stderr, "Keys mismatch\n"); 107296341Sdelphij ret = 1; 108296341Sdelphij } 109238384Sjkim 110296341Sdelphij BN_clear_free(Kclient); 111296341Sdelphij BN_clear_free(Kserver); 112296341Sdelphij BN_clear_free(x); 113296341Sdelphij BN_free(u); 114296341Sdelphij BN_free(Apub); 115296341Sdelphij BN_clear_free(a); 116296341Sdelphij BN_free(Bpub); 117296341Sdelphij BN_clear_free(b); 118296341Sdelphij BN_free(s); 119296341Sdelphij BN_clear_free(v); 120238384Sjkim 121296341Sdelphij return ret; 122296341Sdelphij} 123238384Sjkim 124238384Sjkimint main(int argc, char **argv) 125296341Sdelphij{ 126296341Sdelphij BIO *bio_err; 127296341Sdelphij bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 128238384Sjkim 129296341Sdelphij CRYPTO_malloc_debug_init(); 130296341Sdelphij CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL); 131296341Sdelphij CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 132238384Sjkim 133296341Sdelphij ERR_load_crypto_strings(); 134238384Sjkim 135296341Sdelphij /* "Negative" test, expect a mismatch */ 136296341Sdelphij if (run_srp("alice", "password1", "password2") == 0) { 137296341Sdelphij fprintf(stderr, "Mismatched SRP run failed\n"); 138296341Sdelphij return 1; 139296341Sdelphij } 140238384Sjkim 141296341Sdelphij /* "Positive" test, should pass */ 142296341Sdelphij if (run_srp("alice", "password", "password") != 0) { 143296341Sdelphij fprintf(stderr, "Plain SRP run failed\n"); 144296341Sdelphij return 1; 145296341Sdelphij } 146238384Sjkim 147296341Sdelphij CRYPTO_cleanup_all_ex_data(); 148296341Sdelphij ERR_remove_thread_state(NULL); 149296341Sdelphij ERR_free_strings(); 150296341Sdelphij CRYPTO_mem_leaks(bio_err); 151238384Sjkim 152296341Sdelphij return 0; 153296341Sdelphij} 154238384Sjkim#endif 155