1#include <openssl/opensslconf.h> 2#ifdef OPENSSL_NO_SRP 3 4# include <stdio.h> 5 6int main(int argc, char *argv[]) 7{ 8 printf("No SRP support\n"); 9 return (0); 10} 11 12#else 13 14# include <openssl/srp.h> 15# include <openssl/rand.h> 16# include <openssl/err.h> 17 18static void showbn(const char *name, const BIGNUM *bn) 19{ 20 fputs(name, stdout); 21 fputs(" = ", stdout); 22 BN_print_fp(stdout, bn); 23 putc('\n', stdout); 24} 25 26# define RANDOM_SIZE 32 /* use 256 bits on each side */ 27 28static int run_srp(const char *username, const char *client_pass, 29 const char *server_pass) 30{ 31 int ret = -1; 32 BIGNUM *s = NULL; 33 BIGNUM *v = NULL; 34 BIGNUM *a = NULL; 35 BIGNUM *b = NULL; 36 BIGNUM *u = NULL; 37 BIGNUM *x = NULL; 38 BIGNUM *Apub = NULL; 39 BIGNUM *Bpub = NULL; 40 BIGNUM *Kclient = NULL; 41 BIGNUM *Kserver = NULL; 42 unsigned char rand_tmp[RANDOM_SIZE]; 43 /* use builtin 1024-bit params */ 44 SRP_gN *GN = SRP_get_default_gN("1024"); 45 46 if (GN == NULL) { 47 fprintf(stderr, "Failed to get SRP parameters\n"); 48 return -1; 49 } 50 /* Set up server's password entry */ 51 if (!SRP_create_verifier_BN(username, server_pass, &s, &v, GN->N, GN->g)) { 52 fprintf(stderr, "Failed to create SRP verifier\n"); 53 return -1; 54 } 55 56 showbn("N", GN->N); 57 showbn("g", GN->g); 58 showbn("Salt", s); 59 showbn("Verifier", v); 60 61 /* Server random */ 62 RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp)); 63 b = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL); 64 /* TODO - check b != 0 */ 65 showbn("b", b); 66 67 /* Server's first message */ 68 Bpub = SRP_Calc_B(b, GN->N, GN->g, v); 69 showbn("B", Bpub); 70 71 if (!SRP_Verify_B_mod_N(Bpub, GN->N)) { 72 fprintf(stderr, "Invalid B\n"); 73 return -1; 74 } 75 76 /* Client random */ 77 RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp)); 78 a = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL); 79 /* TODO - check a != 0 */ 80 showbn("a", a); 81 82 /* Client's response */ 83 Apub = SRP_Calc_A(a, GN->N, GN->g); 84 showbn("A", Apub); 85 86 if (!SRP_Verify_A_mod_N(Apub, GN->N)) { 87 fprintf(stderr, "Invalid A\n"); 88 return -1; 89 } 90 91 /* Both sides calculate u */ 92 u = SRP_Calc_u(Apub, Bpub, GN->N); 93 94 /* Client's key */ 95 x = SRP_Calc_x(s, username, client_pass); 96 Kclient = SRP_Calc_client_key(GN->N, Bpub, GN->g, x, a, u); 97 showbn("Client's key", Kclient); 98 99 /* Server's key */ 100 Kserver = SRP_Calc_server_key(Apub, v, u, b, GN->N); 101 showbn("Server's key", Kserver); 102 103 if (BN_cmp(Kclient, Kserver) == 0) { 104 ret = 0; 105 } else { 106 fprintf(stderr, "Keys mismatch\n"); 107 ret = 1; 108 } 109 110 BN_clear_free(Kclient); 111 BN_clear_free(Kserver); 112 BN_clear_free(x); 113 BN_free(u); 114 BN_free(Apub); 115 BN_clear_free(a); 116 BN_free(Bpub); 117 BN_clear_free(b); 118 BN_free(s); 119 BN_clear_free(v); 120 121 return ret; 122} 123 124int main(int argc, char **argv) 125{ 126 BIO *bio_err; 127 bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 128 129 CRYPTO_malloc_debug_init(); 130 CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL); 131 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 132 133 ERR_load_crypto_strings(); 134 135 /* "Negative" test, expect a mismatch */ 136 if (run_srp("alice", "password1", "password2") == 0) { 137 fprintf(stderr, "Mismatched SRP run failed\n"); 138 return 1; 139 } 140 141 /* "Positive" test, should pass */ 142 if (run_srp("alice", "password", "password") != 0) { 143 fprintf(stderr, "Plain SRP run failed\n"); 144 return 1; 145 } 146 147 CRYPTO_cleanup_all_ex_data(); 148 ERR_remove_thread_state(NULL); 149 ERR_free_strings(); 150 CRYPTO_mem_leaks(bio_err); 151 152 return 0; 153} 154#endif 155