/*
- * Written by Christophe Renou (christophe.renou@edelweb.fr) with the
- * precious help of Peter Sylvester (peter.sylvester@edelweb.fr) for the
- * EdelKey project and contributed to the OpenSSL project 2004.
- */
-/* ====================================================================
- * Copyright (c) 2004 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ * Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright (c) 2004, EdelKey Project. All Rights Reserved.
*
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
+ * 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
*
+ * Originally written by Christophe Renou and Peter Sylvester,
+ * for the EdelKey project.
*/
+
#ifndef OPENSSL_NO_SRP
# include "internal/cryptlib.h"
# include <openssl/sha.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, const char *src)
+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);
- 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;
+ size_t size = strlen(src);
+
+ /* Four bytes in src become three bytes output. */
+ if (size > INT_MAX || (size / 4) * 3 > alen)
+ return -1;
+
+ return EVP_DecodeBlock(a, (unsigned char *)src, (int)size);
}
/*
* Convert a raw byte string into a null-terminated base64 ASCII string.
*/
-static char *t_tob64(char *dst, const unsigned char *src, int size)
+static void 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;
+ EVP_EncodeBlock((unsigned char *)dst, src, size);
}
void SRP_user_pwd_free(SRP_user_pwd *user_pwd)
unsigned char tmp[MAX_LEN];
int len;
- if (strlen(s) > MAX_LEN || strlen(v) > MAX_LEN)
+ vinfo->v = NULL;
+ vinfo->s = NULL;
+
+ len = t_fromb64(tmp, sizeof(tmp), v);
+ if (len < 0)
return 0;
- len = t_fromb64(tmp, v);
if (NULL == (vinfo->v = BN_bin2bn(tmp, len, NULL)))
return 0;
- len = t_fromb64(tmp, s);
- return ((vinfo->s = BN_bin2bn(tmp, len, NULL)) != NULL);
+ len = t_fromb64(tmp, sizeof(tmp), s);
+ if (len < 0)
+ goto err;
+ vinfo->s = BN_bin2bn(tmp, len, NULL);
+ if (vinfo->s == NULL)
+ goto err;
+ return 1;
+ err:
+ BN_free(vinfo->v);
+ vinfo->v = NULL;
+ return 0;
}
static int SRP_user_pwd_set_sv_BN(SRP_user_pwd *vinfo, BIGNUM *s, BIGNUM *v)
if (newgN == NULL)
return NULL;
+ len = t_fromb64(tmp, sizeof(tmp), ch);
+ if (len < 0)
+ goto err;
+
if ((newgN->b64_bn = OPENSSL_strdup(ch)) == NULL)
goto err;
- len = t_fromb64(tmp, ch);
if ((newgN->bn = BN_bin2bn(tmp, len, NULL)))
return newgN;
if (sk_SRP_user_pwd_insert(vb->users_pwd, user_pwd, 0) == 0)
goto err;
- user_pwd = NULL; /* abandon responsability */
+ user_pwd = NULL; /* abandon responsibility */
}
}
}
return NULL;
}
- #if OPENSSL_API_COMPAT < 0x10100000L
+# if OPENSSL_API_COMPAT < 0x10100000L
/*
* DEPRECATED: use SRP_VBASE_get1_by_user instead.
* This method ignores the configured seed and fails for an unknown user.
{
return find_user(vb, username);
}
-#endif
+# endif
/*
* Ownership of the returned pointer is released to the caller.
if (RAND_bytes(digv, SHA_DIGEST_LENGTH) <= 0)
goto err;
ctxt = EVP_MD_CTX_new();
- EVP_DigestInit_ex(ctxt, EVP_sha1(), NULL);
- EVP_DigestUpdate(ctxt, vb->seed_key, strlen(vb->seed_key));
- EVP_DigestUpdate(ctxt, username, strlen(username));
- EVP_DigestFinal_ex(ctxt, digs, NULL);
+ if (ctxt == NULL
+ || !EVP_DigestInit_ex(ctxt, EVP_sha1(), NULL)
+ || !EVP_DigestUpdate(ctxt, vb->seed_key, strlen(vb->seed_key))
+ || !EVP_DigestUpdate(ctxt, username, strlen(username))
+ || !EVP_DigestFinal_ex(ctxt, digs, NULL))
+ goto err;
EVP_MD_CTX_free(ctxt);
ctxt = NULL;
if (SRP_user_pwd_set_sv_BN(user,
{
int len;
char *result = NULL, *vf = NULL;
- BIGNUM *N_bn = NULL, *g_bn = NULL, *s = NULL, *v = NULL;
+ const BIGNUM *N_bn = NULL, *g_bn = NULL;
+ BIGNUM *N_bn_alloc = NULL, *g_bn_alloc = NULL, *s = NULL, *v = NULL;
unsigned char tmp[MAX_LEN];
unsigned char tmp2[MAX_LEN];
char *defgNid = NULL;
goto err;
if (N) {
- if ((len = t_fromb64(tmp, N)) == 0)
+ if ((len = t_fromb64(tmp, sizeof(tmp), N)) <= 0)
goto err;
- N_bn = BN_bin2bn(tmp, len, NULL);
- if ((len = t_fromb64(tmp, g)) == 0)
+ N_bn_alloc = BN_bin2bn(tmp, len, NULL);
+ N_bn = N_bn_alloc;
+ if ((len = t_fromb64(tmp, sizeof(tmp) ,g)) <= 0)
goto err;
- g_bn = BN_bin2bn(tmp, len, NULL);
+ g_bn_alloc = BN_bin2bn(tmp, len, NULL);
+ g_bn = g_bn_alloc;
defgNid = "*";
} else {
SRP_gN *gN = SRP_get_gN_by_id(g, NULL);
s = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL);
} else {
- if ((len = t_fromb64(tmp2, *salt)) == 0)
+ if ((len = t_fromb64(tmp2, sizeof(tmp2), *salt)) <= 0)
goto err;
s = BN_bin2bn(tmp2, len, NULL);
}
result = defgNid;
err:
- if (N) {
- BN_free(N_bn);
- BN_free(g_bn);
- }
+ BN_free(N_bn_alloc);
+ BN_free(g_bn_alloc);
OPENSSL_clear_free(vf, vfsize);
BN_clear_free(s);
BN_clear_free(v);