/*
* Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#ifndef OPENSSL_NO_SRP
# include "internal/cryptlib.h"
# include <openssl/sha.h>
# include <openssl/srp.h>
# include <openssl/evp.h>
# include <openssl/buffer.h>
# include <openssl/rand.h>
# include <openssl/txt_db.h>
# define SRP_RANDOM_SALT_LEN 20
# define MAX_LEN 2500
static char b64table[] =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
/*
* the following two conversion routines have been inspired by code from
* Stanford
*/
/*
* Convert a base64 string into raw byte array representation.
*/
static int t_fromb64(unsigned char *a, size_t alen, const char *src)
{
char *loc;
int i, j;
int size;
while (*src && (*src == ' ' || *src == '\t' || *src == '\n'))
++src;
size = strlen(src);
if (alen > INT_MAX || size > (int)alen)
return -1;
i = 0;
while (i < size) {
loc = strchr(b64table, src[i]);
if (loc == (char *)0)
break;
else
a[i] = loc - b64table;
++i;
}
/* if nothing valid to process we have a zero length response */
if (i == 0)
return 0;
size = i;
i = size - 1;
j = size;
while (1) {
a[j] = a[i];
if (--i < 0)
break;
a[j] |= (a[i] & 3) << 6;
--j;
a[j] = (unsigned char)((a[i] & 0x3c) >> 2);
if (--i < 0)
break;
a[j] |= (a[i] & 0xf) << 4;
--j;
a[j] = (unsigned char)((a[i] & 0x30) >> 4);
if (--i < 0)
break;
a[j] |= (a[i] << 2);
a[--j] = 0;
if (--i < 0)
break;
}
while (a[j] == 0 && j <= size)
++j;
i = 0;
while (j <= size)
a[i++] = a[j++];
return i;
}
/*
* Convert a raw byte string into a null-terminated base64 ASCII string.
*/
static char *t_tob64(char *dst, const unsigned char *src, int size)
{
int c, pos = size % 3;
unsigned char b0 = 0, b1 = 0, b2 = 0, notleading = 0;
char *olddst = dst;
switch (pos) {
case 1:
b2 = src[0];
break;
case 2:
b1 = src[0];
b2 = src[1];
break;
}
while (1) {
c = (b0 & 0xfc) >> 2;
if (notleading || c != 0) {
*dst++ = b64table[c];
notleading = 1;
}
c = ((b0 & 3) << 4) | ((b1 & 0xf0) >> 4);
if (notleading || c != 0) {
*dst++ = b64table[c];
notleading = 1;
}
c = ((b1 & 0xf) << 2) | ((b2 & 0xc0) >> 6);
if (notleading || c != 0) {
*dst++ = b64table[c];
notleading = 1;
}
c = b2 & 0x3f;
if (notleading || c != 0) {
*dst++ = b64table[c];
notleading = 1;
}
if (pos >= size)
break;
else {
b0 = src[pos++];
b1 = src[pos++];
b2 = src[pos++];
}
}
*dst++ = '\0';
return olddst;
}
void SRP_user_pwd_free(SRP_user_pwd *user_pwd)
{
if (user_pwd == NULL)
return;
BN_free(user_pwd->s);
BN_clear_free(user_pwd->v);
OPENSSL_free(user_pwd->id);
OPENSSL_free(user_pwd->info);
OPENSSL_free(user_pwd);
}
static SRP_user_pwd *SRP_user_pwd_new(void)
{
SRP_user_pwd *ret = OPENSSL_malloc(sizeof(*ret));
if (ret == NULL)
return NULL;
ret->N = NULL;
ret->g = NULL;
ret->s = NULL;
ret->v = NULL;
ret->id = NULL;
ret->info = NULL;
return ret;
}
static void SRP_user_pwd_set_gN(SRP_user_pwd *vinfo, const BIGNUM *g,
const BIGNUM *N)
{
vinfo->N =