1 /* librist. Copyright © 2020 SipRadius LLC. All right reserved.
2 * Author: Gijs Peskens <gijs@in2ip.nl>
3 * Author: Sergio Ammirata, Ph.D. <sergio@ammirata.net>
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8 #include <mbedtls/base64.h>
9 #include <stddef.h>
10 #include <stdbool.h>
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <string.h>
14
user_verifier_lookup(char * username,size_t * verifier_len,char ** verifier,size_t * salt_len,char ** salt,bool * use_default_2048_bit_n_modulus,char ** n_modulus_ascii,char ** generator_ascii,void * user_data)15 void user_verifier_lookup(char * username,
16 size_t *verifier_len, char **verifier,
17 size_t *salt_len, char **salt,
18 bool *use_default_2048_bit_n_modulus,
19 char **n_modulus_ascii,
20 char **generator_ascii,
21 void *user_data)
22 {
23 (void)n_modulus_ascii;
24 (void)generator_ascii;
25 if (user_data == NULL)
26 return;
27 FILE *fh = (FILE *)user_data;
28 size_t username_offset = 0;
29
30 size_t read_verifier_len = 0;
31 char *read_verifier = malloc(1024);
32 size_t read_salt_len = 0;
33 char *read_salt = malloc(1024);
34
35 int reading = 0;//0 = username, 1 = verifier, 2 = salt
36 bool skipnextline = false;
37 int read = getc(fh);
38 //expected format: username:verifier:salt:3
39 while (read != EOF)
40 {
41 if (skipnextline)
42 {
43 if (read == '\n')
44 skipnextline = false;
45 } else if (read == ':')
46 {
47 if (reading == 0 && username_offset != (strlen(username))) {
48 skipnextline = true;
49 username_offset = 0;
50 continue;
51 }
52 if (reading == 1)
53 read_verifier[read_verifier_len+1] = '\0';
54 else if (reading == 2)
55 {
56 read_salt[read_salt_len +1] = '\0';
57 break;
58 }
59 reading++;
60 }
61 else if (reading == 0)
62 {
63 if (username[username_offset] != read)
64 {
65 username_offset = 0;
66 skipnextline = true;
67 }
68 else
69 username_offset++;
70 } else if (reading == 1)
71 {
72 if (read_verifier_len == 1024)
73 goto out;
74 read_verifier[read_verifier_len] = read;
75 read_verifier_len++;
76 } else if (reading == 2)
77 {
78 if (read_salt_len == 1024)
79 goto out;
80 read_salt[read_salt_len] = read;
81 read_salt_len++;
82 }
83 read = getc(fh);
84 }
85 if (reading != 2)
86 goto out;
87 //PAD with ==
88 if ((read_verifier_len % 4) != 0)
89 {
90 size_t needed_padding = 4 - (read_verifier_len % 4);
91 for (size_t i = 0; i < needed_padding; i++)
92 read_verifier[(read_verifier_len + i)] = '=';
93 read_verifier_len += needed_padding;
94 read_verifier[read_verifier_len] = '\0';
95 }
96 if ((read_salt_len % 4) != 0)
97 {
98 size_t needed_padding = 4 - (read_salt_len % 4);
99 for (size_t i = 0; i < needed_padding; i++)
100 read_salt[(read_salt_len + i)] = '=';
101 read_salt_len += needed_padding;
102 read_salt[read_salt_len] = '\0';
103 }
104 char *decoded_verifier = malloc(1024);
105 char *decoded_salt = malloc(1024);
106 if (mbedtls_base64_decode((unsigned char *)decoded_verifier, 1024, verifier_len, (unsigned char *)read_verifier, read_verifier_len) != 0)
107 goto fail_decode;
108
109 if (mbedtls_base64_decode((unsigned char *)decoded_salt, 1024, salt_len, (unsigned char *)read_salt, read_salt_len) != 0)
110 goto fail_decode;
111
112 *verifier = decoded_verifier;
113 *salt = decoded_salt;
114 *use_default_2048_bit_n_modulus = true;
115 goto out;
116
117 fail_decode:
118 *verifier_len = 0;
119 *salt_len = 0;
120 free(decoded_verifier);
121 free(decoded_salt);
122 out:
123 free(read_verifier);
124 free(read_salt);
125 rewind(fh);
126 return;
127 }
128