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, const char *server_pass) 29 { 30 int ret=-1; 31 BIGNUM *s = NULL; 32 BIGNUM *v = NULL; 33 BIGNUM *a = NULL; 34 BIGNUM *b = NULL; 35 BIGNUM *u = NULL; 36 BIGNUM *x = NULL; 37 BIGNUM *Apub = NULL; 38 BIGNUM *Bpub = NULL; 39 BIGNUM *Kclient = NULL; 40 BIGNUM *Kserver = NULL; 41 unsigned char rand_tmp[RANDOM_SIZE]; 42 /* use builtin 1024-bit params */ 43 SRP_gN *GN = SRP_get_default_gN("1024"); 44 45 if(GN == NULL) 46 { 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 { 53 fprintf(stderr, "Failed to create SRP verifier\n"); 54 return -1; 55 } 56 57 showbn("N", GN->N); 58 showbn("g", GN->g); 59 showbn("Salt", s); 60 showbn("Verifier", v); 61 62 /* Server random */ 63 RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp)); 64 b = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL); 65 /* TODO - check b != 0 */ 66 showbn("b", b); 67 68 /* Server's first message */ 69 Bpub = SRP_Calc_B(b, GN->N, GN->g, v); 70 showbn("B", Bpub); 71 72 if(!SRP_Verify_B_mod_N(Bpub, GN->N)) 73 { 74 fprintf(stderr, "Invalid B\n"); 75 return -1; 76 } 77 78 /* Client random */ 79 RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp)); 80 a = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL); 81 /* TODO - check a != 0 */ 82 showbn("a", a); 83 84 /* Client's response */ 85 Apub = SRP_Calc_A(a, GN->N, GN->g); 86 showbn("A", Apub); 87 88 if(!SRP_Verify_A_mod_N(Apub, GN->N)) 89 { 90 fprintf(stderr, "Invalid A\n"); 91 return -1; 92 } 93 94 /* Both sides calculate u */ 95 u = SRP_Calc_u(Apub, Bpub, GN->N); 96 97 /* Client's key */ 98 x = SRP_Calc_x(s, username, client_pass); 99 Kclient = SRP_Calc_client_key(GN->N, Bpub, GN->g, x, a, u); 100 showbn("Client's key", Kclient); 101 102 /* Server's key */ 103 Kserver = SRP_Calc_server_key(Apub, v, u, b, GN->N); 104 showbn("Server's key", Kserver); 105 106 if(BN_cmp(Kclient, Kserver) == 0) 107 { 108 ret = 0; 109 } 110 else 111 { 112 fprintf(stderr, "Keys mismatch\n"); 113 ret = 1; 114 } 115 116 BN_clear_free(Kclient); 117 BN_clear_free(Kserver); 118 BN_clear_free(x); 119 BN_free(u); 120 BN_free(Apub); 121 BN_clear_free(a); 122 BN_free(Bpub); 123 BN_clear_free(b); 124 BN_free(s); 125 BN_clear_free(v); 126 127 return ret; 128 } 129 130int main(int argc, char **argv) 131 { 132 BIO *bio_err; 133 bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 134 135 CRYPTO_malloc_debug_init(); 136 CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL); 137 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 138 139 ERR_load_crypto_strings(); 140 141 /* "Negative" test, expect a mismatch */ 142 if(run_srp("alice", "password1", "password2") == 0) 143 { 144 fprintf(stderr, "Mismatched SRP run failed\n"); 145 return 1; 146 } 147 148 /* "Positive" test, should pass */ 149 if(run_srp("alice", "password", "password") != 0) 150 { 151 fprintf(stderr, "Plain SRP run failed\n"); 152 return 1; 153 } 154 155 CRYPTO_cleanup_all_ex_data(); 156 ERR_remove_thread_state(NULL); 157 ERR_free_strings(); 158 CRYPTO_mem_leaks(bio_err); 159 160 return 0; 161 } 162#endif 163