Add SRP support.
[openssl.git] / crypto / srp / srptest.c
1 #include <openssl/opensslconf.h>
2 #ifdef OPENSSL_NO_SRP
3
4 #include <stdio.h>
5
6 int 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
18 static 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
28 static 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
130 int 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