1238384Sjkim#include <openssl/opensslconf.h> 2238384Sjkim#ifdef OPENSSL_NO_SRP 3238384Sjkim 4280304Sjkim# include <stdio.h> 5238384Sjkim 6238384Sjkimint main(int argc, char *argv[]) 7280304Sjkim{ 8280304Sjkim printf("No SRP support\n"); 9280304Sjkim return (0); 10280304Sjkim} 11238384Sjkim 12238384Sjkim#else 13238384Sjkim 14280304Sjkim# include <openssl/srp.h> 15280304Sjkim# include <openssl/rand.h> 16280304Sjkim# include <openssl/err.h> 17238384Sjkim 18238384Sjkimstatic void showbn(const char *name, const BIGNUM *bn) 19280304Sjkim{ 20280304Sjkim fputs(name, stdout); 21280304Sjkim fputs(" = ", stdout); 22280304Sjkim BN_print_fp(stdout, bn); 23280304Sjkim putc('\n', stdout); 24280304Sjkim} 25238384Sjkim 26280304Sjkim# define RANDOM_SIZE 32 /* use 256 bits on each side */ 27238384Sjkim 28280304Sjkimstatic int run_srp(const char *username, const char *client_pass, 29280304Sjkim const char *server_pass) 30280304Sjkim{ 31280304Sjkim int ret = -1; 32280304Sjkim BIGNUM *s = NULL; 33280304Sjkim BIGNUM *v = NULL; 34280304Sjkim BIGNUM *a = NULL; 35280304Sjkim BIGNUM *b = NULL; 36280304Sjkim BIGNUM *u = NULL; 37280304Sjkim BIGNUM *x = NULL; 38280304Sjkim BIGNUM *Apub = NULL; 39280304Sjkim BIGNUM *Bpub = NULL; 40280304Sjkim BIGNUM *Kclient = NULL; 41280304Sjkim BIGNUM *Kserver = NULL; 42280304Sjkim unsigned char rand_tmp[RANDOM_SIZE]; 43280304Sjkim /* use builtin 1024-bit params */ 44280304Sjkim SRP_gN *GN = SRP_get_default_gN("1024"); 45238384Sjkim 46280304Sjkim if (GN == NULL) { 47280304Sjkim fprintf(stderr, "Failed to get SRP parameters\n"); 48280304Sjkim return -1; 49280304Sjkim } 50280304Sjkim /* Set up server's password entry */ 51280304Sjkim if (!SRP_create_verifier_BN(username, server_pass, &s, &v, GN->N, GN->g)) { 52280304Sjkim fprintf(stderr, "Failed to create SRP verifier\n"); 53280304Sjkim return -1; 54280304Sjkim } 55238384Sjkim 56280304Sjkim showbn("N", GN->N); 57280304Sjkim showbn("g", GN->g); 58280304Sjkim showbn("Salt", s); 59280304Sjkim showbn("Verifier", v); 60238384Sjkim 61280304Sjkim /* Server random */ 62280304Sjkim RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp)); 63280304Sjkim b = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL); 64280304Sjkim /* TODO - check b != 0 */ 65280304Sjkim showbn("b", b); 66238384Sjkim 67280304Sjkim /* Server's first message */ 68280304Sjkim Bpub = SRP_Calc_B(b, GN->N, GN->g, v); 69280304Sjkim showbn("B", Bpub); 70238384Sjkim 71280304Sjkim if (!SRP_Verify_B_mod_N(Bpub, GN->N)) { 72280304Sjkim fprintf(stderr, "Invalid B\n"); 73280304Sjkim return -1; 74280304Sjkim } 75238384Sjkim 76280304Sjkim /* Client random */ 77280304Sjkim RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp)); 78280304Sjkim a = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL); 79280304Sjkim /* TODO - check a != 0 */ 80280304Sjkim showbn("a", a); 81238384Sjkim 82280304Sjkim /* Client's response */ 83280304Sjkim Apub = SRP_Calc_A(a, GN->N, GN->g); 84280304Sjkim showbn("A", Apub); 85238384Sjkim 86280304Sjkim if (!SRP_Verify_A_mod_N(Apub, GN->N)) { 87280304Sjkim fprintf(stderr, "Invalid A\n"); 88280304Sjkim return -1; 89280304Sjkim } 90238384Sjkim 91280304Sjkim /* Both sides calculate u */ 92280304Sjkim u = SRP_Calc_u(Apub, Bpub, GN->N); 93238384Sjkim 94280304Sjkim /* Client's key */ 95280304Sjkim x = SRP_Calc_x(s, username, client_pass); 96280304Sjkim Kclient = SRP_Calc_client_key(GN->N, Bpub, GN->g, x, a, u); 97280304Sjkim showbn("Client's key", Kclient); 98238384Sjkim 99280304Sjkim /* Server's key */ 100280304Sjkim Kserver = SRP_Calc_server_key(Apub, v, u, b, GN->N); 101280304Sjkim showbn("Server's key", Kserver); 102238384Sjkim 103280304Sjkim if (BN_cmp(Kclient, Kserver) == 0) { 104280304Sjkim ret = 0; 105280304Sjkim } else { 106280304Sjkim fprintf(stderr, "Keys mismatch\n"); 107280304Sjkim ret = 1; 108280304Sjkim } 109238384Sjkim 110280304Sjkim BN_clear_free(Kclient); 111280304Sjkim BN_clear_free(Kserver); 112280304Sjkim BN_clear_free(x); 113280304Sjkim BN_free(u); 114280304Sjkim BN_free(Apub); 115280304Sjkim BN_clear_free(a); 116280304Sjkim BN_free(Bpub); 117280304Sjkim BN_clear_free(b); 118280304Sjkim BN_free(s); 119280304Sjkim BN_clear_free(v); 120238384Sjkim 121280304Sjkim return ret; 122280304Sjkim} 123238384Sjkim 124238384Sjkimint main(int argc, char **argv) 125280304Sjkim{ 126280304Sjkim BIO *bio_err; 127280304Sjkim bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 128238384Sjkim 129280304Sjkim CRYPTO_malloc_debug_init(); 130280304Sjkim CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL); 131280304Sjkim CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 132238384Sjkim 133280304Sjkim ERR_load_crypto_strings(); 134238384Sjkim 135280304Sjkim /* "Negative" test, expect a mismatch */ 136280304Sjkim if (run_srp("alice", "password1", "password2") == 0) { 137280304Sjkim fprintf(stderr, "Mismatched SRP run failed\n"); 138280304Sjkim return 1; 139280304Sjkim } 140238384Sjkim 141280304Sjkim /* "Positive" test, should pass */ 142280304Sjkim if (run_srp("alice", "password", "password") != 0) { 143280304Sjkim fprintf(stderr, "Plain SRP run failed\n"); 144280304Sjkim return 1; 145280304Sjkim } 146238384Sjkim 147280304Sjkim CRYPTO_cleanup_all_ex_data(); 148280304Sjkim ERR_remove_thread_state(NULL); 149280304Sjkim ERR_free_strings(); 150280304Sjkim CRYPTO_mem_leaks(bio_err); 151238384Sjkim 152280304Sjkim return 0; 153280304Sjkim} 154238384Sjkim#endif 155