Change SRP functions to use EVP_EncodeUpdate/EVP_DecodeUpdate functions
Previously they were using EVP_EncodeBlock/EVP_DecodeBlock. These are low level functions that do not handle padding characters. This was causing the SRP code to fail. One side effect of using EVP_EncodeUpdate is that it inserts newlines which is not what we need in SRP so we add a flag to avoid that. Reviewed-by: Andy Polyakov <appro@openssl.org> (Merged from https://github.com/openssl/openssl/pull/5925)
This commit is contained in:
parent
0320e8e286
commit
c080461448
4 changed files with 65 additions and 13 deletions
|
@ -12,6 +12,7 @@
|
|||
#include "internal/cryptlib.h"
|
||||
#include <openssl/evp.h>
|
||||
#include "evp_locl.h"
|
||||
#include "internal/evp_int.h"
|
||||
|
||||
static unsigned char conv_ascii2bin(unsigned char a);
|
||||
#ifndef CHARSET_EBCDIC
|
||||
|
@ -115,11 +116,17 @@ int EVP_ENCODE_CTX_num(EVP_ENCODE_CTX *ctx)
|
|||
return ctx->num;
|
||||
}
|
||||
|
||||
void evp_encode_ctx_set_flags(EVP_ENCODE_CTX *ctx, unsigned int flags)
|
||||
{
|
||||
ctx->flags = flags;
|
||||
}
|
||||
|
||||
void EVP_EncodeInit(EVP_ENCODE_CTX *ctx)
|
||||
{
|
||||
ctx->length = 48;
|
||||
ctx->num = 0;
|
||||
ctx->line_num = 0;
|
||||
ctx->flags = 0;
|
||||
}
|
||||
|
||||
int EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
|
||||
|
@ -145,18 +152,24 @@ int EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
|
|||
j = EVP_EncodeBlock(out, ctx->enc_data, ctx->length);
|
||||
ctx->num = 0;
|
||||
out += j;
|
||||
total = j;
|
||||
if ((ctx->flags & EVP_ENCODE_CTX_NO_NEWLINES) == 0) {
|
||||
*(out++) = '\n';
|
||||
total++;
|
||||
}
|
||||
*out = '\0';
|
||||
total = j + 1;
|
||||
}
|
||||
while (inl >= ctx->length && total <= INT_MAX) {
|
||||
j = EVP_EncodeBlock(out, in, ctx->length);
|
||||
in += ctx->length;
|
||||
inl -= ctx->length;
|
||||
out += j;
|
||||
total += j;
|
||||
if ((ctx->flags & EVP_ENCODE_CTX_NO_NEWLINES) == 0) {
|
||||
*(out++) = '\n';
|
||||
total++;
|
||||
}
|
||||
*out = '\0';
|
||||
total += j + 1;
|
||||
}
|
||||
if (total > INT_MAX) {
|
||||
/* Too much output data! */
|
||||
|
@ -177,6 +190,7 @@ void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
|
|||
|
||||
if (ctx->num != 0) {
|
||||
ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num);
|
||||
if ((ctx->flags & EVP_ENCODE_CTX_NO_NEWLINES) == 0)
|
||||
out[ret++] = '\n';
|
||||
out[ret] = '\0';
|
||||
ctx->num = 0;
|
||||
|
@ -217,11 +231,11 @@ int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen)
|
|||
|
||||
void EVP_DecodeInit(EVP_ENCODE_CTX *ctx)
|
||||
{
|
||||
/* Only ctx->num is used during decoding. */
|
||||
/* Only ctx->num and ctx->flags are used during decoding. */
|
||||
ctx->num = 0;
|
||||
ctx->length = 0;
|
||||
ctx->line_num = 0;
|
||||
ctx->expect_nl = 0;
|
||||
ctx->flags = 0;
|
||||
}
|
||||
|
||||
/*-
|
||||
|
|
|
@ -59,7 +59,7 @@ struct evp_Encode_Ctx_st {
|
|||
unsigned char enc_data[80];
|
||||
/* number read on current line */
|
||||
int line_num;
|
||||
int expect_nl;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
typedef struct evp_pbe_st EVP_PBE_CTL;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include "internal/refcount.h"
|
||||
|
||||
struct evp_pkey_ctx_st {
|
||||
|
@ -422,3 +423,8 @@ void evp_app_cleanup_int(void);
|
|||
#ifndef TLS1_1_VERSION
|
||||
# define TLS1_1_VERSION 0x0302
|
||||
#endif
|
||||
|
||||
void evp_encode_ctx_set_flags(EVP_ENCODE_CTX *ctx, unsigned int flags);
|
||||
|
||||
/* EVP_ENCODE_CTX flags */
|
||||
#define EVP_ENCODE_CTX_NO_NEWLINES 1
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
# include "internal/cryptlib.h"
|
||||
# include "internal/evp_int.h"
|
||||
# include <openssl/sha.h>
|
||||
# include <openssl/srp.h>
|
||||
# include <openssl/evp.h>
|
||||
|
@ -26,24 +27,55 @@
|
|||
|
||||
/*
|
||||
* Convert a base64 string into raw byte array representation.
|
||||
* Returns the length of the decoded data, or -1 on error.
|
||||
*/
|
||||
static int t_fromb64(unsigned char *a, size_t alen, const char *src)
|
||||
{
|
||||
EVP_ENCODE_CTX *ctx;
|
||||
int outl = 0, outl2 = 0;
|
||||
size_t size = strlen(src);
|
||||
|
||||
/* Four bytes in src become three bytes output. */
|
||||
if (size > INT_MAX || (size / 4) * 3 > alen)
|
||||
if (size > INT_MAX)
|
||||
return -1;
|
||||
|
||||
return EVP_DecodeBlock(a, (unsigned char *)src, (int)size);
|
||||
ctx = EVP_ENCODE_CTX_new();
|
||||
if (ctx == NULL)
|
||||
return -1;
|
||||
|
||||
EVP_DecodeInit(ctx);
|
||||
if (EVP_DecodeUpdate(ctx, a, &outl, (const unsigned char *)src, size) < 0) {
|
||||
EVP_ENCODE_CTX_free(ctx);
|
||||
return -1;
|
||||
}
|
||||
EVP_DecodeFinal(ctx, a + outl, &outl2);
|
||||
|
||||
EVP_ENCODE_CTX_free(ctx);
|
||||
return outl + outl2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a raw byte string into a null-terminated base64 ASCII string.
|
||||
* Returns 1 on success or 0 on error.
|
||||
*/
|
||||
static void t_tob64(char *dst, const unsigned char *src, int size)
|
||||
static int t_tob64(char *dst, const unsigned char *src, int size)
|
||||
{
|
||||
EVP_EncodeBlock((unsigned char *)dst, src, size);
|
||||
EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
|
||||
int outl = 0, outl2 = 0;
|
||||
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
EVP_EncodeInit(ctx);
|
||||
evp_encode_ctx_set_flags(ctx, EVP_ENCODE_CTX_NO_NEWLINES);
|
||||
|
||||
if (!EVP_EncodeUpdate(ctx, (unsigned char *)dst, &outl, src, size)) {
|
||||
EVP_ENCODE_CTX_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
EVP_EncodeFinal(ctx, (unsigned char *)dst + outl, &outl2);
|
||||
|
||||
EVP_ENCODE_CTX_free(ctx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void SRP_user_pwd_free(SRP_user_pwd *user_pwd)
|
||||
|
|
Loading…
Reference in a new issue