Add #defines for magic numbers in API.
[openssl.git] / test / srptest.c
1 /*
2  * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <openssl/opensslconf.h>
11 #ifdef OPENSSL_NO_SRP
12
13 # include <stdio.h>
14
15 int main(int argc, char *argv[])
16 {
17     printf("No SRP support\n");
18     return (0);
19 }
20
21 #else
22
23 # include <openssl/srp.h>
24 # include <openssl/rand.h>
25 # include <openssl/err.h>
26
27 static void showbn(const char *name, const BIGNUM *bn)
28 {
29     fputs(name, stdout);
30     fputs(" = ", stdout);
31     BN_print_fp(stdout, bn);
32     putc('\n', stdout);
33 }
34
35 # define RANDOM_SIZE 32         /* use 256 bits on each side */
36
37 static int run_srp(const char *username, const char *client_pass,
38                    const char *server_pass)
39 {
40     int ret = -1;
41     BIGNUM *s = NULL;
42     BIGNUM *v = NULL;
43     BIGNUM *a = NULL;
44     BIGNUM *b = NULL;
45     BIGNUM *u = NULL;
46     BIGNUM *x = NULL;
47     BIGNUM *Apub = NULL;
48     BIGNUM *Bpub = NULL;
49     BIGNUM *Kclient = NULL;
50     BIGNUM *Kserver = NULL;
51     unsigned char rand_tmp[RANDOM_SIZE];
52     /* use builtin 1024-bit params */
53     const SRP_gN *GN = SRP_get_default_gN("1024");
54
55     if (GN == NULL) {
56         fprintf(stderr, "Failed to get SRP parameters\n");
57         return -1;
58     }
59     /* Set up server's password entry */
60     if (!SRP_create_verifier_BN(username, server_pass, &s, &v, GN->N, GN->g)) {
61         fprintf(stderr, "Failed to create SRP verifier\n");
62         return -1;
63     }
64
65     showbn("N", GN->N);
66     showbn("g", GN->g);
67     showbn("Salt", s);
68     showbn("Verifier", v);
69
70     /* Server random */
71     RAND_bytes(rand_tmp, sizeof(rand_tmp));
72     b = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL);
73     /* TODO - check b != 0 */
74     showbn("b", b);
75
76     /* Server's first message */
77     Bpub = SRP_Calc_B(b, GN->N, GN->g, v);
78     showbn("B", Bpub);
79
80     if (!SRP_Verify_B_mod_N(Bpub, GN->N)) {
81         fprintf(stderr, "Invalid B\n");
82         return -1;
83     }
84
85     /* Client random */
86     RAND_bytes(rand_tmp, sizeof(rand_tmp));
87     a = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL);
88     /* TODO - check a != 0 */
89     showbn("a", a);
90
91     /* Client's response */
92     Apub = SRP_Calc_A(a, GN->N, GN->g);
93     showbn("A", Apub);
94
95     if (!SRP_Verify_A_mod_N(Apub, GN->N)) {
96         fprintf(stderr, "Invalid A\n");
97         return -1;
98     }
99
100     /* Both sides calculate u */
101     u = SRP_Calc_u(Apub, Bpub, GN->N);
102
103     /* Client's key */
104     x = SRP_Calc_x(s, username, client_pass);
105     Kclient = SRP_Calc_client_key(GN->N, Bpub, GN->g, x, a, u);
106     showbn("Client's key", Kclient);
107
108     /* Server's key */
109     Kserver = SRP_Calc_server_key(Apub, v, u, b, GN->N);
110     showbn("Server's key", Kserver);
111
112     if (BN_cmp(Kclient, Kserver) == 0) {
113         ret = 0;
114     } else {
115         fprintf(stderr, "Keys mismatch\n");
116         ret = 1;
117     }
118
119     BN_clear_free(Kclient);
120     BN_clear_free(Kserver);
121     BN_clear_free(x);
122     BN_free(u);
123     BN_free(Apub);
124     BN_clear_free(a);
125     BN_free(Bpub);
126     BN_clear_free(b);
127     BN_free(s);
128     BN_clear_free(v);
129
130     return ret;
131 }
132
133 int main(int argc, char **argv)
134 {
135     BIO *bio_err;
136     bio_err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
137
138     CRYPTO_set_mem_debug(1);
139     CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
140
141
142     /* "Negative" test, expect a mismatch */
143     if (run_srp("alice", "password1", "password2") == 0) {
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         fprintf(stderr, "Plain SRP run failed\n");
151         return 1;
152     }
153
154 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
155     if (CRYPTO_mem_leaks(bio_err) <= 0)
156         return 1;
157 #endif
158     BIO_free(bio_err);
159
160     return 0;
161 }
162 #endif