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