xref: /aosp_15_r20/external/iperf3/src/iperf_auth.c (revision 7ab6e6ace082586527a400463bc693a412a40341)
1*7ab6e6acSAndroid Build Coastguard Worker /*
2*7ab6e6acSAndroid Build Coastguard Worker  * iperf, Copyright (c) 2014-2020, The Regents of the University of
3*7ab6e6acSAndroid Build Coastguard Worker  * California, through Lawrence Berkeley National Laboratory (subject
4*7ab6e6acSAndroid Build Coastguard Worker  * to receipt of any required approvals from the U.S. Dept. of
5*7ab6e6acSAndroid Build Coastguard Worker  * Energy).  All rights reserved.
6*7ab6e6acSAndroid Build Coastguard Worker  *
7*7ab6e6acSAndroid Build Coastguard Worker  * If you have questions about your rights to use or distribute this
8*7ab6e6acSAndroid Build Coastguard Worker  * software, please contact Berkeley Lab's Technology Transfer
9*7ab6e6acSAndroid Build Coastguard Worker  * Department at [email protected].
10*7ab6e6acSAndroid Build Coastguard Worker  *
11*7ab6e6acSAndroid Build Coastguard Worker  * NOTICE.  This software is owned by the U.S. Department of Energy.
12*7ab6e6acSAndroid Build Coastguard Worker  * As such, the U.S. Government has been granted for itself and others
13*7ab6e6acSAndroid Build Coastguard Worker  * acting on its behalf a paid-up, nonexclusive, irrevocable,
14*7ab6e6acSAndroid Build Coastguard Worker  * worldwide license in the Software to reproduce, prepare derivative
15*7ab6e6acSAndroid Build Coastguard Worker  * works, and perform publicly and display publicly.  Beginning five
16*7ab6e6acSAndroid Build Coastguard Worker  * (5) years after the date permission to assert copyright is obtained
17*7ab6e6acSAndroid Build Coastguard Worker  * from the U.S. Department of Energy, and subject to any subsequent
18*7ab6e6acSAndroid Build Coastguard Worker  * five (5) year renewals, the U.S. Government is granted for itself
19*7ab6e6acSAndroid Build Coastguard Worker  * and others acting on its behalf a paid-up, nonexclusive,
20*7ab6e6acSAndroid Build Coastguard Worker  * irrevocable, worldwide license in the Software to reproduce,
21*7ab6e6acSAndroid Build Coastguard Worker  * prepare derivative works, distribute copies to the public, perform
22*7ab6e6acSAndroid Build Coastguard Worker  * publicly and display publicly, and to permit others to do so.
23*7ab6e6acSAndroid Build Coastguard Worker  *
24*7ab6e6acSAndroid Build Coastguard Worker  * This code is distributed under a BSD style license, see the LICENSE file
25*7ab6e6acSAndroid Build Coastguard Worker  * for complete information.
26*7ab6e6acSAndroid Build Coastguard Worker  */
27*7ab6e6acSAndroid Build Coastguard Worker 
28*7ab6e6acSAndroid Build Coastguard Worker #include "iperf_config.h"
29*7ab6e6acSAndroid Build Coastguard Worker 
30*7ab6e6acSAndroid Build Coastguard Worker #include <string.h>
31*7ab6e6acSAndroid Build Coastguard Worker #include <assert.h>
32*7ab6e6acSAndroid Build Coastguard Worker #include <time.h>
33*7ab6e6acSAndroid Build Coastguard Worker #include <sys/types.h>
34*7ab6e6acSAndroid Build Coastguard Worker /* FreeBSD needs _WITH_GETLINE to enable the getline() declaration */
35*7ab6e6acSAndroid Build Coastguard Worker #define _WITH_GETLINE
36*7ab6e6acSAndroid Build Coastguard Worker #include <stdio.h>
37*7ab6e6acSAndroid Build Coastguard Worker #include <termios.h>
38*7ab6e6acSAndroid Build Coastguard Worker 
39*7ab6e6acSAndroid Build Coastguard Worker #if defined(HAVE_SSL)
40*7ab6e6acSAndroid Build Coastguard Worker 
41*7ab6e6acSAndroid Build Coastguard Worker #include <openssl/rsa.h>
42*7ab6e6acSAndroid Build Coastguard Worker #include <openssl/bio.h>
43*7ab6e6acSAndroid Build Coastguard Worker #include <openssl/pem.h>
44*7ab6e6acSAndroid Build Coastguard Worker #include <openssl/sha.h>
45*7ab6e6acSAndroid Build Coastguard Worker #include <openssl/buffer.h>
46*7ab6e6acSAndroid Build Coastguard Worker #include <openssl/err.h>
47*7ab6e6acSAndroid Build Coastguard Worker 
48*7ab6e6acSAndroid Build Coastguard Worker const char *auth_text_format = "user: %s\npwd:  %s\nts:   %ld";
49*7ab6e6acSAndroid Build Coastguard Worker 
sha256(const char * string,char outputBuffer[65])50*7ab6e6acSAndroid Build Coastguard Worker void sha256(const char *string, char outputBuffer[65])
51*7ab6e6acSAndroid Build Coastguard Worker {
52*7ab6e6acSAndroid Build Coastguard Worker     unsigned char hash[SHA256_DIGEST_LENGTH];
53*7ab6e6acSAndroid Build Coastguard Worker     SHA256_CTX sha256;
54*7ab6e6acSAndroid Build Coastguard Worker     SHA256_Init(&sha256);
55*7ab6e6acSAndroid Build Coastguard Worker     SHA256_Update(&sha256, string, strlen(string));
56*7ab6e6acSAndroid Build Coastguard Worker     SHA256_Final(hash, &sha256);
57*7ab6e6acSAndroid Build Coastguard Worker     int i = 0;
58*7ab6e6acSAndroid Build Coastguard Worker     for(i = 0; i < SHA256_DIGEST_LENGTH; i++)
59*7ab6e6acSAndroid Build Coastguard Worker     {
60*7ab6e6acSAndroid Build Coastguard Worker         sprintf(outputBuffer + (i * 2), "%02x", hash[i]);
61*7ab6e6acSAndroid Build Coastguard Worker     }
62*7ab6e6acSAndroid Build Coastguard Worker     outputBuffer[64] = 0;
63*7ab6e6acSAndroid Build Coastguard Worker }
64*7ab6e6acSAndroid Build Coastguard Worker 
check_authentication(const char * username,const char * password,const time_t ts,const char * filename)65*7ab6e6acSAndroid Build Coastguard Worker int check_authentication(const char *username, const char *password, const time_t ts, const char *filename){
66*7ab6e6acSAndroid Build Coastguard Worker     time_t t = time(NULL);
67*7ab6e6acSAndroid Build Coastguard Worker     time_t utc_seconds = mktime(localtime(&t));
68*7ab6e6acSAndroid Build Coastguard Worker     if ( (utc_seconds - ts) > 10 || (utc_seconds - ts) < -10 ) {
69*7ab6e6acSAndroid Build Coastguard Worker         return 1;
70*7ab6e6acSAndroid Build Coastguard Worker     }
71*7ab6e6acSAndroid Build Coastguard Worker 
72*7ab6e6acSAndroid Build Coastguard Worker     char passwordHash[65];
73*7ab6e6acSAndroid Build Coastguard Worker     char salted[strlen(username) + strlen(password) + 3];
74*7ab6e6acSAndroid Build Coastguard Worker     sprintf(salted, "{%s}%s", username, password);
75*7ab6e6acSAndroid Build Coastguard Worker     sha256(&salted[0], passwordHash);
76*7ab6e6acSAndroid Build Coastguard Worker 
77*7ab6e6acSAndroid Build Coastguard Worker     char *s_username, *s_password;
78*7ab6e6acSAndroid Build Coastguard Worker     int i;
79*7ab6e6acSAndroid Build Coastguard Worker     FILE *ptr_file;
80*7ab6e6acSAndroid Build Coastguard Worker     char buf[1024];
81*7ab6e6acSAndroid Build Coastguard Worker 
82*7ab6e6acSAndroid Build Coastguard Worker     ptr_file =fopen(filename,"r");
83*7ab6e6acSAndroid Build Coastguard Worker     if (!ptr_file)
84*7ab6e6acSAndroid Build Coastguard Worker         return 2;
85*7ab6e6acSAndroid Build Coastguard Worker 
86*7ab6e6acSAndroid Build Coastguard Worker     while (fgets(buf,1024, ptr_file)){
87*7ab6e6acSAndroid Build Coastguard Worker         //strip the \n or \r\n chars
88*7ab6e6acSAndroid Build Coastguard Worker         for (i = 0; buf[i] != '\0'; i++){
89*7ab6e6acSAndroid Build Coastguard Worker             if (buf[i] == '\n' || buf[i] == '\r'){
90*7ab6e6acSAndroid Build Coastguard Worker                 buf[i] = '\0';
91*7ab6e6acSAndroid Build Coastguard Worker                 break;
92*7ab6e6acSAndroid Build Coastguard Worker             }
93*7ab6e6acSAndroid Build Coastguard Worker         }
94*7ab6e6acSAndroid Build Coastguard Worker         //skip empty / not completed / comment lines
95*7ab6e6acSAndroid Build Coastguard Worker         if (strlen(buf) == 0 || strchr(buf, ',') == NULL || buf[0] == '#'){
96*7ab6e6acSAndroid Build Coastguard Worker             continue;
97*7ab6e6acSAndroid Build Coastguard Worker         }
98*7ab6e6acSAndroid Build Coastguard Worker         s_username = strtok(buf, ",");
99*7ab6e6acSAndroid Build Coastguard Worker         s_password = strtok(NULL, ",");
100*7ab6e6acSAndroid Build Coastguard Worker         if (strcmp( username, s_username ) == 0 && strcmp( passwordHash, s_password ) == 0){
101*7ab6e6acSAndroid Build Coastguard Worker             fclose(ptr_file);
102*7ab6e6acSAndroid Build Coastguard Worker             return 0;
103*7ab6e6acSAndroid Build Coastguard Worker         }
104*7ab6e6acSAndroid Build Coastguard Worker     }
105*7ab6e6acSAndroid Build Coastguard Worker     fclose(ptr_file);
106*7ab6e6acSAndroid Build Coastguard Worker     return 3;
107*7ab6e6acSAndroid Build Coastguard Worker }
108*7ab6e6acSAndroid Build Coastguard Worker 
109*7ab6e6acSAndroid Build Coastguard Worker 
Base64Encode(const unsigned char * buffer,const size_t length,char ** b64text)110*7ab6e6acSAndroid Build Coastguard Worker int Base64Encode(const unsigned char* buffer, const size_t length, char** b64text) { //Encodes a binary safe base 64 string
111*7ab6e6acSAndroid Build Coastguard Worker     BIO *bio, *b64;
112*7ab6e6acSAndroid Build Coastguard Worker     BUF_MEM *bufferPtr;
113*7ab6e6acSAndroid Build Coastguard Worker 
114*7ab6e6acSAndroid Build Coastguard Worker     b64 = BIO_new(BIO_f_base64());
115*7ab6e6acSAndroid Build Coastguard Worker     bio = BIO_new(BIO_s_mem());
116*7ab6e6acSAndroid Build Coastguard Worker     bio = BIO_push(b64, bio);
117*7ab6e6acSAndroid Build Coastguard Worker 
118*7ab6e6acSAndroid Build Coastguard Worker     BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); //Ignore newlines - write everything in one line
119*7ab6e6acSAndroid Build Coastguard Worker     BIO_write(bio, buffer, length);
120*7ab6e6acSAndroid Build Coastguard Worker     BIO_flush(bio);
121*7ab6e6acSAndroid Build Coastguard Worker     BIO_get_mem_ptr(bio, &bufferPtr);
122*7ab6e6acSAndroid Build Coastguard Worker     *b64text = strndup( (*bufferPtr).data, (*bufferPtr).length );
123*7ab6e6acSAndroid Build Coastguard Worker     BIO_free_all(bio);
124*7ab6e6acSAndroid Build Coastguard Worker 
125*7ab6e6acSAndroid Build Coastguard Worker     return (0); //success
126*7ab6e6acSAndroid Build Coastguard Worker }
127*7ab6e6acSAndroid Build Coastguard Worker 
calcDecodeLength(const char * b64input)128*7ab6e6acSAndroid Build Coastguard Worker size_t calcDecodeLength(const char* b64input) { //Calculates the length of a decoded string
129*7ab6e6acSAndroid Build Coastguard Worker     size_t len = strlen(b64input), padding = 0;
130*7ab6e6acSAndroid Build Coastguard Worker     if (b64input[len-1] == '=' && b64input[len-2] == '=') //last two chars are =
131*7ab6e6acSAndroid Build Coastguard Worker         padding = 2;
132*7ab6e6acSAndroid Build Coastguard Worker     else if (b64input[len-1] == '=') //last char is =
133*7ab6e6acSAndroid Build Coastguard Worker         padding = 1;
134*7ab6e6acSAndroid Build Coastguard Worker 
135*7ab6e6acSAndroid Build Coastguard Worker     return (len*3)/4 - padding;
136*7ab6e6acSAndroid Build Coastguard Worker }
137*7ab6e6acSAndroid Build Coastguard Worker 
Base64Decode(const char * b64message,unsigned char ** buffer,size_t * length)138*7ab6e6acSAndroid Build Coastguard Worker int Base64Decode(const char* b64message, unsigned char** buffer, size_t* length) { //Decodes a base64 encoded string
139*7ab6e6acSAndroid Build Coastguard Worker     BIO *bio, *b64;
140*7ab6e6acSAndroid Build Coastguard Worker 
141*7ab6e6acSAndroid Build Coastguard Worker     int decodeLen = calcDecodeLength(b64message);
142*7ab6e6acSAndroid Build Coastguard Worker     *buffer = (unsigned char*)malloc(decodeLen + 1);
143*7ab6e6acSAndroid Build Coastguard Worker     (*buffer)[decodeLen] = '\0';
144*7ab6e6acSAndroid Build Coastguard Worker 
145*7ab6e6acSAndroid Build Coastguard Worker     bio = BIO_new_mem_buf(b64message, -1);
146*7ab6e6acSAndroid Build Coastguard Worker     b64 = BIO_new(BIO_f_base64());
147*7ab6e6acSAndroid Build Coastguard Worker     bio = BIO_push(b64, bio);
148*7ab6e6acSAndroid Build Coastguard Worker 
149*7ab6e6acSAndroid Build Coastguard Worker     BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); //Do not use newlines to flush buffer
150*7ab6e6acSAndroid Build Coastguard Worker     *length = BIO_read(bio, *buffer, strlen(b64message));
151*7ab6e6acSAndroid Build Coastguard Worker     assert(*length == decodeLen); //length should equal decodeLen, else something went horribly wrong
152*7ab6e6acSAndroid Build Coastguard Worker     BIO_free_all(bio);
153*7ab6e6acSAndroid Build Coastguard Worker 
154*7ab6e6acSAndroid Build Coastguard Worker     return (0); //success
155*7ab6e6acSAndroid Build Coastguard Worker }
156*7ab6e6acSAndroid Build Coastguard Worker 
load_pubkey_from_file(const char * file)157*7ab6e6acSAndroid Build Coastguard Worker EVP_PKEY *load_pubkey_from_file(const char *file) {
158*7ab6e6acSAndroid Build Coastguard Worker     BIO *key = NULL;
159*7ab6e6acSAndroid Build Coastguard Worker     EVP_PKEY *pkey = NULL;
160*7ab6e6acSAndroid Build Coastguard Worker 
161*7ab6e6acSAndroid Build Coastguard Worker     if (file) {
162*7ab6e6acSAndroid Build Coastguard Worker       key = BIO_new_file(file, "r");
163*7ab6e6acSAndroid Build Coastguard Worker       pkey = PEM_read_bio_PUBKEY(key, NULL, NULL, NULL);
164*7ab6e6acSAndroid Build Coastguard Worker 
165*7ab6e6acSAndroid Build Coastguard Worker       BIO_free(key);
166*7ab6e6acSAndroid Build Coastguard Worker     }
167*7ab6e6acSAndroid Build Coastguard Worker     return (pkey);
168*7ab6e6acSAndroid Build Coastguard Worker }
169*7ab6e6acSAndroid Build Coastguard Worker 
load_pubkey_from_base64(const char * buffer)170*7ab6e6acSAndroid Build Coastguard Worker EVP_PKEY *load_pubkey_from_base64(const char *buffer) {
171*7ab6e6acSAndroid Build Coastguard Worker     unsigned char *key = NULL;
172*7ab6e6acSAndroid Build Coastguard Worker     size_t key_len;
173*7ab6e6acSAndroid Build Coastguard Worker     Base64Decode(buffer, &key, &key_len);
174*7ab6e6acSAndroid Build Coastguard Worker 
175*7ab6e6acSAndroid Build Coastguard Worker     BIO* bio = BIO_new(BIO_s_mem());
176*7ab6e6acSAndroid Build Coastguard Worker     BIO_write(bio, key, key_len);
177*7ab6e6acSAndroid Build Coastguard Worker     free(key);
178*7ab6e6acSAndroid Build Coastguard Worker     EVP_PKEY *pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
179*7ab6e6acSAndroid Build Coastguard Worker     BIO_free(bio);
180*7ab6e6acSAndroid Build Coastguard Worker     return (pkey);
181*7ab6e6acSAndroid Build Coastguard Worker }
182*7ab6e6acSAndroid Build Coastguard Worker 
load_privkey_from_file(const char * file)183*7ab6e6acSAndroid Build Coastguard Worker EVP_PKEY *load_privkey_from_file(const char *file) {
184*7ab6e6acSAndroid Build Coastguard Worker     BIO *key = NULL;
185*7ab6e6acSAndroid Build Coastguard Worker     EVP_PKEY *pkey = NULL;
186*7ab6e6acSAndroid Build Coastguard Worker 
187*7ab6e6acSAndroid Build Coastguard Worker     if (file) {
188*7ab6e6acSAndroid Build Coastguard Worker       key = BIO_new_file(file, "r");
189*7ab6e6acSAndroid Build Coastguard Worker       pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, NULL);
190*7ab6e6acSAndroid Build Coastguard Worker 
191*7ab6e6acSAndroid Build Coastguard Worker       BIO_free(key);
192*7ab6e6acSAndroid Build Coastguard Worker     }
193*7ab6e6acSAndroid Build Coastguard Worker     return (pkey);
194*7ab6e6acSAndroid Build Coastguard Worker }
195*7ab6e6acSAndroid Build Coastguard Worker 
load_privkey_from_base64(const char * buffer)196*7ab6e6acSAndroid Build Coastguard Worker EVP_PKEY *load_privkey_from_base64(const char *buffer) {
197*7ab6e6acSAndroid Build Coastguard Worker     unsigned char *key = NULL;
198*7ab6e6acSAndroid Build Coastguard Worker     size_t key_len;
199*7ab6e6acSAndroid Build Coastguard Worker     Base64Decode(buffer, &key, &key_len);
200*7ab6e6acSAndroid Build Coastguard Worker 
201*7ab6e6acSAndroid Build Coastguard Worker     BIO* bio = BIO_new(BIO_s_mem());
202*7ab6e6acSAndroid Build Coastguard Worker     BIO_write(bio, key, key_len);
203*7ab6e6acSAndroid Build Coastguard Worker     free(key);
204*7ab6e6acSAndroid Build Coastguard Worker     EVP_PKEY *pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
205*7ab6e6acSAndroid Build Coastguard Worker     BIO_free(bio);
206*7ab6e6acSAndroid Build Coastguard Worker     return (pkey);
207*7ab6e6acSAndroid Build Coastguard Worker }
208*7ab6e6acSAndroid Build Coastguard Worker 
test_load_pubkey_from_file(const char * file)209*7ab6e6acSAndroid Build Coastguard Worker int test_load_pubkey_from_file(const char *file){
210*7ab6e6acSAndroid Build Coastguard Worker     EVP_PKEY *key = load_pubkey_from_file(file);
211*7ab6e6acSAndroid Build Coastguard Worker     if (key == NULL){
212*7ab6e6acSAndroid Build Coastguard Worker         return -1;
213*7ab6e6acSAndroid Build Coastguard Worker     }
214*7ab6e6acSAndroid Build Coastguard Worker     EVP_PKEY_free(key);
215*7ab6e6acSAndroid Build Coastguard Worker     return 0;
216*7ab6e6acSAndroid Build Coastguard Worker }
217*7ab6e6acSAndroid Build Coastguard Worker 
test_load_private_key_from_file(const char * file)218*7ab6e6acSAndroid Build Coastguard Worker int test_load_private_key_from_file(const char *file){
219*7ab6e6acSAndroid Build Coastguard Worker     EVP_PKEY *key = load_privkey_from_file(file);
220*7ab6e6acSAndroid Build Coastguard Worker     if (key == NULL){
221*7ab6e6acSAndroid Build Coastguard Worker         return -1;
222*7ab6e6acSAndroid Build Coastguard Worker     }
223*7ab6e6acSAndroid Build Coastguard Worker     EVP_PKEY_free(key);
224*7ab6e6acSAndroid Build Coastguard Worker     return 0;
225*7ab6e6acSAndroid Build Coastguard Worker }
226*7ab6e6acSAndroid Build Coastguard Worker 
encrypt_rsa_message(const char * plaintext,EVP_PKEY * public_key,unsigned char ** encryptedtext)227*7ab6e6acSAndroid Build Coastguard Worker int encrypt_rsa_message(const char *plaintext, EVP_PKEY *public_key, unsigned char **encryptedtext) {
228*7ab6e6acSAndroid Build Coastguard Worker     RSA *rsa = NULL;
229*7ab6e6acSAndroid Build Coastguard Worker     unsigned char *rsa_buffer = NULL, pad = RSA_PKCS1_PADDING;
230*7ab6e6acSAndroid Build Coastguard Worker     int keysize, encryptedtext_len, rsa_buffer_len;
231*7ab6e6acSAndroid Build Coastguard Worker 
232*7ab6e6acSAndroid Build Coastguard Worker     rsa = EVP_PKEY_get1_RSA(public_key);
233*7ab6e6acSAndroid Build Coastguard Worker     keysize = RSA_size(rsa);
234*7ab6e6acSAndroid Build Coastguard Worker 
235*7ab6e6acSAndroid Build Coastguard Worker     rsa_buffer  = OPENSSL_malloc(keysize * 2);
236*7ab6e6acSAndroid Build Coastguard Worker     *encryptedtext = (unsigned char*)OPENSSL_malloc(keysize);
237*7ab6e6acSAndroid Build Coastguard Worker 
238*7ab6e6acSAndroid Build Coastguard Worker     BIO *bioBuff   = BIO_new_mem_buf((void*)plaintext, (int)strlen(plaintext));
239*7ab6e6acSAndroid Build Coastguard Worker     rsa_buffer_len = BIO_read(bioBuff, rsa_buffer, keysize * 2);
240*7ab6e6acSAndroid Build Coastguard Worker     encryptedtext_len = RSA_public_encrypt(rsa_buffer_len, rsa_buffer, *encryptedtext, rsa, pad);
241*7ab6e6acSAndroid Build Coastguard Worker 
242*7ab6e6acSAndroid Build Coastguard Worker     RSA_free(rsa);
243*7ab6e6acSAndroid Build Coastguard Worker     OPENSSL_free(rsa_buffer);
244*7ab6e6acSAndroid Build Coastguard Worker     BIO_free(bioBuff);
245*7ab6e6acSAndroid Build Coastguard Worker 
246*7ab6e6acSAndroid Build Coastguard Worker     if (encryptedtext_len < 0) {
247*7ab6e6acSAndroid Build Coastguard Worker       /* We probably shoudln't be printing stuff like this */
248*7ab6e6acSAndroid Build Coastguard Worker       fprintf(stderr, "%s\n", ERR_error_string(ERR_get_error(), NULL));
249*7ab6e6acSAndroid Build Coastguard Worker     }
250*7ab6e6acSAndroid Build Coastguard Worker 
251*7ab6e6acSAndroid Build Coastguard Worker     return encryptedtext_len;
252*7ab6e6acSAndroid Build Coastguard Worker }
253*7ab6e6acSAndroid Build Coastguard Worker 
decrypt_rsa_message(const unsigned char * encryptedtext,const int encryptedtext_len,EVP_PKEY * private_key,unsigned char ** plaintext)254*7ab6e6acSAndroid Build Coastguard Worker int decrypt_rsa_message(const unsigned char *encryptedtext, const int encryptedtext_len, EVP_PKEY *private_key, unsigned char **plaintext) {
255*7ab6e6acSAndroid Build Coastguard Worker     RSA *rsa = NULL;
256*7ab6e6acSAndroid Build Coastguard Worker     unsigned char *rsa_buffer = NULL, pad = RSA_PKCS1_PADDING;
257*7ab6e6acSAndroid Build Coastguard Worker     int plaintext_len, rsa_buffer_len, keysize;
258*7ab6e6acSAndroid Build Coastguard Worker 
259*7ab6e6acSAndroid Build Coastguard Worker     rsa = EVP_PKEY_get1_RSA(private_key);
260*7ab6e6acSAndroid Build Coastguard Worker 
261*7ab6e6acSAndroid Build Coastguard Worker     keysize = RSA_size(rsa);
262*7ab6e6acSAndroid Build Coastguard Worker     rsa_buffer  = OPENSSL_malloc(keysize * 2);
263*7ab6e6acSAndroid Build Coastguard Worker     *plaintext = (unsigned char*)OPENSSL_malloc(keysize);
264*7ab6e6acSAndroid Build Coastguard Worker 
265*7ab6e6acSAndroid Build Coastguard Worker     BIO *bioBuff   = BIO_new_mem_buf((void*)encryptedtext, encryptedtext_len);
266*7ab6e6acSAndroid Build Coastguard Worker     rsa_buffer_len = BIO_read(bioBuff, rsa_buffer, keysize * 2);
267*7ab6e6acSAndroid Build Coastguard Worker     plaintext_len = RSA_private_decrypt(rsa_buffer_len, rsa_buffer, *plaintext, rsa, pad);
268*7ab6e6acSAndroid Build Coastguard Worker 
269*7ab6e6acSAndroid Build Coastguard Worker     RSA_free(rsa);
270*7ab6e6acSAndroid Build Coastguard Worker     OPENSSL_free(rsa_buffer);
271*7ab6e6acSAndroid Build Coastguard Worker     BIO_free(bioBuff);
272*7ab6e6acSAndroid Build Coastguard Worker 
273*7ab6e6acSAndroid Build Coastguard Worker     if (plaintext_len < 0) {
274*7ab6e6acSAndroid Build Coastguard Worker       /* We probably shoudln't be printing stuff like this */
275*7ab6e6acSAndroid Build Coastguard Worker       fprintf(stderr, "%s\n", ERR_error_string(ERR_get_error(), NULL));
276*7ab6e6acSAndroid Build Coastguard Worker     }
277*7ab6e6acSAndroid Build Coastguard Worker 
278*7ab6e6acSAndroid Build Coastguard Worker     return plaintext_len;
279*7ab6e6acSAndroid Build Coastguard Worker }
280*7ab6e6acSAndroid Build Coastguard Worker 
encode_auth_setting(const char * username,const char * password,EVP_PKEY * public_key,char ** authtoken)281*7ab6e6acSAndroid Build Coastguard Worker int encode_auth_setting(const char *username, const char *password, EVP_PKEY *public_key, char **authtoken){
282*7ab6e6acSAndroid Build Coastguard Worker     time_t t = time(NULL);
283*7ab6e6acSAndroid Build Coastguard Worker     time_t utc_seconds = mktime(localtime(&t));
284*7ab6e6acSAndroid Build Coastguard Worker 
285*7ab6e6acSAndroid Build Coastguard Worker     /*
286*7ab6e6acSAndroid Build Coastguard Worker      * Compute a pessimistic/conservative estimate of storage required.
287*7ab6e6acSAndroid Build Coastguard Worker      * It's OK to allocate too much storage but too little is bad.
288*7ab6e6acSAndroid Build Coastguard Worker      */
289*7ab6e6acSAndroid Build Coastguard Worker     const int text_len = strlen(auth_text_format) + strlen(username) + strlen(password) + 32;
290*7ab6e6acSAndroid Build Coastguard Worker     char *text = (char *) calloc(text_len, sizeof(char));
291*7ab6e6acSAndroid Build Coastguard Worker     if (text == NULL) {
292*7ab6e6acSAndroid Build Coastguard Worker 	return -1;
293*7ab6e6acSAndroid Build Coastguard Worker     }
294*7ab6e6acSAndroid Build Coastguard Worker     snprintf(text, text_len, auth_text_format, username, password, utc_seconds);
295*7ab6e6acSAndroid Build Coastguard Worker 
296*7ab6e6acSAndroid Build Coastguard Worker     unsigned char *encrypted = NULL;
297*7ab6e6acSAndroid Build Coastguard Worker     int encrypted_len;
298*7ab6e6acSAndroid Build Coastguard Worker     encrypted_len = encrypt_rsa_message(text, public_key, &encrypted);
299*7ab6e6acSAndroid Build Coastguard Worker     free(text);
300*7ab6e6acSAndroid Build Coastguard Worker     if (encrypted_len < 0) {
301*7ab6e6acSAndroid Build Coastguard Worker       return -1;
302*7ab6e6acSAndroid Build Coastguard Worker     }
303*7ab6e6acSAndroid Build Coastguard Worker     Base64Encode(encrypted, encrypted_len, authtoken);
304*7ab6e6acSAndroid Build Coastguard Worker     OPENSSL_free(encrypted);
305*7ab6e6acSAndroid Build Coastguard Worker 
306*7ab6e6acSAndroid Build Coastguard Worker     return (0); //success
307*7ab6e6acSAndroid Build Coastguard Worker }
308*7ab6e6acSAndroid Build Coastguard Worker 
decode_auth_setting(int enable_debug,const char * authtoken,EVP_PKEY * private_key,char ** username,char ** password,time_t * ts)309*7ab6e6acSAndroid Build Coastguard Worker int decode_auth_setting(int enable_debug, const char *authtoken, EVP_PKEY *private_key, char **username, char **password, time_t *ts){
310*7ab6e6acSAndroid Build Coastguard Worker     unsigned char *encrypted_b64 = NULL;
311*7ab6e6acSAndroid Build Coastguard Worker     size_t encrypted_len_b64;
312*7ab6e6acSAndroid Build Coastguard Worker     Base64Decode(authtoken, &encrypted_b64, &encrypted_len_b64);
313*7ab6e6acSAndroid Build Coastguard Worker 
314*7ab6e6acSAndroid Build Coastguard Worker     unsigned char *plaintext = NULL;
315*7ab6e6acSAndroid Build Coastguard Worker     int plaintext_len;
316*7ab6e6acSAndroid Build Coastguard Worker     plaintext_len = decrypt_rsa_message(encrypted_b64, encrypted_len_b64, private_key, &plaintext);
317*7ab6e6acSAndroid Build Coastguard Worker     free(encrypted_b64);
318*7ab6e6acSAndroid Build Coastguard Worker     if (plaintext_len < 0) {
319*7ab6e6acSAndroid Build Coastguard Worker         return -1;
320*7ab6e6acSAndroid Build Coastguard Worker     }
321*7ab6e6acSAndroid Build Coastguard Worker     plaintext[plaintext_len] = '\0';
322*7ab6e6acSAndroid Build Coastguard Worker 
323*7ab6e6acSAndroid Build Coastguard Worker     char *s_username, *s_password;
324*7ab6e6acSAndroid Build Coastguard Worker     s_username = (char *) calloc(plaintext_len, sizeof(char));
325*7ab6e6acSAndroid Build Coastguard Worker     if (s_username == NULL) {
326*7ab6e6acSAndroid Build Coastguard Worker 	return -1;
327*7ab6e6acSAndroid Build Coastguard Worker     }
328*7ab6e6acSAndroid Build Coastguard Worker     s_password = (char *) calloc(plaintext_len, sizeof(char));
329*7ab6e6acSAndroid Build Coastguard Worker     if (s_password == NULL) {
330*7ab6e6acSAndroid Build Coastguard Worker 	free(s_username);
331*7ab6e6acSAndroid Build Coastguard Worker 	return -1;
332*7ab6e6acSAndroid Build Coastguard Worker     }
333*7ab6e6acSAndroid Build Coastguard Worker 
334*7ab6e6acSAndroid Build Coastguard Worker     int rc = sscanf((char *) plaintext, auth_text_format, s_username, s_password, ts);
335*7ab6e6acSAndroid Build Coastguard Worker     if (rc != 3) {
336*7ab6e6acSAndroid Build Coastguard Worker 	free(s_password);
337*7ab6e6acSAndroid Build Coastguard Worker 	free(s_username);
338*7ab6e6acSAndroid Build Coastguard Worker 	return -1;
339*7ab6e6acSAndroid Build Coastguard Worker     }
340*7ab6e6acSAndroid Build Coastguard Worker 
341*7ab6e6acSAndroid Build Coastguard Worker     if (enable_debug) {
342*7ab6e6acSAndroid Build Coastguard Worker         printf("Auth Token Content:\n%s\n", plaintext);
343*7ab6e6acSAndroid Build Coastguard Worker         printf("Auth Token Credentials:\n--> %s %s\n", s_username, s_password);
344*7ab6e6acSAndroid Build Coastguard Worker     }
345*7ab6e6acSAndroid Build Coastguard Worker     *username = s_username;
346*7ab6e6acSAndroid Build Coastguard Worker     *password = s_password;
347*7ab6e6acSAndroid Build Coastguard Worker     OPENSSL_free(plaintext);
348*7ab6e6acSAndroid Build Coastguard Worker     return (0);
349*7ab6e6acSAndroid Build Coastguard Worker }
350*7ab6e6acSAndroid Build Coastguard Worker 
351*7ab6e6acSAndroid Build Coastguard Worker #endif //HAVE_SSL
352*7ab6e6acSAndroid Build Coastguard Worker 
iperf_getpass(char ** lineptr,size_t * n,FILE * stream)353*7ab6e6acSAndroid Build Coastguard Worker ssize_t iperf_getpass (char **lineptr, size_t *n, FILE *stream) {
354*7ab6e6acSAndroid Build Coastguard Worker     struct termios old, new;
355*7ab6e6acSAndroid Build Coastguard Worker     ssize_t nread;
356*7ab6e6acSAndroid Build Coastguard Worker 
357*7ab6e6acSAndroid Build Coastguard Worker     /* Turn echoing off and fail if we can't. */
358*7ab6e6acSAndroid Build Coastguard Worker     if (tcgetattr (fileno (stream), &old) != 0)
359*7ab6e6acSAndroid Build Coastguard Worker         return -1;
360*7ab6e6acSAndroid Build Coastguard Worker     new = old;
361*7ab6e6acSAndroid Build Coastguard Worker     new.c_lflag &= ~ECHO;
362*7ab6e6acSAndroid Build Coastguard Worker     if (tcsetattr (fileno (stream), TCSAFLUSH, &new) != 0)
363*7ab6e6acSAndroid Build Coastguard Worker         return -1;
364*7ab6e6acSAndroid Build Coastguard Worker 
365*7ab6e6acSAndroid Build Coastguard Worker     /* Read the password. */
366*7ab6e6acSAndroid Build Coastguard Worker     printf("Password: ");
367*7ab6e6acSAndroid Build Coastguard Worker     nread = getline (lineptr, n, stream);
368*7ab6e6acSAndroid Build Coastguard Worker 
369*7ab6e6acSAndroid Build Coastguard Worker     /* Restore terminal. */
370*7ab6e6acSAndroid Build Coastguard Worker     (void) tcsetattr (fileno (stream), TCSAFLUSH, &old);
371*7ab6e6acSAndroid Build Coastguard Worker 
372*7ab6e6acSAndroid Build Coastguard Worker     //strip the \n or \r\n chars
373*7ab6e6acSAndroid Build Coastguard Worker     char *buf = *lineptr;
374*7ab6e6acSAndroid Build Coastguard Worker     int i;
375*7ab6e6acSAndroid Build Coastguard Worker     for (i = 0; buf[i] != '\0'; i++){
376*7ab6e6acSAndroid Build Coastguard Worker         if (buf[i] == '\n' || buf[i] == '\r'){
377*7ab6e6acSAndroid Build Coastguard Worker             buf[i] = '\0';
378*7ab6e6acSAndroid Build Coastguard Worker             break;
379*7ab6e6acSAndroid Build Coastguard Worker         }
380*7ab6e6acSAndroid Build Coastguard Worker     }
381*7ab6e6acSAndroid Build Coastguard Worker 
382*7ab6e6acSAndroid Build Coastguard Worker     return nread;
383*7ab6e6acSAndroid Build Coastguard Worker }
384*7ab6e6acSAndroid Build Coastguard Worker 
385*7ab6e6acSAndroid Build Coastguard Worker 
386