OpenSSH changes

- increase FP_MAX_BITS for OpenSSH
- Add helpful loggin API (names are self-explanatory)
-- wolfSSL_GetLoggingCb
-- WOLFSSL_IS_DEBUG_ON
- Define WOLFSSL_EC_METHOD as an alias of WOLFSSL_EC_GROUP
- Add wolfSSL_EC_GROUP_method_of which really just returns the group itself
- Add wolfSSL_EC_METHOD_get_field_type which gets the curve type of the WOLFSSL_EC_GROUP(remember that WOLFSSL_EC_METHOD is an alias of WOLFSSL_EC_GROUP for now)
- Modify Base64_Decode so that it accepts arbitrary PEM line length
- Modify PemToDer so that it accepts private keys with a custom -----BEGIN * PRIVATE KEY----- header
This commit is contained in:
Juliusz Sosinowicz
2019-12-13 19:34:14 +01:00
parent 84a2ca7a4e
commit fbedabe601
10 changed files with 189 additions and 35 deletions

View File

@@ -30002,7 +30002,12 @@ int wolfSSL_DH_generate_key(WOLFSSL_DH* dh)
}
if (rng) {
pubSz = privSz = wolfSSL_BN_num_bytes(dh->p);
pubSz = wolfSSL_BN_num_bytes(dh->p);
if (dh->length) {
privSz = dh->length/8; /* to bytes */
} else {
privSz = pubSz;
}
pub = (unsigned char*)XMALLOC(pubSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
priv = (unsigned char*)XMALLOC(privSz, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
if (pub == NULL || priv == NULL) {
@@ -33219,6 +33224,12 @@ static int SetECKeyInternal(WOLFSSL_EC_KEY* eckey)
return WOLFSSL_FATAL_ERROR;
}
/* copy over the public point to key */
if (wc_ecc_copy_point((ecc_point*)eckey->pub_key->internal, &key->pubkey) != MP_OKAY) {
WOLFSSL_MSG("wc_ecc_copy_point error");
return WOLFSSL_FATAL_ERROR;
}
/* public key */
key->type = ECC_PUBLICKEY;
}
@@ -33306,6 +33317,11 @@ WOLFSSL_BIGNUM *wolfSSL_EC_KEY_get0_private_key(const WOLFSSL_EC_KEY *key)
return NULL;
}
if (wolfSSL_BN_is_zero(key->priv_key)) {
/* return NULL if not set */
return NULL;
}
return key->priv_key;
}
@@ -33738,7 +33754,12 @@ int wolfSSL_EC_KEY_set_public_key(WOLFSSL_EC_KEY *key,
return WOLFSSL_FAILURE;
}
if (SetECKeyExternal(key) != WOLFSSL_SUCCESS) {
if (SetECPointExternal(key->pub_key) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("SetECKeyInternal failed");
return WOLFSSL_FAILURE;
}
if (SetECKeyInternal(key) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("SetECKeyInternal failed");
return WOLFSSL_FAILURE;
}
@@ -33894,6 +33915,10 @@ void wolfSSL_EC_POINT_dump(const char *msg, const WOLFSSL_EC_POINT *p)
WOLFSSL_ENTER("wolfSSL_EC_POINT_dump");
if (!WOLFSSL_IS_DEBUG_ON() || wolfSSL_GetLoggingCb()) {
return;
}
if (p == NULL) {
printf("%s = NULL", msg);
return;
@@ -33944,6 +33969,20 @@ int wolfSSL_EC_GROUP_cmp(const WOLFSSL_EC_GROUP *a, const WOLFSSL_EC_GROUP *b,
#endif /* OPENSSL_EXTRA */
#if defined(HAVE_ECC) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
const WOLFSSL_EC_METHOD* wolfSSL_EC_GROUP_method_of(
const WOLFSSL_EC_GROUP *group)
{
return group;
}
int wolfSSL_EC_METHOD_get_field_type(const WOLFSSL_EC_METHOD *meth)
{
if (meth) {
return NID_X9_62_prime_field;
}
return WOLFSSL_FAILURE;
}
void wolfSSL_EC_GROUP_free(WOLFSSL_EC_GROUP *group)
{
WOLFSSL_ENTER("wolfSSL_EC_GROUP_free");
@@ -34661,7 +34700,7 @@ int wolfSSL_EC_POINT_is_at_infinity(const WOLFSSL_EC_GROUP *group,
return WOLFSSL_FAILURE;
}
return WOLFSSL_SUCCESS;
return ret;
}
/* End EC_POINT */
@@ -46407,6 +46446,8 @@ WOLFSSL_BIGNUM* wolfSSL_BN_bin2bn(const unsigned char* str, int len,
wolfSSL_BN_free(ret);
return NULL;
}
} else {
return NULL;
}
return ret;

View File

@@ -9759,6 +9759,11 @@ const char* const END_ENC_PRIV_KEY = "-----END ENCRYPTED PRIVATE KEY-----";
const char* const BEGIN_DSA_PRIV = "-----BEGIN DSA PRIVATE KEY-----";
const char* const END_DSA_PRIV = "-----END DSA PRIVATE KEY-----";
#endif
#ifdef OPENSSL_EXTRA
const char BEGIN_PRIV_KEY_PREFIX[] = "-----BEGIN";
const char PRIV_KEY_SUFFIX[] = "PRIVATE KEY-----";
const char END_PRIV_KEY_PREFIX[] = "-----END";
#endif
const char* const BEGIN_PUB_KEY = "-----BEGIN PUBLIC KEY-----";
const char* const END_PUB_KEY = "-----END PUBLIC KEY-----";
#ifdef HAVE_ED25519
@@ -10216,6 +10221,8 @@ int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz,
#ifdef WOLFSSL_PEM_TO_DER
#define STR_SIZEOF(x) (sizeof(x) - 1) /* -1 to not count the null char */
/* Remove PEM header/footer, convert to ASN1, store any encrypted data
info->consumed tracks of PEM bytes consumed in case multiple parts */
int PemToDer(const unsigned char* buff, long longSz, int type,
@@ -10238,6 +10245,10 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
int padVal = 0;
#endif
#endif
#ifdef OPENSSL_EXTRA
char beginBuf[PEM_LINE_LEN];
char endBuf[PEM_LINE_LEN];
#endif
WOLFSSL_ENTER("PemToDer");
@@ -10293,12 +10304,59 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
}
if (!headerEnd) {
#ifdef OPENSSL_EXTRA
char* beginEnd;
int endLen;
/* see if there is a -----BEGIN * PRIVATE KEY----- header */
headerEnd = XSTRNSTR((char*)buff, PRIV_KEY_SUFFIX, sz);
if (headerEnd) {
beginEnd = headerEnd + STR_SIZEOF(PRIV_KEY_SUFFIX);
/* back up to BEGIN_PRIV_KEY_PREFIX */
headerEnd -= STR_SIZEOF(BEGIN_PRIV_KEY_PREFIX);
while (headerEnd > (char*)buff &&
XSTRNCMP(headerEnd, BEGIN_PRIV_KEY_PREFIX,
STR_SIZEOF(BEGIN_PRIV_KEY_PREFIX)) != 0) {
headerEnd--;
}
if (XSTRNCMP(headerEnd, BEGIN_PRIV_KEY_PREFIX,
STR_SIZEOF(BEGIN_PRIV_KEY_PREFIX)) != 0 ||
beginEnd - headerEnd > PEM_LINE_LEN) {
WOLFSSL_MSG("Couldn't find PEM header");
return ASN_NO_PEM_HEADER;
}
/* headerEnd now points to beginning of header */
XMEMCPY(beginBuf, headerEnd, beginEnd - headerEnd);
beginBuf[beginEnd - headerEnd] = '\0';
/* look for matching footer */
footer = XSTRNSTR(beginEnd,
beginBuf + STR_SIZEOF(BEGIN_PRIV_KEY_PREFIX),
(char*)buff + sz - beginEnd);
if (!footer) {
WOLFSSL_MSG("Couldn't find PEM footer");
return ASN_NO_PEM_HEADER;
}
footer -= STR_SIZEOF(END_PRIV_KEY_PREFIX);
endLen = beginEnd - headerEnd -
(STR_SIZEOF(BEGIN_PRIV_KEY_PREFIX) -
STR_SIZEOF(END_PRIV_KEY_PREFIX));
XMEMCPY(endBuf, footer, endLen);
endBuf[endLen] = '\0';
header = beginBuf;
footer = endBuf;
headerEnd = beginEnd;
} else {
WOLFSSL_MSG("Couldn't find PEM header");
return ASN_NO_PEM_HEADER;
}
#else
WOLFSSL_MSG("Couldn't find PEM header");
return ASN_NO_PEM_HEADER;
#endif
} else {
headerEnd += XSTRLEN(header);
}
headerEnd += XSTRLEN(header);
/* eat end of line characters */
headerEnd = SkipEndOfLineChars(headerEnd, bufferEnd);
@@ -10306,8 +10364,9 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
/* keyFormat is Key_Sum enum */
if (keyFormat) {
#ifdef HAVE_ECC
if (header == BEGIN_EC_PRIV)
*keyFormat = ECDSAk;
*eccKey = (header == BEGIN_EC_PRIV || header == beginBuf) ? 1 : 0;
#else
*eccKey = 0;
#endif
#if !defined(NO_DSA)
if (header == BEGIN_DSA_PRIV)
@@ -10327,7 +10386,7 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
#endif /* WOLFSSL_ENCRYPTED_KEYS */
/* find footer */
footerEnd = XSTRNSTR((char*)buff, footer, sz);
footerEnd = XSTRNSTR(headerEnd, footer, (char*)buff + sz - headerEnd);
if (!footerEnd) {
if (info)
info->consumed = longSz; /* No more certs if no footer */
@@ -10363,6 +10422,9 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
return BUFFER_E;
if ((header == BEGIN_PRIV_KEY
#ifdef OPENSSL_EXTRA
|| header == beginBuf
#endif
#ifdef HAVE_ECC
|| header == BEGIN_EC_PRIV
#endif

View File

@@ -57,27 +57,66 @@ const byte base64Decode[] = { 62, BAD, BAD, BAD, 63, /* + starts at 0x2B */
46, 47, 48, 49, 50, 51
};
static WC_INLINE int Base64_SkipNewline(const byte* in, word32 *outLen, word32 *outJ)
{
word32 inLen = *outLen;
word32 j = *outJ;
if (inLen && (in[j] == ' ' || in[j] == '\r' || in[j] == '\n')) {
byte endLine = in[j++];
inLen--;
while (inLen && endLine == ' ') { /* allow trailing whitespace */
endLine = in[j++];
inLen--;
}
if (endLine == '\r') {
if (inLen) {
endLine = in[j++];
inLen--;
}
}
if (endLine != '\n') {
WOLFSSL_MSG("Bad end of line in Base64 Decode");
return ASN_INPUT_E;
}
}
*outLen = inLen;
*outJ = j;
return 0;
}
int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen)
{
word32 i = 0;
word32 j = 0;
word32 plainSz = inLen - ((inLen + (PEM_LINE_SZ - 1)) / PEM_LINE_SZ );
int ret;
const byte maxIdx = (byte)sizeof(base64Decode) + BASE64_MIN - 1;
plainSz = (plainSz * 3 + 3) / 4;
if (plainSz > *outLen) return BAD_FUNC_ARG;
while (inLen > 3) {
byte b1, b2, b3;
byte e1 = in[j++];
byte e2 = in[j++];
byte e3 = in[j++];
byte e4 = in[j++];
int pad3 = 0;
int pad4 = 0;
byte b1, b2, b3;
if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) {
return ret;
}
byte e1 = in[j++];
if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) {
return ret;
}
byte e2 = in[j++];
if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) {
return ret;
}
byte e3 = in[j++];
if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) {
return ret;
}
byte e4 = in[j++];
if (e1 == 0) /* end file 0's */
break;
if (e3 == PAD)
@@ -118,24 +157,6 @@ int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen)
break;
inLen -= 4;
if (inLen && (in[j] == ' ' || in[j] == '\r' || in[j] == '\n')) {
byte endLine = in[j++];
inLen--;
while (inLen && endLine == ' ') { /* allow trailing whitespace */
endLine = in[j++];
inLen--;
}
if (endLine == '\r') {
if (inLen) {
endLine = in[j++];
inLen--;
}
}
if (endLine != '\n') {
WOLFSSL_MSG("Bad end of line in Base64 Decode");
return ASN_INPUT_E;
}
}
}
/* If the output buffer has a room for an extra byte, add a null terminator */
if (out && *outLen > i)

View File

@@ -137,6 +137,12 @@ int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb f)
#endif
}
/* allow this to be set to NULL, so logs can be redirected to default output */
wolfSSL_Logging_cb wolfSSL_GetLoggingCb(void)
{
return log_function;
}
int wolfSSL_Debugging_ON(void)
{
@@ -346,6 +352,11 @@ void WOLFSSL_LEAVE(const char* msg, int ret)
wolfssl_log(LEAVE_LOG , buffer);
}
}
WOLFSSL_API int WOLFSSL_IS_DEBUG_ON(void)
{
return loggingEnabled;
}
#endif /* !WOLFSSL_DEBUG_ERRORS_ONLY */
#endif /* DEBUG_WOLFSSL */

View File

@@ -1383,7 +1383,7 @@ int base64_test(void)
#endif
const byte badSmall[] = "AAA Gdj=";
const byte badLarge[] = "AAA~Gdj=";
const byte badEOL[] = "A+Gd ";
const byte badEOL[] = "A+Gd AA";
int i;
/* Good Base64 encodings. */

View File

@@ -76,11 +76,14 @@ typedef struct WOLFSSL_EC_KEY WOLFSSL_EC_KEY;
typedef struct WOLFSSL_EC_POINT WOLFSSL_EC_POINT;
typedef struct WOLFSSL_EC_GROUP WOLFSSL_EC_GROUP;
typedef struct WOLFSSL_EC_BUILTIN_CURVE WOLFSSL_EC_BUILTIN_CURVE;
/* WOLFSSL_EC_METHOD is just an alias of WOLFSSL_EC_GROUP for now */
typedef struct WOLFSSL_EC_GROUP WOLFSSL_EC_METHOD;
#define WOLFSSL_EC_TYPE_DEFINED
#endif
typedef WOLFSSL_EC_KEY EC_KEY;
typedef WOLFSSL_EC_GROUP EC_GROUP;
typedef WOLFSSL_EC_GROUP EC_METHOD;
typedef WOLFSSL_EC_POINT EC_POINT;
typedef WOLFSSL_EC_BUILTIN_CURVE EC_builtin_curve;
@@ -200,6 +203,11 @@ int wolfSSL_EC_GROUP_order_bits(const WOLFSSL_EC_GROUP *group);
WOLFSSL_API
void wolfSSL_EC_GROUP_free(WOLFSSL_EC_GROUP *group);
WOLFSSL_API
const WOLFSSL_EC_METHOD* wolfSSL_EC_GROUP_method_of(
const WOLFSSL_EC_GROUP *group);
WOLFSSL_API
int wolfSSL_EC_METHOD_get_field_type(const WOLFSSL_EC_METHOD *meth);
WOLFSSL_API
WOLFSSL_EC_POINT *wolfSSL_EC_POINT_new(const WOLFSSL_EC_GROUP *group);
WOLFSSL_API
int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group,
@@ -265,6 +273,9 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group,
#define EC_GROUP_get_degree wolfSSL_EC_GROUP_get_degree
#define EC_GROUP_get_order wolfSSL_EC_GROUP_get_order
#define EC_GROUP_order_bits wolfSSL_EC_GROUP_order_bits
#define EC_GROUP_method_of wolfSSL_EC_GROUP_method_of
#define EC_METHOD_get_field_type wolfSSL_EC_METHOD_get_field_type
#define EC_POINT_new wolfSSL_EC_POINT_new
#define EC_POINT_free wolfSSL_EC_POINT_free

View File

@@ -1207,8 +1207,6 @@ enum {
#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
#define TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9)
#define EC_METHOD_get_field_type(x) -1
#define EVP_CIPHER_mode WOLFSSL_CIPHER_mode
/* WOLFSSL_EVP_CIPHER is just the string name of the cipher */
#define EVP_CIPHER_name(x) x

View File

@@ -151,6 +151,8 @@ typedef struct WOLFSSL_EC_KEY WOLFSSL_EC_KEY;
typedef struct WOLFSSL_EC_POINT WOLFSSL_EC_POINT;
typedef struct WOLFSSL_EC_GROUP WOLFSSL_EC_GROUP;
typedef struct WOLFSSL_EC_BUILTIN_CURVE WOLFSSL_EC_BUILTIN_CURVE;
/* WOLFSSL_EC_METHOD is just an alias of WOLFSSL_EC_GROUP for now */
typedef struct WOLFSSL_EC_GROUP WOLFSSL_EC_METHOD;
#define WOLFSSL_EC_TYPE_DEFINED
#endif

View File

@@ -93,6 +93,7 @@ typedef void (*wolfSSL_Logging_cb)(const int logLevel,
const char *const logMessage);
WOLFSSL_API int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb log_function);
WOLFSSL_API wolfSSL_Logging_cb wolfSSL_GetLoggingCb(void);
/* turn logging on, only if compiled in */
WOLFSSL_API int wolfSSL_Debugging_ON(void);
@@ -148,6 +149,7 @@ WOLFSSL_API void wolfSSL_Debugging_OFF(void);
WOLFSSL_API void WOLFSSL_LEAVE(const char* msg, int ret);
#define WOLFSSL_STUB(m) \
WOLFSSL_MSG(WOLFSSL_LOG_CAT(wolfSSL Stub, m, not implemented))
WOLFSSL_API int WOLFSSL_IS_DEBUG_ON(void);
WOLFSSL_API void WOLFSSL_MSG(const char* msg);
WOLFSSL_API void WOLFSSL_BUFFER(const byte* buffer, word32 length);
@@ -157,6 +159,7 @@ WOLFSSL_API void wolfSSL_Debugging_OFF(void);
#define WOLFSSL_ENTER(m)
#define WOLFSSL_LEAVE(m, r)
#define WOLFSSL_STUB(m)
#define WOLFSSL_IS_DEBUG_ON() 0
#define WOLFSSL_MSG(m)
#define WOLFSSL_BUFFER(b, l)

View File

@@ -258,6 +258,11 @@
#ifndef FP_MAX_BITS
#define FP_MAX_BITS 4096
#endif
#ifdef WOLFSSL_OPENSSH
/* OpenSSH uses some BIG primes so we need to accommodate for that */
#undef FP_MAX_BITS
#define FP_MAX_BITS 16384
#endif
#define FP_MAX_SIZE (FP_MAX_BITS+(8*DIGIT_BIT))
/* will this lib work? */