forked from wolfSSL/wolfssl
fix bio gets and enhance x509 get public key
This commit is contained in:
24
src/bio.c
24
src/bio.c
@ -38,7 +38,7 @@ WOLFSSL_API long wolfSSL_BIO_ctrl(WOLFSSL_BIO *bio, int cmd, long larg, void *pa
|
||||
|
||||
/* helper function for wolfSSL_BIO_gets
|
||||
* size till a newline is hit
|
||||
* returns the number of bytes
|
||||
* returns the number of bytes including the new line character
|
||||
*/
|
||||
static int wolfSSL_getLineLength(char* in, int inSz)
|
||||
{
|
||||
@ -46,11 +46,11 @@ static int wolfSSL_getLineLength(char* in, int inSz)
|
||||
|
||||
for (i = 0; i < inSz; i++) {
|
||||
if (in[i] == '\n') {
|
||||
break;
|
||||
return i + 1; /* includes new line character */
|
||||
}
|
||||
}
|
||||
|
||||
return i + 1; /* +1 to return number of bytes not index */
|
||||
return inSz; /* rest of buffer is all one line */
|
||||
}
|
||||
|
||||
|
||||
@ -72,6 +72,10 @@ int wolfSSL_BIO_gets(WOLFSSL_BIO* bio, char* buf, int sz)
|
||||
switch (bio->type) {
|
||||
#ifndef NO_FILESYSTEM
|
||||
case WOLFSSL_BIO_FILE:
|
||||
if (bio->file == NULL) {
|
||||
return WOLFSSL_BIO_ERROR;
|
||||
}
|
||||
|
||||
#if defined(MICRIUM) || defined(LSR_FS) || defined(EBSNET)
|
||||
WOLFSSL_MSG("XFGETS not ported for this system yet");
|
||||
ret = XFGETS(buf, sz, bio->file);
|
||||
@ -103,10 +107,15 @@ int wolfSSL_BIO_gets(WOLFSSL_BIO* bio, char* buf, int sz)
|
||||
cSz = wolfSSL_getLineLength((char*)c, cSz);
|
||||
/* check case where line was bigger then buffer and buffer
|
||||
* needs end terminator */
|
||||
if (cSz > sz) {
|
||||
if (cSz >= sz) {
|
||||
cSz = sz - 1;
|
||||
buf[cSz] = '\0';
|
||||
}
|
||||
else {
|
||||
/* not minus 1 here because placing terminator after
|
||||
msg and have checked that sz is large enough */
|
||||
buf[cSz] = '\0';
|
||||
}
|
||||
|
||||
ret = wolfSSL_BIO_read(bio, (void*)buf, cSz);
|
||||
/* ret is read after the switch statment */
|
||||
@ -125,10 +134,15 @@ int wolfSSL_BIO_gets(WOLFSSL_BIO* bio, char* buf, int sz)
|
||||
cSz = wolfSSL_getLineLength(c, cSz);
|
||||
/* check case where line was bigger then buffer and buffer
|
||||
* needs end terminator */
|
||||
if (cSz > sz) {
|
||||
if (cSz >= sz) {
|
||||
cSz = sz - 1;
|
||||
buf[cSz] = '\0';
|
||||
}
|
||||
else {
|
||||
/* not minus 1 here because placing terminator after
|
||||
msg and have checked that sz is large enough */
|
||||
buf[cSz] = '\0';
|
||||
}
|
||||
|
||||
ret = wolfSSL_BIO_nread(bio, &c, cSz);
|
||||
if (ret > 0 && ret < sz) {
|
||||
|
123
src/ssl.c
123
src/ssl.c
@ -17220,34 +17220,6 @@ WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_nextUpdate(WOLFSSL_X509_CRL* crl)
|
||||
|
||||
|
||||
|
||||
WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
|
||||
{
|
||||
WOLFSSL_EVP_PKEY* key = NULL;
|
||||
if (x509 != NULL) {
|
||||
key = (WOLFSSL_EVP_PKEY*)XMALLOC(
|
||||
sizeof(WOLFSSL_EVP_PKEY), x509->heap,
|
||||
DYNAMIC_TYPE_PUBLIC_KEY);
|
||||
if (key != NULL) {
|
||||
key->type = EVP_PKEY_RSA; /*x509->pubKeyOID;*/
|
||||
key->save_type = 0;
|
||||
key->pkey.ptr = (char*)XMALLOC(
|
||||
x509->pubKey.length, x509->heap,
|
||||
DYNAMIC_TYPE_PUBLIC_KEY);
|
||||
if (key->pkey.ptr == NULL) {
|
||||
XFREE(key, x509->heap, DYNAMIC_TYPE_PUBLIC_KEY);
|
||||
return NULL;
|
||||
}
|
||||
XMEMCPY(key->pkey.ptr,
|
||||
x509->pubKey.buffer, x509->pubKey.length);
|
||||
key->pkey_sz = x509->pubKey.length;
|
||||
#ifdef HAVE_ECC
|
||||
key->pkey_curve = (int)x509->pkCurveOID;
|
||||
#endif /* HAVE_ECC */
|
||||
}
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
int wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL* crl, WOLFSSL_EVP_PKEY* key)
|
||||
{
|
||||
@ -17334,6 +17306,14 @@ void wolfSSL_EVP_PKEY_free(WOLFSSL_EVP_PKEY* key)
|
||||
break;
|
||||
#endif /* NO_RSA */
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
case EVP_PKEY_EC:
|
||||
if (key->ecc != NULL && key->ownEcc == 1) {
|
||||
wolfSSL_EC_KEY_free(key->ecc);
|
||||
}
|
||||
break;
|
||||
#endif /* HAVE_ECC */
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -24478,6 +24458,91 @@ int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key,
|
||||
}
|
||||
#endif /* HAVE_ECC */
|
||||
|
||||
|
||||
WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
|
||||
{
|
||||
WOLFSSL_EVP_PKEY* key = NULL;
|
||||
if (x509 != NULL) {
|
||||
key = (WOLFSSL_EVP_PKEY*)XMALLOC(
|
||||
sizeof(WOLFSSL_EVP_PKEY), x509->heap,
|
||||
DYNAMIC_TYPE_PUBLIC_KEY);
|
||||
if (key != NULL) {
|
||||
XMEMSET(key, 0, sizeof(WOLFSSL_EVP_PKEY));
|
||||
if (x509->pubKeyOID == RSAk) {
|
||||
key->type = EVP_PKEY_RSA;
|
||||
}
|
||||
else {
|
||||
key->type = EVP_PKEY_EC;
|
||||
}
|
||||
key->save_type = 0;
|
||||
key->pkey.ptr = (char*)XMALLOC(
|
||||
x509->pubKey.length, x509->heap,
|
||||
DYNAMIC_TYPE_PUBLIC_KEY);
|
||||
if (key->pkey.ptr == NULL) {
|
||||
XFREE(key, x509->heap, DYNAMIC_TYPE_PUBLIC_KEY);
|
||||
return NULL;
|
||||
}
|
||||
XMEMCPY(key->pkey.ptr, x509->pubKey.buffer, x509->pubKey.length);
|
||||
key->pkey_sz = x509->pubKey.length;
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
key->pkey_curve = (int)x509->pkCurveOID;
|
||||
#endif /* HAVE_ECC */
|
||||
|
||||
/* decode RSA key */
|
||||
#ifndef NO_RSA
|
||||
if (key->type == EVP_PKEY_RSA) {
|
||||
key->ownRsa = 1;
|
||||
key->rsa = wolfSSL_RSA_new();
|
||||
if (key->rsa == NULL) {
|
||||
XFREE(key, x509->heap, DYNAMIC_TYPE_PUBLIC_KEY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (wolfSSL_RSA_LoadDer_ex(key->rsa,
|
||||
(const unsigned char*)key->pkey.ptr, key->pkey_sz,
|
||||
WOLFSSL_RSA_LOAD_PUBLIC) != SSL_SUCCESS) {
|
||||
XFREE(key, x509->heap, DYNAMIC_TYPE_PUBLIC_KEY);
|
||||
wolfSSL_RSA_free(key->rsa);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif /* NO_RSA */
|
||||
|
||||
/* decode ECC key */
|
||||
#ifdef HAVE_ECC
|
||||
if (key->type == EVP_PKEY_EC) {
|
||||
key->ownEcc = 1;
|
||||
key->ecc = wolfSSL_EC_KEY_new();
|
||||
if (key->ecc == NULL || key->ecc->internal == NULL) {
|
||||
XFREE(key, x509->heap, DYNAMIC_TYPE_PUBLIC_KEY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* not using wolfSSL_EC_KEY_LoadDer because public key in x509
|
||||
* is in the format of x963 (no sequence at start of buffer) */
|
||||
if (wc_ecc_import_x963((const unsigned char*)key->pkey.ptr,
|
||||
key->pkey_sz, (ecc_key*)key->ecc->internal) < 0) {
|
||||
WOLFSSL_MSG("wc_ecc_import_x963 failed");
|
||||
XFREE(key, x509->heap, DYNAMIC_TYPE_PUBLIC_KEY);
|
||||
wolfSSL_EC_KEY_free(key->ecc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (SetECKeyExternal(key->ecc) != SSL_SUCCESS) {
|
||||
WOLFSSL_MSG("SetECKeyExternal failed");
|
||||
XFREE(key, x509->heap, DYNAMIC_TYPE_PUBLIC_KEY);
|
||||
wolfSSL_EC_KEY_free(key->ecc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
key->ecc->inSet = 1;
|
||||
}
|
||||
#endif /* HAVE_ECC */
|
||||
}
|
||||
}
|
||||
return key;
|
||||
}
|
||||
#endif /* OPENSSL_EXTRA */
|
||||
|
||||
|
||||
@ -26292,7 +26357,7 @@ WOLFSSL_BIO *wolfSSL_BIO_new_file(const char *filename, const char *mode)
|
||||
(void)filename;
|
||||
(void)mode;
|
||||
return NULL;
|
||||
#endif
|
||||
#endif /* NO_FILESYSTEM */
|
||||
}
|
||||
|
||||
|
||||
|
104
tests/api.c
104
tests/api.c
@ -13716,7 +13716,34 @@ static void test_wolfSSL_CTX_add_extra_chain_cert(void)
|
||||
|
||||
x509 = wolfSSL_X509_load_certificate_file(clientFile, WOLFSSL_FILETYPE_PEM);
|
||||
AssertNotNull(x509);
|
||||
AssertIntEQ((int)SSL_CTX_add_extra_chain_cert(ctx, x509), WOLFSSL_SUCCESS);
|
||||
|
||||
/* additional test of getting EVP_PKEY key size from X509 */
|
||||
{
|
||||
EVP_PKEY* pkey;
|
||||
#if defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256)
|
||||
X509* ecX509;
|
||||
#endif /* HAVE_ECC */
|
||||
|
||||
AssertNotNull(pkey = X509_get_pubkey(x509));
|
||||
/* current RSA key is 2048 bit (256 bytes) */
|
||||
AssertIntEQ(EVP_PKEY_size(pkey), 256);
|
||||
|
||||
EVP_PKEY_free(pkey);
|
||||
|
||||
#if defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256)
|
||||
AssertNotNull(ecX509 = wolfSSL_X509_load_certificate_buffer(
|
||||
cliecc_cert_der_256, sizeof_cliecc_cert_der_256,
|
||||
SSL_FILETYPE_ASN1));
|
||||
AssertNotNull(pkey = X509_get_pubkey(ecX509));
|
||||
/* current ECC key is 256 bit (32 bytes) */
|
||||
AssertIntEQ(EVP_PKEY_size(pkey), 32);
|
||||
|
||||
X509_free(ecX509);
|
||||
EVP_PKEY_free(pkey);
|
||||
#endif /* HAVE_ECC */
|
||||
}
|
||||
|
||||
AssertIntEQ((int)SSL_CTX_add_extra_chain_cert(ctx, x509), SSL_SUCCESS);
|
||||
|
||||
AssertNull(SSL_CTX_get_default_passwd_cb(ctx));
|
||||
AssertNull(SSL_CTX_get_default_passwd_cb_userdata(ctx));
|
||||
@ -14551,7 +14578,7 @@ static void test_wolfSSL_BIO(void)
|
||||
BIO_free(f_bio1);
|
||||
BIO_free(f_bio2);
|
||||
|
||||
AssertNotNull(f_bio1 = BIO_new_file(svrCert, "rwb"));
|
||||
AssertNotNull(f_bio1 = BIO_new_file(svrCertFile, "rwb"));
|
||||
AssertIntEQ((int)BIO_set_mem_eof_return(f_bio1, -1), 0);
|
||||
AssertIntEQ(BIO_read(f_bio1, cert, sizeof(cert)), sizeof(cert));
|
||||
BIO_free(f_bio1);
|
||||
@ -14977,6 +15004,7 @@ static void test_wolfSSL_BIO_gets(void)
|
||||
BIO* bio;
|
||||
BIO* bio2;
|
||||
char msg[] = "\nhello wolfSSL\n security plus\t---...**adf\na...b.c";
|
||||
char emp[] = "";
|
||||
char buffer[20];
|
||||
int bufferSz = 20;
|
||||
|
||||
@ -14989,6 +15017,9 @@ static void test_wolfSSL_BIO_gets(void)
|
||||
AssertNotNull(bio2 = BIO_find_type(bio, BIO_TYPE_BIO));
|
||||
AssertFalse(bio2 != BIO_next(bio));
|
||||
|
||||
/* make buffer filled with no terminating characters */
|
||||
XMEMSET(buffer, 1, bufferSz);
|
||||
|
||||
/* BIO_gets reads a line of data */
|
||||
AssertIntEQ(BIO_gets(bio, buffer, -3), 0);
|
||||
AssertIntEQ(BIO_gets(bio, buffer, bufferSz), 1);
|
||||
@ -14998,6 +15029,75 @@ static void test_wolfSSL_BIO_gets(void)
|
||||
AssertIntEQ(BIO_gets(bio, buffer, bufferSz), 8);
|
||||
AssertIntEQ(BIO_gets(bio, buffer, -1), 0);
|
||||
|
||||
/* check not null terminated string */
|
||||
BIO_free(bio);
|
||||
msg[0] = 0x33;
|
||||
msg[1] = 0x33;
|
||||
msg[2] = 0x33;
|
||||
AssertNotNull(bio = BIO_new_mem_buf((void*)msg, 3));
|
||||
AssertIntEQ(BIO_gets(bio, buffer, 3), 2);
|
||||
AssertIntEQ(buffer[0], msg[0]);
|
||||
AssertIntEQ(buffer[1], msg[1]);
|
||||
AssertIntNE(buffer[2], msg[2]);
|
||||
|
||||
BIO_free(bio);
|
||||
msg[3] = 0x33;
|
||||
buffer[3] = 0x33;
|
||||
AssertNotNull(bio = BIO_new_mem_buf((void*)msg, 3));
|
||||
AssertIntEQ(BIO_gets(bio, buffer, bufferSz), 3);
|
||||
AssertIntEQ(buffer[0], msg[0]);
|
||||
AssertIntEQ(buffer[1], msg[1]);
|
||||
AssertIntEQ(buffer[2], msg[2]);
|
||||
AssertIntNE(buffer[3], 0x33); /* make sure null terminator was set */
|
||||
|
||||
/* check reading an empty string */
|
||||
BIO_free(bio);
|
||||
AssertNotNull(bio = BIO_new_mem_buf((void*)emp, sizeof(emp)));
|
||||
AssertIntEQ(BIO_gets(bio, buffer, bufferSz), 1); /* just terminator */
|
||||
AssertStrEQ(emp, buffer);
|
||||
|
||||
/* check error cases */
|
||||
BIO_free(bio);
|
||||
AssertIntEQ(BIO_gets(NULL, NULL, 0), SSL_FAILURE);
|
||||
AssertNotNull(bio = BIO_new(BIO_s_mem()));
|
||||
AssertIntEQ(BIO_gets(bio, buffer, 2), -1); /* nothing to read */
|
||||
|
||||
#if !defined(NO_FILESYSTEM)
|
||||
{
|
||||
BIO* f_bio;
|
||||
XFILE f;
|
||||
AssertNotNull(f_bio = BIO_new(BIO_s_file()));
|
||||
AssertIntLE(BIO_gets(f_bio, buffer, bufferSz), 0);
|
||||
|
||||
f = XFOPEN(svrCertFile, "rb");
|
||||
AssertIntEQ((int)BIO_set_fp(f_bio, f, BIO_CLOSE), SSL_SUCCESS);
|
||||
AssertIntGT(BIO_gets(f_bio, buffer, bufferSz), 0);
|
||||
|
||||
BIO_free(f_bio);
|
||||
}
|
||||
#endif /* NO_FILESYSTEM */
|
||||
|
||||
BIO_free(bio);
|
||||
BIO_free(bio2);
|
||||
|
||||
/* try with type BIO */
|
||||
XMEMCPY(msg, "\nhello wolfSSL\n security plus\t---...**adf\na...b.c",
|
||||
sizeof(msg));
|
||||
AssertNotNull(bio = BIO_new(BIO_s_bio()));
|
||||
AssertNotNull(bio2 = BIO_new(BIO_s_bio()));
|
||||
|
||||
AssertIntEQ(BIO_set_write_buf_size(bio, 10), SSL_SUCCESS);
|
||||
AssertIntEQ(BIO_set_write_buf_size(bio2, sizeof(msg)), SSL_SUCCESS);
|
||||
AssertIntEQ(BIO_make_bio_pair(bio, bio2), SSL_SUCCESS);
|
||||
|
||||
AssertIntEQ(BIO_write(bio2, msg, sizeof(msg)), sizeof(msg));
|
||||
AssertIntEQ(BIO_gets(bio, buffer, -3), 0);
|
||||
AssertIntEQ(BIO_gets(bio, buffer, bufferSz), 1);
|
||||
AssertIntEQ(BIO_gets(bio, buffer, bufferSz), 14);
|
||||
AssertStrEQ(buffer, "hello wolfSSL\n");
|
||||
AssertIntEQ(BIO_gets(bio, buffer, bufferSz), 19);
|
||||
AssertIntEQ(BIO_gets(bio, buffer, bufferSz), 8);
|
||||
AssertIntEQ(BIO_gets(bio, buffer, -1), 0);
|
||||
|
||||
BIO_free(bio);
|
||||
BIO_free(bio2);
|
||||
|
@ -756,8 +756,14 @@ WOLFSSL_API int wolfSSL_EVP_PKEY_size(WOLFSSL_EVP_PKEY *pkey)
|
||||
#endif /* NO_RSA */
|
||||
|
||||
case EVP_PKEY_EC:
|
||||
WOLFSSL_MSG("not implemented");
|
||||
/* not implemented */
|
||||
#ifdef HAVE_ECC
|
||||
if (pkey->ecc == NULL || pkey->ecc->internal == NULL) {
|
||||
WOLFSSL_MSG("No ECC key has been set");
|
||||
return 0;
|
||||
}
|
||||
return wc_ecc_size((ecc_key*)(pkey->ecc->internal));
|
||||
#endif /* HAVE_ECC */
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -531,11 +531,6 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX;
|
||||
/* yassl had set the default to be 500 */
|
||||
#define SSL_get_default_timeout(ctx) 500
|
||||
|
||||
/* Lighthttp compatibility */
|
||||
|
||||
#if defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
|
||||
defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
|
||||
defined(HAVE_POCO_LIB) || defined(WOLFSSL_HAPROXY)
|
||||
typedef WOLFSSL_X509_NAME_ENTRY X509_NAME_ENTRY;
|
||||
|
||||
#define X509_NAME_free wolfSSL_X509_NAME_free
|
||||
@ -604,7 +599,6 @@ enum {
|
||||
#define sk_SSL_COMP_zero wolfSSL_sk_SSL_COMP_zero
|
||||
#define sk_SSL_CIPHER_value wolfSSL_sk_SSL_CIPHER_value
|
||||
#endif /* WOLFSSL_HAPROXY */
|
||||
#endif /* HAVE_STUNNEL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */
|
||||
|
||||
#define SSL_CTX_set_tmp_dh wolfSSL_CTX_set_tmp_dh
|
||||
|
||||
|
@ -207,6 +207,10 @@ typedef struct WOLFSSL_EVP_PKEY {
|
||||
WOLFSSL_RSA* rsa;
|
||||
byte ownRsa; /* if struct owns RSA and should free it */
|
||||
#endif
|
||||
#ifdef HAVE_ECC
|
||||
WOLFSSL_EC_KEY* ecc;
|
||||
byte ownEcc; /* if struct owns ECC and should free it */
|
||||
#endif
|
||||
WC_RNG rng;
|
||||
#endif
|
||||
#ifdef HAVE_ECC
|
||||
|
Reference in New Issue
Block a user