mirror of https://github.com/wolfSSL/wolfssl.git
First pass at changes to move PemToDer into asn.c.
parent
2ded38ec2b
commit
f9e830bce7
|
@ -14974,9 +14974,6 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
|
|||
case SUITES_ERROR:
|
||||
return "Suites Pointer Error";
|
||||
|
||||
case SSL_NO_PEM_HEADER:
|
||||
return "No PEM Header Error";
|
||||
|
||||
case OUT_OF_ORDER_E:
|
||||
return "Out of order message, fatal";
|
||||
|
||||
|
|
533
src/ssl.c
533
src/ssl.c
|
@ -2931,59 +2931,6 @@ int wolfSSL_GetHmacSize(WOLFSSL* ssl)
|
|||
#endif /* ATOMIC_USER */
|
||||
|
||||
#ifndef NO_CERTS
|
||||
int AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)
|
||||
{
|
||||
int ret = BAD_FUNC_ARG;
|
||||
if (pDer) {
|
||||
int dynType = 0;
|
||||
DerBuffer* der;
|
||||
|
||||
/* Determine dynamic type */
|
||||
switch (type) {
|
||||
case CA_TYPE: dynType = DYNAMIC_TYPE_CA; break;
|
||||
case CERT_TYPE: dynType = DYNAMIC_TYPE_CERT; break;
|
||||
case CRL_TYPE: dynType = DYNAMIC_TYPE_CRL; break;
|
||||
case DSA_TYPE: dynType = DYNAMIC_TYPE_DSA; break;
|
||||
case ECC_TYPE: dynType = DYNAMIC_TYPE_ECC; break;
|
||||
case RSA_TYPE: dynType = DYNAMIC_TYPE_RSA; break;
|
||||
default: dynType = DYNAMIC_TYPE_KEY; break;
|
||||
}
|
||||
|
||||
/* Setup new buffer */
|
||||
*pDer = (DerBuffer*)XMALLOC(sizeof(DerBuffer) + length, heap, dynType);
|
||||
if (*pDer == NULL) {
|
||||
return MEMORY_ERROR;
|
||||
}
|
||||
XMEMSET(*pDer, 0, sizeof(DerBuffer) + length);
|
||||
|
||||
der = *pDer;
|
||||
der->type = type;
|
||||
der->dynType = dynType; /* Cache this for FreeDer */
|
||||
der->heap = heap;
|
||||
der->buffer = (byte*)der + sizeof(DerBuffer);
|
||||
der->length = length;
|
||||
ret = 0; /* Success */
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FreeDer(DerBuffer** pDer)
|
||||
{
|
||||
if (pDer && *pDer)
|
||||
{
|
||||
DerBuffer* der = (DerBuffer*)*pDer;
|
||||
|
||||
/* ForceZero private keys */
|
||||
if (der->type == PRIVATEKEY_TYPE) {
|
||||
ForceZero(der->buffer, der->length);
|
||||
}
|
||||
der->buffer = NULL;
|
||||
der->length = 0;
|
||||
XFREE(der, der->heap, der->dynType);
|
||||
|
||||
*pDer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
WOLFSSL_CERT_MANAGER* wolfSSL_CTX_GetCertManager(WOLFSSL_CTX* ctx)
|
||||
{
|
||||
|
@ -4645,318 +4592,6 @@ static int wolfssl_encrypt_buffer_key(byte* der, word32 derSz, byte* password,
|
|||
|
||||
#ifndef NO_CERTS
|
||||
|
||||
/* 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,
|
||||
DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey)
|
||||
{
|
||||
const char* header = NULL;
|
||||
const char* footer = NULL;
|
||||
char* headerEnd;
|
||||
char* footerEnd;
|
||||
char* consumedEnd;
|
||||
char* bufferEnd = (char*)(buff + longSz);
|
||||
long neededSz;
|
||||
int ret = 0;
|
||||
int sz = (int)longSz;
|
||||
int encrypted_key = 0;
|
||||
DerBuffer* der;
|
||||
|
||||
WOLFSSL_ENTER("PemToDer");
|
||||
|
||||
switch (type) {
|
||||
case CA_TYPE: /* same as below */
|
||||
case TRUSTED_PEER_TYPE:
|
||||
case CERT_TYPE: header=BEGIN_CERT; footer=END_CERT;
|
||||
break;
|
||||
case CRL_TYPE: header=BEGIN_X509_CRL; footer=END_X509_CRL;
|
||||
break;
|
||||
#ifndef NO_DH
|
||||
case DH_PARAM_TYPE: header=BEGIN_DH_PARAM; footer=END_DH_PARAM;
|
||||
break;
|
||||
#endif
|
||||
#ifndef NO_DSA
|
||||
case DSA_PARAM_TYPE: header=BEGIN_DSA_PARAM; footer=END_DSA_PARAM;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_CERT_REQ
|
||||
case CERTREQ_TYPE: header=BEGIN_CERT_REQ; footer=END_CERT_REQ;
|
||||
break;
|
||||
#endif
|
||||
#ifndef NO_DSA
|
||||
case DSA_TYPE: header=BEGIN_DSA_PRIV; footer=END_DSA_PRIV;
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_ECC
|
||||
case ECC_TYPE: header=BEGIN_EC_PRIV; footer=END_EC_PRIV;
|
||||
break;
|
||||
#endif
|
||||
case RSA_TYPE: header=BEGIN_RSA_PRIV; footer=END_RSA_PRIV;
|
||||
break;
|
||||
#ifdef HAVE_ED25519
|
||||
case ED25519_TYPE: header=BEGIN_EDDSA_PRIV; footer=END_EDDSA_PRIV;
|
||||
break;
|
||||
#endif
|
||||
case PUBLICKEY_TYPE: header=BEGIN_PUB_KEY; footer=END_PUB_KEY;
|
||||
break;
|
||||
default: header=BEGIN_RSA_PRIV; footer=END_RSA_PRIV;
|
||||
break;
|
||||
}
|
||||
|
||||
/* find header */
|
||||
for (;;) {
|
||||
headerEnd = XSTRNSTR((char*)buff, header, sz);
|
||||
|
||||
if (headerEnd || type != PRIVATEKEY_TYPE) {
|
||||
break;
|
||||
} else
|
||||
if (header == BEGIN_RSA_PRIV) {
|
||||
header = BEGIN_PRIV_KEY; footer = END_PRIV_KEY;
|
||||
} else
|
||||
if (header == BEGIN_PRIV_KEY) {
|
||||
header = BEGIN_ENC_PRIV_KEY; footer = END_ENC_PRIV_KEY;
|
||||
} else
|
||||
#ifdef HAVE_ECC
|
||||
if (header == BEGIN_ENC_PRIV_KEY) {
|
||||
header = BEGIN_EC_PRIV; footer = END_EC_PRIV;
|
||||
} else
|
||||
if (header == BEGIN_EC_PRIV) {
|
||||
header = BEGIN_DSA_PRIV; footer = END_DSA_PRIV;
|
||||
} else
|
||||
#endif
|
||||
#ifdef HAVE_ED25519
|
||||
#ifdef HAVE_ECC
|
||||
if (header == BEGIN_DSA_PRIV)
|
||||
#else
|
||||
if (header == BEGIN_ENC_PRIV_KEY)
|
||||
#endif
|
||||
{
|
||||
header = BEGIN_EDDSA_PRIV; footer = END_EDDSA_PRIV;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!headerEnd) {
|
||||
WOLFSSL_MSG("Couldn't find PEM header");
|
||||
return SSL_NO_PEM_HEADER;
|
||||
}
|
||||
|
||||
headerEnd += XSTRLEN(header);
|
||||
|
||||
if ((headerEnd + 1) >= bufferEnd)
|
||||
return WOLFSSL_BAD_FILE;
|
||||
|
||||
/* eat end of line */
|
||||
if (headerEnd[0] == '\n')
|
||||
headerEnd++;
|
||||
else if (headerEnd[1] == '\n')
|
||||
headerEnd += 2;
|
||||
else {
|
||||
if (info)
|
||||
info->consumed = (long)(headerEnd+2 - (char*)buff);
|
||||
return WOLFSSL_BAD_FILE;
|
||||
}
|
||||
|
||||
if (type == PRIVATEKEY_TYPE) {
|
||||
if (eccKey) {
|
||||
#ifdef HAVE_ECC
|
||||
*eccKey = header == BEGIN_EC_PRIV;
|
||||
#else
|
||||
*eccKey = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
|
||||
defined(HAVE_WEBSERVER)
|
||||
{
|
||||
/* remove encrypted header if there */
|
||||
const char* const encHeader = "Proc-Type";
|
||||
word32 headerEndSz = (word32)(bufferEnd - headerEnd);
|
||||
char* line = XSTRNSTR(headerEnd, encHeader, min(headerEndSz,
|
||||
PEM_LINE_LEN));
|
||||
if (line != NULL) {
|
||||
word32 lineSz;
|
||||
char* finish;
|
||||
word32 finishSz;
|
||||
char* start = NULL;
|
||||
word32 startSz;
|
||||
char* newline;
|
||||
|
||||
if (line >= bufferEnd) {
|
||||
return WOLFSSL_BAD_FILE;
|
||||
}
|
||||
|
||||
lineSz = (word32)(bufferEnd - line);
|
||||
#ifndef NO_DES3
|
||||
start = XSTRNSTR(line, "DES", min(lineSz, PEM_LINE_LEN));
|
||||
#endif
|
||||
|
||||
#ifndef NO_AES
|
||||
if (start == NULL) {
|
||||
start = XSTRNSTR(line, "AES", min(lineSz, PEM_LINE_LEN));
|
||||
}
|
||||
#endif
|
||||
|
||||
(void)lineSz;
|
||||
if (start == NULL) return WOLFSSL_BAD_FILE;
|
||||
if (info == NULL) return WOLFSSL_BAD_FILE;
|
||||
|
||||
if (start >= bufferEnd) {
|
||||
return WOLFSSL_BAD_FILE;
|
||||
}
|
||||
|
||||
startSz = (word32)(bufferEnd - start);
|
||||
finish = XSTRNSTR(start, ",", min(startSz, PEM_LINE_LEN));
|
||||
|
||||
if ((start != NULL) && (finish != NULL) && (start < finish)) {
|
||||
if (finish >= bufferEnd) {
|
||||
return WOLFSSL_BAD_FILE;
|
||||
}
|
||||
|
||||
finishSz = (word32)(bufferEnd - finish);
|
||||
newline = XSTRNSTR(finish, "\r", min(finishSz, PEM_LINE_LEN));
|
||||
|
||||
if (NAME_SZ < (finish - start)) /* buffer size of info->name*/
|
||||
return BUFFER_E;
|
||||
if (XMEMCPY(info->name, start, finish - start) == NULL)
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
info->name[finish - start] = 0;
|
||||
if (finishSz < sizeof(info->iv) + 1)
|
||||
return BUFFER_E;
|
||||
if (XMEMCPY(info->iv, finish + 1, sizeof(info->iv)) == NULL)
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
|
||||
if (newline == NULL)
|
||||
newline = XSTRNSTR(finish, "\n", min(finishSz,
|
||||
PEM_LINE_LEN));
|
||||
if ((newline != NULL) && (newline > finish)) {
|
||||
info->ivSz = (word32)(newline - (finish + 1));
|
||||
info->set = 1;
|
||||
}
|
||||
else
|
||||
return WOLFSSL_BAD_FILE;
|
||||
}
|
||||
else
|
||||
return WOLFSSL_BAD_FILE;
|
||||
|
||||
/* eat blank line */
|
||||
while (newline < bufferEnd &&
|
||||
(*newline == '\r' || *newline == '\n'))
|
||||
newline++;
|
||||
headerEnd = newline;
|
||||
|
||||
encrypted_key = 1;
|
||||
}
|
||||
}
|
||||
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL || HAVE_WEBSERVER */
|
||||
|
||||
/* find footer */
|
||||
footerEnd = XSTRNSTR((char*)buff, footer, sz);
|
||||
if (!footerEnd) {
|
||||
if (info)
|
||||
info->consumed = longSz; /* No more certs if no footer */
|
||||
return WOLFSSL_BAD_FILE;
|
||||
}
|
||||
|
||||
consumedEnd = footerEnd + XSTRLEN(footer);
|
||||
|
||||
if (consumedEnd < bufferEnd) { /* handle no end of line on last line */
|
||||
/* eat end of line */
|
||||
if (consumedEnd[0] == '\n')
|
||||
consumedEnd++;
|
||||
else if ((consumedEnd + 1 < bufferEnd) && consumedEnd[1] == '\n')
|
||||
consumedEnd += 2;
|
||||
else {
|
||||
if (info)
|
||||
info->consumed = (long)(consumedEnd+2 - (char*)buff);
|
||||
return WOLFSSL_BAD_FILE;
|
||||
}
|
||||
}
|
||||
|
||||
if (info)
|
||||
info->consumed = (long)(consumedEnd - (char*)buff);
|
||||
|
||||
/* set up der buffer */
|
||||
neededSz = (long)(footerEnd - headerEnd);
|
||||
if (neededSz > sz || neededSz <= 0)
|
||||
return WOLFSSL_BAD_FILE;
|
||||
|
||||
ret = AllocDer(pDer, (word32)neededSz, type, heap);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
der = *pDer;
|
||||
|
||||
if (Base64_Decode((byte*)headerEnd, (word32)neededSz,
|
||||
der->buffer, &der->length) < 0)
|
||||
return WOLFSSL_BAD_FILE;
|
||||
|
||||
if (header == BEGIN_PRIV_KEY && !encrypted_key) {
|
||||
/* pkcs8 key, convert and adjust length */
|
||||
if ((ret = ToTraditional(der->buffer, der->length)) < 0)
|
||||
return ret;
|
||||
|
||||
der->length = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
|
||||
defined(HAVE_WEBSERVER)) && !defined(NO_PWDBASED)
|
||||
if (encrypted_key || header == BEGIN_ENC_PRIV_KEY) {
|
||||
int passwordSz;
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
char* password = NULL;
|
||||
#else
|
||||
char password[NAME_SZ];
|
||||
#endif
|
||||
|
||||
if (!info || !info->ctx || !info->ctx->passwd_cb)
|
||||
return WOLFSSL_BAD_FILE; /* no callback error */
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
password = (char*)XMALLOC(NAME_SZ, heap, DYNAMIC_TYPE_STRING);
|
||||
if (password == NULL)
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
passwordSz = info->ctx->passwd_cb(password, NAME_SZ, 0,
|
||||
info->ctx->userdata);
|
||||
/* convert and adjust length */
|
||||
if (header == BEGIN_ENC_PRIV_KEY) {
|
||||
ret = ToTraditionalEnc(der->buffer, der->length,
|
||||
password, passwordSz);
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(password, NULL, DYNAMIC_TYPE_STRING);
|
||||
#endif
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
der->length = ret;
|
||||
}
|
||||
/* decrypt the key */
|
||||
else {
|
||||
ret = wolfssl_decrypt_buffer_key(der, (byte*)password,
|
||||
passwordSz, info);
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(password, heap, DYNAMIC_TYPE_STRING);
|
||||
#endif
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL || HAVE_WEBSERVER ||
|
||||
NO_PWDBASED */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* process user cert chain to pass during the handshake */
|
||||
static int ProcessUserChain(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||
long sz, int format, int type, WOLFSSL* ssl,
|
||||
|
@ -5010,7 +4645,7 @@ static int ProcessUserChain(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
|||
/* get length of der (read sequence) */
|
||||
word32 inOutIdx = 0;
|
||||
if (GetSequence(buff + consumed, &inOutIdx, &length, remain) < 0) {
|
||||
ret = SSL_NO_PEM_HEADER;
|
||||
ret = ASN_NO_PEM_HEADER;
|
||||
}
|
||||
length += inOutIdx; /* include leading squence */
|
||||
}
|
||||
|
@ -5043,7 +4678,7 @@ static int ProcessUserChain(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
|||
}
|
||||
FreeDer(&part);
|
||||
|
||||
if (ret == SSL_NO_PEM_HEADER && gotOne) {
|
||||
if (ret == ASN_NO_PEM_HEADER && gotOne) {
|
||||
WOLFSSL_MSG("We got one good cert, so stuff at end ok");
|
||||
break;
|
||||
}
|
||||
|
@ -6789,162 +6424,6 @@ int wolfSSL_CTX_der_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
|
|||
#endif /* WOLFSSL_DER_LOAD */
|
||||
|
||||
|
||||
#ifdef WOLFSSL_CERT_GEN
|
||||
|
||||
/* load pem cert from file into der buffer, return der size or error */
|
||||
int wolfSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz)
|
||||
{
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
EncryptedInfo* info = NULL;
|
||||
byte staticBuffer[1]; /* force XMALLOC */
|
||||
#else
|
||||
EncryptedInfo info[1];
|
||||
byte staticBuffer[FILE_BUFFER_SIZE];
|
||||
#endif
|
||||
byte* fileBuf = staticBuffer;
|
||||
int dynamic = 0;
|
||||
int ret = 0;
|
||||
int ecc = 0;
|
||||
long sz = 0;
|
||||
XFILE file = XFOPEN(fileName, "rb");
|
||||
DerBuffer* converted = NULL;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_PemCertToDer");
|
||||
|
||||
if (file == XBADFILE) {
|
||||
ret = WOLFSSL_BAD_FILE;
|
||||
}
|
||||
else {
|
||||
XFSEEK(file, 0, XSEEK_END);
|
||||
sz = XFTELL(file);
|
||||
XREWIND(file);
|
||||
|
||||
if (sz <= 0) {
|
||||
ret = WOLFSSL_BAD_FILE;
|
||||
}
|
||||
else if (sz > (long)sizeof(staticBuffer)) {
|
||||
#ifdef WOLFSSL_STATIC_MEMORY
|
||||
WOLFSSL_MSG("File was larger then static buffer");
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
fileBuf = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_FILE);
|
||||
if (fileBuf == NULL)
|
||||
ret = MEMORY_E;
|
||||
else
|
||||
dynamic = 1;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
if ( (ret = (int)XFREAD(fileBuf, 1, sz, file)) != sz) {
|
||||
ret = WOLFSSL_BAD_FILE;
|
||||
}
|
||||
else {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
|
||||
DYNAMIC_TYPE_ENCRYPTEDINFO);
|
||||
if (info == NULL)
|
||||
ret = MEMORY_E;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ret = PemToDer(fileBuf, sz, CA_TYPE, &converted,
|
||||
0, info, &ecc);
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
if (converted->length < (word32)derSz) {
|
||||
XMEMCPY(derBuf, converted->buffer, converted->length);
|
||||
ret = converted->length;
|
||||
}
|
||||
else
|
||||
ret = BUFFER_E;
|
||||
}
|
||||
|
||||
FreeDer(&converted);
|
||||
}
|
||||
|
||||
XFCLOSE(file);
|
||||
if (dynamic)
|
||||
XFREE(fileBuf, 0, DYNAMIC_TYPE_FILE);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_CERT_GEN */
|
||||
|
||||
#if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)
|
||||
/* load pem public key from file into der buffer, return der size or error */
|
||||
int wolfSSL_PemPubKeyToDer(const char* fileName,
|
||||
unsigned char* derBuf, int derSz)
|
||||
{
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
byte staticBuffer[1]; /* force XMALLOC */
|
||||
#else
|
||||
byte staticBuffer[FILE_BUFFER_SIZE];
|
||||
#endif
|
||||
byte* fileBuf = staticBuffer;
|
||||
int dynamic = 0;
|
||||
int ret = 0;
|
||||
long sz = 0;
|
||||
XFILE file = XFOPEN(fileName, "rb");
|
||||
DerBuffer* converted = NULL;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_PemPubKeyToDer");
|
||||
|
||||
if (file == XBADFILE) {
|
||||
ret = WOLFSSL_BAD_FILE;
|
||||
}
|
||||
else {
|
||||
XFSEEK(file, 0, XSEEK_END);
|
||||
sz = XFTELL(file);
|
||||
XREWIND(file);
|
||||
|
||||
if (sz <= 0) {
|
||||
ret = WOLFSSL_BAD_FILE;
|
||||
}
|
||||
else if (sz > (long)sizeof(staticBuffer)) {
|
||||
#ifdef WOLFSSL_STATIC_MEMORY
|
||||
WOLFSSL_MSG("File was larger then static buffer");
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
fileBuf = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_FILE);
|
||||
if (fileBuf == NULL)
|
||||
ret = MEMORY_E;
|
||||
else
|
||||
dynamic = 1;
|
||||
}
|
||||
if (ret == 0) {
|
||||
if ( (ret = (int)XFREAD(fileBuf, 1, sz, file)) != sz)
|
||||
ret = WOLFSSL_BAD_FILE;
|
||||
else
|
||||
ret = PemToDer(fileBuf, sz, PUBLICKEY_TYPE, &converted,
|
||||
0, NULL, NULL);
|
||||
|
||||
if (ret == 0) {
|
||||
if (converted->length < (word32)derSz) {
|
||||
XMEMCPY(derBuf, converted->buffer, converted->length);
|
||||
ret = converted->length;
|
||||
}
|
||||
else
|
||||
ret = BUFFER_E;
|
||||
}
|
||||
|
||||
FreeDer(&converted);
|
||||
}
|
||||
|
||||
XFCLOSE(file);
|
||||
if (dynamic)
|
||||
XFREE(fileBuf, 0, DYNAMIC_TYPE_FILE);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */
|
||||
|
||||
int wolfSSL_CTX_use_certificate_file(WOLFSSL_CTX* ctx, const char* file,
|
||||
int format)
|
||||
|
@ -29221,7 +28700,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
|
|||
}
|
||||
#ifdef WOLFSSL_NGINX
|
||||
if (l == 0)
|
||||
WOLFSSL_ERROR(SSL_NO_PEM_HEADER);
|
||||
WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
|
||||
#endif
|
||||
pemSz = (int)i;
|
||||
x509 = wolfSSL_X509_load_certificate_buffer(pem, pemSz,
|
||||
|
@ -30518,7 +29997,7 @@ unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line)
|
|||
return 0;
|
||||
}
|
||||
#ifdef WOLFSSL_NGINX
|
||||
if (ret == -SSL_NO_PEM_HEADER)
|
||||
if (ret == -ASN_NO_PEM_HEADER)
|
||||
return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
|
||||
#endif
|
||||
return (unsigned long)ret;
|
||||
|
@ -31356,7 +30835,7 @@ unsigned long wolfSSL_ERR_peek_last_error(void)
|
|||
WOLFSSL_MSG("Issue peeking at error node in queue");
|
||||
return 0;
|
||||
}
|
||||
if (ret == -SSL_NO_PEM_HEADER)
|
||||
if (ret == -ASN_NO_PEM_HEADER)
|
||||
return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
|
||||
return (unsigned long)ret;
|
||||
}
|
||||
|
@ -32093,7 +31572,7 @@ unsigned long wolfSSL_ERR_peek_error_line_data(const char **file, int *line,
|
|||
}
|
||||
ret = -ret;
|
||||
|
||||
if (ret == SSL_NO_PEM_HEADER)
|
||||
if (ret == ASN_NO_PEM_HEADER)
|
||||
return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
|
||||
if (ret != WANT_READ && ret != WANT_WRITE &&
|
||||
ret != ZERO_RETURN && ret != WOLFSSL_ERROR_ZERO_RETURN &&
|
||||
|
|
|
@ -7546,6 +7546,531 @@ int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz,
|
|||
|
||||
#endif /* WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN || OPENSSL_EXTRA */
|
||||
|
||||
int AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)
|
||||
{
|
||||
int ret = BAD_FUNC_ARG;
|
||||
if (pDer) {
|
||||
int dynType = 0;
|
||||
DerBuffer* der;
|
||||
|
||||
/* Determine dynamic type */
|
||||
switch (type) {
|
||||
case CA_TYPE: dynType = DYNAMIC_TYPE_CA; break;
|
||||
case CERT_TYPE: dynType = DYNAMIC_TYPE_CERT; break;
|
||||
case CRL_TYPE: dynType = DYNAMIC_TYPE_CRL; break;
|
||||
case DSA_TYPE: dynType = DYNAMIC_TYPE_DSA; break;
|
||||
case ECC_TYPE: dynType = DYNAMIC_TYPE_ECC; break;
|
||||
case RSA_TYPE: dynType = DYNAMIC_TYPE_RSA; break;
|
||||
default: dynType = DYNAMIC_TYPE_KEY; break;
|
||||
}
|
||||
|
||||
/* Setup new buffer */
|
||||
*pDer = (DerBuffer*)XMALLOC(sizeof(DerBuffer) + length, heap, dynType);
|
||||
if (*pDer == NULL) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
XMEMSET(*pDer, 0, sizeof(DerBuffer) + length);
|
||||
|
||||
der = *pDer;
|
||||
der->type = type;
|
||||
der->dynType = dynType; /* Cache this for FreeDer */
|
||||
der->heap = heap;
|
||||
der->buffer = (byte*)der + sizeof(DerBuffer);
|
||||
der->length = length;
|
||||
ret = 0; /* Success */
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FreeDer(DerBuffer** pDer)
|
||||
{
|
||||
if (pDer && *pDer)
|
||||
{
|
||||
DerBuffer* der = (DerBuffer*)*pDer;
|
||||
|
||||
/* ForceZero private keys */
|
||||
if (der->type == PRIVATEKEY_TYPE) {
|
||||
ForceZero(der->buffer, der->length);
|
||||
}
|
||||
der->buffer = NULL;
|
||||
der->length = 0;
|
||||
XFREE(der, der->heap, der->dynType);
|
||||
|
||||
*pDer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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,
|
||||
DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey)
|
||||
{
|
||||
const char* header = NULL;
|
||||
const char* footer = NULL;
|
||||
char* headerEnd;
|
||||
char* footerEnd;
|
||||
char* consumedEnd;
|
||||
char* bufferEnd = (char*)(buff + longSz);
|
||||
long neededSz;
|
||||
int ret = 0;
|
||||
int sz = (int)longSz;
|
||||
int encrypted_key = 0;
|
||||
DerBuffer* der;
|
||||
|
||||
WOLFSSL_ENTER("PemToDer");
|
||||
|
||||
switch (type) {
|
||||
case CA_TYPE: /* same as below */
|
||||
case TRUSTED_PEER_TYPE:
|
||||
case CERT_TYPE: header=BEGIN_CERT; footer=END_CERT;
|
||||
break;
|
||||
case CRL_TYPE: header=BEGIN_X509_CRL; footer=END_X509_CRL;
|
||||
break;
|
||||
#ifndef NO_DH
|
||||
case DH_PARAM_TYPE: header=BEGIN_DH_PARAM; footer=END_DH_PARAM;
|
||||
break;
|
||||
#endif
|
||||
#ifndef NO_DSA
|
||||
case DSA_PARAM_TYPE: header=BEGIN_DSA_PARAM; footer=END_DSA_PARAM;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_CERT_REQ
|
||||
case CERTREQ_TYPE: header=BEGIN_CERT_REQ; footer=END_CERT_REQ;
|
||||
break;
|
||||
#endif
|
||||
#ifndef NO_DSA
|
||||
case DSA_TYPE: header=BEGIN_DSA_PRIV; footer=END_DSA_PRIV;
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_ECC
|
||||
case ECC_TYPE: header=BEGIN_EC_PRIV; footer=END_EC_PRIV;
|
||||
break;
|
||||
#endif
|
||||
case RSA_TYPE: header=BEGIN_RSA_PRIV; footer=END_RSA_PRIV;
|
||||
break;
|
||||
#ifdef HAVE_ED25519
|
||||
case ED25519_TYPE: header=BEGIN_EDDSA_PRIV; footer=END_EDDSA_PRIV;
|
||||
break;
|
||||
#endif
|
||||
case PUBLICKEY_TYPE: header=BEGIN_PUB_KEY; footer=END_PUB_KEY;
|
||||
break;
|
||||
default: header=BEGIN_RSA_PRIV; footer=END_RSA_PRIV;
|
||||
break;
|
||||
}
|
||||
|
||||
/* find header */
|
||||
for (;;) {
|
||||
headerEnd = XSTRNSTR((char*)buff, header, sz);
|
||||
|
||||
if (headerEnd || type != PRIVATEKEY_TYPE) {
|
||||
break;
|
||||
} else
|
||||
if (header == BEGIN_RSA_PRIV) {
|
||||
header = BEGIN_PRIV_KEY; footer = END_PRIV_KEY;
|
||||
} else
|
||||
if (header == BEGIN_PRIV_KEY) {
|
||||
header = BEGIN_ENC_PRIV_KEY; footer = END_ENC_PRIV_KEY;
|
||||
} else
|
||||
#ifdef HAVE_ECC
|
||||
if (header == BEGIN_ENC_PRIV_KEY) {
|
||||
header = BEGIN_EC_PRIV; footer = END_EC_PRIV;
|
||||
} else
|
||||
if (header == BEGIN_EC_PRIV) {
|
||||
header = BEGIN_DSA_PRIV; footer = END_DSA_PRIV;
|
||||
} else
|
||||
#endif
|
||||
#ifdef HAVE_ED25519
|
||||
if (header == BEGIN_DSA_PRIV) {
|
||||
header = BEGIN_EDDSA_PRIV; footer = END_EDDSA_PRIV;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!headerEnd) {
|
||||
WOLFSSL_MSG("Couldn't find PEM header");
|
||||
return ASN_NO_PEM_HEADER;
|
||||
}
|
||||
|
||||
headerEnd += XSTRLEN(header);
|
||||
|
||||
if ((headerEnd + 1) >= bufferEnd)
|
||||
return BUFFER_E;
|
||||
|
||||
/* eat end of line */
|
||||
if (headerEnd[0] == '\n')
|
||||
headerEnd++;
|
||||
else if (headerEnd[1] == '\n')
|
||||
headerEnd += 2;
|
||||
else {
|
||||
if (info)
|
||||
info->consumed = (long)(headerEnd+2 - (char*)buff);
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
if (type == PRIVATEKEY_TYPE) {
|
||||
if (eccKey) {
|
||||
#ifdef HAVE_ECC
|
||||
*eccKey = header == BEGIN_EC_PRIV;
|
||||
#else
|
||||
*eccKey = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
|
||||
defined(HAVE_WEBSERVER)
|
||||
{
|
||||
/* remove encrypted header if there */
|
||||
const char* const encHeader = "Proc-Type";
|
||||
word32 headerEndSz = (word32)(bufferEnd - headerEnd);
|
||||
char* line = XSTRNSTR(headerEnd, encHeader, min(headerEndSz,
|
||||
PEM_LINE_LEN));
|
||||
if (line != NULL) {
|
||||
word32 lineSz;
|
||||
char* finish;
|
||||
word32 finishSz;
|
||||
char* start = NULL;
|
||||
word32 startSz;
|
||||
char* newline;
|
||||
|
||||
if (line >= bufferEnd) {
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
lineSz = (word32)(bufferEnd - line);
|
||||
#ifndef NO_DES3
|
||||
start = XSTRNSTR(line, "DES", min(lineSz, PEM_LINE_LEN));
|
||||
#endif
|
||||
|
||||
#ifndef NO_AES
|
||||
if (start == NULL) {
|
||||
start = XSTRNSTR(line, "AES", min(lineSz, PEM_LINE_LEN));
|
||||
}
|
||||
#endif
|
||||
|
||||
(void)lineSz;
|
||||
if (start == NULL) return BUFFER_E;
|
||||
if (info == NULL) return BUFFER_E;
|
||||
|
||||
if (start >= bufferEnd) {
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
startSz = (word32)(bufferEnd - start);
|
||||
finish = XSTRNSTR(start, ",", min(startSz, PEM_LINE_LEN));
|
||||
|
||||
if ((start != NULL) && (finish != NULL) && (start < finish)) {
|
||||
if (finish >= bufferEnd) {
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
finishSz = (word32)(bufferEnd - finish);
|
||||
newline = XSTRNSTR(finish, "\r", min(finishSz, PEM_LINE_LEN));
|
||||
|
||||
if (NAME_SZ < (finish - start)) /* buffer size of info->name*/
|
||||
return BUFFER_E;
|
||||
if (XMEMCPY(info->name, start, finish - start) == NULL)
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
info->name[finish - start] = 0;
|
||||
if (finishSz < sizeof(info->iv) + 1)
|
||||
return BUFFER_E;
|
||||
if (XMEMCPY(info->iv, finish + 1, sizeof(info->iv)) == NULL)
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
|
||||
if (newline == NULL)
|
||||
newline = XSTRNSTR(finish, "\n", min(finishSz,
|
||||
PEM_LINE_LEN));
|
||||
if ((newline != NULL) && (newline > finish)) {
|
||||
info->ivSz = (word32)(newline - (finish + 1));
|
||||
info->set = 1;
|
||||
}
|
||||
else
|
||||
return BUFFER_E;
|
||||
}
|
||||
else
|
||||
return BUFFER_E;
|
||||
|
||||
/* eat blank line */
|
||||
while (newline < bufferEnd &&
|
||||
(*newline == '\r' || *newline == '\n'))
|
||||
newline++;
|
||||
headerEnd = newline;
|
||||
|
||||
encrypted_key = 1;
|
||||
}
|
||||
}
|
||||
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL || HAVE_WEBSERVER */
|
||||
|
||||
/* find footer */
|
||||
footerEnd = XSTRNSTR((char*)buff, footer, sz);
|
||||
if (!footerEnd) {
|
||||
if (info)
|
||||
info->consumed = longSz; /* No more certs if no footer */
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
consumedEnd = footerEnd + XSTRLEN(footer);
|
||||
|
||||
if (consumedEnd < bufferEnd) { /* handle no end of line on last line */
|
||||
/* eat end of line */
|
||||
if (consumedEnd[0] == '\n')
|
||||
consumedEnd++;
|
||||
else if ((consumedEnd + 1 < bufferEnd) && consumedEnd[1] == '\n')
|
||||
consumedEnd += 2;
|
||||
else {
|
||||
if (info)
|
||||
info->consumed = (long)(consumedEnd+2 - (char*)buff);
|
||||
return BUFFER_E;
|
||||
}
|
||||
}
|
||||
|
||||
if (info)
|
||||
info->consumed = (long)(consumedEnd - (char*)buff);
|
||||
|
||||
/* set up der buffer */
|
||||
neededSz = (long)(footerEnd - headerEnd);
|
||||
if (neededSz > sz || neededSz <= 0)
|
||||
return BUFFER_E;
|
||||
|
||||
ret = AllocDer(pDer, (word32)neededSz, type, heap);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
der = *pDer;
|
||||
|
||||
if (Base64_Decode((byte*)headerEnd, (word32)neededSz,
|
||||
der->buffer, &der->length) < 0)
|
||||
return BUFFER_E;
|
||||
|
||||
if (header == BEGIN_PRIV_KEY && !encrypted_key) {
|
||||
/* pkcs8 key, convert and adjust length */
|
||||
if ((ret = ToTraditional(der->buffer, der->length)) < 0)
|
||||
return ret;
|
||||
|
||||
der->length = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)) && !defined(NO_PWDBASED)
|
||||
if (encrypted_key || header == BEGIN_ENC_PRIV_KEY) {
|
||||
int passwordSz;
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
char* password = NULL;
|
||||
#else
|
||||
char password[NAME_SZ];
|
||||
#endif
|
||||
|
||||
if (!info || !info->ctx || !info->ctx->passwd_cb)
|
||||
return BUFFER_E; /* no callback error */
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
password = (char*)XMALLOC(NAME_SZ, heap, DYNAMIC_TYPE_STRING);
|
||||
if (password == NULL)
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
passwordSz = info->ctx->passwd_cb(password, NAME_SZ, 0,
|
||||
info->ctx->userdata);
|
||||
/* convert and adjust length */
|
||||
if (header == BEGIN_ENC_PRIV_KEY) {
|
||||
ret = ToTraditionalEnc(der->buffer, der->length,
|
||||
password, passwordSz);
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(password, NULL, DYNAMIC_TYPE_STRING);
|
||||
#endif
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
der->length = ret;
|
||||
}
|
||||
/* decrypt the key */
|
||||
else {
|
||||
ret = wolfssl_decrypt_buffer_key(der, (byte*)password,
|
||||
passwordSz, info);
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(password, heap, DYNAMIC_TYPE_STRING);
|
||||
#endif
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER || NO_PWDBASED */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wc_PemToDer(const unsigned char* buff, long longSz, int type,
|
||||
DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey)
|
||||
{
|
||||
return PemToDer(buff, longSz, type, pDer, heap, info, eccKey);
|
||||
}
|
||||
|
||||
|
||||
#ifndef NO_FILESYSTEM
|
||||
#ifdef WOLFSSL_CERT_GEN
|
||||
|
||||
/* load pem cert from file into der buffer, return der size or error */
|
||||
int wolfSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz)
|
||||
{
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
EncryptedInfo* info = NULL;
|
||||
byte staticBuffer[1]; /* force XMALLOC */
|
||||
#else
|
||||
EncryptedInfo info[1];
|
||||
byte staticBuffer[FILE_BUFFER_SIZE];
|
||||
#endif
|
||||
byte* fileBuf = staticBuffer;
|
||||
int dynamic = 0;
|
||||
int ret = 0;
|
||||
int ecc = 0;
|
||||
long sz = 0;
|
||||
XFILE file = XFOPEN(fileName, "rb");
|
||||
DerBuffer* converted = NULL;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_PemCertToDer");
|
||||
|
||||
if (file == XBADFILE) {
|
||||
ret = BUFFER_E;
|
||||
}
|
||||
else {
|
||||
XFSEEK(file, 0, XSEEK_END);
|
||||
sz = XFTELL(file);
|
||||
XREWIND(file);
|
||||
|
||||
if (sz <= 0) {
|
||||
ret = BUFFER_E;
|
||||
}
|
||||
else if (sz > (long)sizeof(staticBuffer)) {
|
||||
#ifdef WOLFSSL_STATIC_MEMORY
|
||||
WOLFSSL_MSG("File was larger then static buffer");
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
fileBuf = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_FILE);
|
||||
if (fileBuf == NULL)
|
||||
ret = MEMORY_E;
|
||||
else
|
||||
dynamic = 1;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
if ( (ret = (int)XFREAD(fileBuf, 1, sz, file)) != sz) {
|
||||
ret = BUFFER_E;
|
||||
}
|
||||
else {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
|
||||
DYNAMIC_TYPE_ENCRYPTEDINFO);
|
||||
if (info == NULL)
|
||||
ret = MEMORY_E;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ret = PemToDer(fileBuf, sz, CA_TYPE, &converted,
|
||||
0, info, &ecc);
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
if (converted->length < (word32)derSz) {
|
||||
XMEMCPY(derBuf, converted->buffer, converted->length);
|
||||
ret = converted->length;
|
||||
}
|
||||
else
|
||||
ret = BUFFER_E;
|
||||
}
|
||||
|
||||
FreeDer(&converted);
|
||||
}
|
||||
|
||||
XFCLOSE(file);
|
||||
if (dynamic)
|
||||
XFREE(fileBuf, 0, DYNAMIC_TYPE_FILE);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_CERT_GEN */
|
||||
|
||||
#if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)
|
||||
/* load pem public key from file into der buffer, return der size or error */
|
||||
int wolfSSL_PemPubKeyToDer(const char* fileName,
|
||||
unsigned char* derBuf, int derSz)
|
||||
{
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
byte staticBuffer[1]; /* force XMALLOC */
|
||||
#else
|
||||
byte staticBuffer[FILE_BUFFER_SIZE];
|
||||
#endif
|
||||
byte* fileBuf = staticBuffer;
|
||||
int dynamic = 0;
|
||||
int ret = 0;
|
||||
long sz = 0;
|
||||
XFILE file = XFOPEN(fileName, "rb");
|
||||
DerBuffer* converted = NULL;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_PemPubKeyToDer");
|
||||
|
||||
if (file == XBADFILE) {
|
||||
ret = BUFFER_E;
|
||||
}
|
||||
else {
|
||||
XFSEEK(file, 0, XSEEK_END);
|
||||
sz = XFTELL(file);
|
||||
XREWIND(file);
|
||||
|
||||
if (sz <= 0) {
|
||||
ret = BUFFER_E;
|
||||
}
|
||||
else if (sz > (long)sizeof(staticBuffer)) {
|
||||
#ifdef WOLFSSL_STATIC_MEMORY
|
||||
WOLFSSL_MSG("File was larger then static buffer");
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
fileBuf = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_FILE);
|
||||
if (fileBuf == NULL)
|
||||
ret = MEMORY_E;
|
||||
else
|
||||
dynamic = 1;
|
||||
}
|
||||
if (ret == 0) {
|
||||
if ( (ret = (int)XFREAD(fileBuf, 1, sz, file)) != sz)
|
||||
ret = BUFFER_E;
|
||||
else
|
||||
ret = PemToDer(fileBuf, sz, PUBLICKEY_TYPE, &converted,
|
||||
0, NULL, NULL);
|
||||
|
||||
if (ret == 0) {
|
||||
if (converted->length < (word32)derSz) {
|
||||
XMEMCPY(derBuf, converted->buffer, converted->length);
|
||||
ret = converted->length;
|
||||
}
|
||||
else
|
||||
ret = BUFFER_E;
|
||||
}
|
||||
|
||||
FreeDer(&converted);
|
||||
}
|
||||
|
||||
XFCLOSE(file);
|
||||
if (dynamic)
|
||||
XFREE(fileBuf, 0, DYNAMIC_TYPE_FILE);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */
|
||||
#endif /* !NO_FILESYSTEM */
|
||||
|
||||
|
||||
#if !defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) || \
|
||||
(defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA)))
|
||||
/* USER RSA ifdef portions used instead of refactor in consideration for
|
||||
|
|
|
@ -263,6 +263,9 @@ const char* wc_GetErrorString(int error)
|
|||
case ASN_OCSP_CONFIRM_E :
|
||||
return "ASN OCSP sig error, confirm failure";
|
||||
|
||||
case ASN_NO_PEM_HEADER:
|
||||
return "ASN no PEM Header Error";
|
||||
|
||||
case BAD_STATE_E:
|
||||
return "Bad state operation";
|
||||
|
||||
|
|
|
@ -1090,7 +1090,7 @@ int error_test(void)
|
|||
int j = 0;
|
||||
/* Values that are not or no longer error codes. */
|
||||
int missing[] = { -122, -123, -124, -127, -128, -129,
|
||||
-162, -163, -164, -165, -166, -167, -168, -169,
|
||||
-163, -164, -165, -166, -167, -168, -169,
|
||||
-179, -233,
|
||||
0 };
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ enum wolfSSL_ErrorCodes {
|
|||
COOKIE_ERROR = -369, /* dtls cookie error */
|
||||
SEQUENCE_ERROR = -370, /* dtls sequence error */
|
||||
SUITES_ERROR = -371, /* suites pointer error */
|
||||
SSL_NO_PEM_HEADER = -372, /* no PEM header found */
|
||||
|
||||
OUT_OF_ORDER_E = -373, /* out of order message */
|
||||
BAD_KEA_TYPE_E = -374, /* bad KEA type found */
|
||||
SANITY_CIPHER_E = -375, /* sanity check on cipher error */
|
||||
|
|
|
@ -1521,17 +1521,6 @@ WOLFSSL_LOCAL int DoTls13ServerHello(WOLFSSL* ssl, const byte* input,
|
|||
word32* inOutIdx, word32 helloSz);
|
||||
#endif
|
||||
|
||||
#ifndef NO_CERTS
|
||||
/* wolfSSL DER buffer */
|
||||
typedef struct DerBuffer {
|
||||
byte* buffer;
|
||||
void* heap;
|
||||
word32 length;
|
||||
int type; /* enum CertType */
|
||||
int dynType; /* DYNAMIC_TYPE_* */
|
||||
} DerBuffer;
|
||||
#endif /* !NO_CERTS */
|
||||
|
||||
|
||||
enum {
|
||||
FORCED_FREE = 1,
|
||||
|
@ -3665,31 +3654,9 @@ void FreeSSL(WOLFSSL*, void* heap);
|
|||
WOLFSSL_API void SSL_ResourceFree(WOLFSSL*); /* Micrium uses */
|
||||
|
||||
|
||||
enum {
|
||||
IV_SZ = 32, /* max iv sz */
|
||||
NAME_SZ = 80 /* max one line */
|
||||
};
|
||||
|
||||
|
||||
typedef struct EncryptedInfo {
|
||||
char name[NAME_SZ]; /* encryption name */
|
||||
byte iv[IV_SZ]; /* encrypted IV */
|
||||
word32 ivSz; /* encrypted IV size */
|
||||
long consumed; /* tracks PEM bytes consumed */
|
||||
byte set; /* if encryption set */
|
||||
WOLFSSL_CTX* ctx; /* CTX owner */
|
||||
} EncryptedInfo;
|
||||
|
||||
|
||||
#ifndef NO_CERTS
|
||||
|
||||
WOLFSSL_LOCAL int AllocDer(DerBuffer** der, word32 length, int type, void* heap);
|
||||
WOLFSSL_LOCAL void FreeDer(DerBuffer** der);
|
||||
|
||||
WOLFSSL_LOCAL int PemToDer(const unsigned char* buff, long sz, int type,
|
||||
DerBuffer** pDer, void* heap, EncryptedInfo* info,
|
||||
int* eccKey);
|
||||
|
||||
WOLFSSL_LOCAL int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||
long sz, int format, int type, WOLFSSL* ssl,
|
||||
long* used, int userChain);
|
||||
|
|
|
@ -514,11 +514,6 @@ WOLFSSL_API int wolfSSL_use_RSAPrivateKey_file(WOLFSSL*, const char*, int);
|
|||
/* load NTRU private key blob */
|
||||
#endif
|
||||
|
||||
#ifndef WOLFSSL_PEMCERT_TODER_DEFINED
|
||||
WOLFSSL_API int wolfSSL_PemCertToDer(const char*, unsigned char*, int);
|
||||
#define WOLFSSL_PEMCERT_TODER_DEFINED
|
||||
#endif
|
||||
|
||||
#endif /* !NO_FILESYSTEM && !NO_CERTS */
|
||||
|
||||
WOLFSSL_API WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD*);
|
||||
|
@ -1710,17 +1705,6 @@ WOLFSSL_API int wolfSSL_KeyPemToDer(const unsigned char*, int,
|
|||
unsigned char*, int, const char*);
|
||||
WOLFSSL_API int wolfSSL_CertPemToDer(const unsigned char*, int,
|
||||
unsigned char*, int, int);
|
||||
#if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)
|
||||
#ifndef WOLFSSL_PEMPUBKEY_TODER_DEFINED
|
||||
#ifndef NO_FILESYSTEM
|
||||
WOLFSSL_API int wolfSSL_PemPubKeyToDer(const char* fileName,
|
||||
unsigned char* derBuf, int derSz);
|
||||
#endif
|
||||
WOLFSSL_API int wolfSSL_PubKeyPemToDer(const unsigned char*, int,
|
||||
unsigned char*, int);
|
||||
#define WOLFSSL_PEMPUBKEY_TODER_DEFINED
|
||||
#endif /* WOLFSSL_PEMPUBKEY_TODER_DEFINED */
|
||||
#endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER*/
|
||||
|
||||
typedef void (*CallbackCACache)(unsigned char* der, int sz, int type);
|
||||
typedef void (*CbMissingCRL)(const char* url);
|
||||
|
|
|
@ -914,6 +914,15 @@ WOLFSSL_LOCAL int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der);
|
|||
WOLFSSL_LOCAL void InitSignatureCtx(SignatureCtx* sigCtx, void* heap, int devId);
|
||||
WOLFSSL_LOCAL void FreeSignatureCtx(SignatureCtx* sigCtx);
|
||||
|
||||
#ifndef NO_CERTS
|
||||
|
||||
WOLFSSL_LOCAL int PemToDer(const unsigned char* buff, long sz, int type,
|
||||
DerBuffer** pDer, void* heap, EncryptedInfo* info,
|
||||
int* eccKey);
|
||||
WOLFSSL_LOCAL int AllocDer(DerBuffer** der, word32 length, int type, void* heap);
|
||||
WOLFSSL_LOCAL void FreeDer(DerBuffer** der);
|
||||
|
||||
#endif /* !NO_CERTS */
|
||||
|
||||
#ifdef WOLFSSL_CERT_GEN
|
||||
|
||||
|
@ -928,15 +937,6 @@ enum cert_enums {
|
|||
ED25519_KEY = 13
|
||||
};
|
||||
|
||||
#ifndef WOLFSSL_PEMCERT_TODER_DEFINED
|
||||
#ifndef NO_FILESYSTEM
|
||||
/* forward from wolfSSL */
|
||||
WOLFSSL_API
|
||||
int wolfSSL_PemCertToDer(const char* fileName,unsigned char* derBuf,int derSz);
|
||||
#define WOLFSSL_PEMCERT_TODER_DEFINED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* WOLFSSL_CERT_GEN */
|
||||
|
||||
|
||||
|
|
|
@ -50,6 +50,9 @@
|
|||
#define WC_RNG_TYPE_DEFINED
|
||||
#endif
|
||||
|
||||
struct WOLFSSL_CTX;
|
||||
|
||||
|
||||
/* Certificate file Type */
|
||||
enum CertType {
|
||||
CERT_TYPE = 0,
|
||||
|
@ -112,6 +115,29 @@ enum Ctc_Misc {
|
|||
#endif /* WOLFSSL_CERT_EXT */
|
||||
};
|
||||
|
||||
/* DER buffer */
|
||||
typedef struct DerBuffer {
|
||||
byte* buffer;
|
||||
void* heap;
|
||||
word32 length;
|
||||
int type; /* enum CertType */
|
||||
int dynType; /* DYNAMIC_TYPE_* */
|
||||
} DerBuffer;
|
||||
|
||||
enum {
|
||||
IV_SZ = 32, /* max iv sz */
|
||||
NAME_SZ = 80 /* max one line */
|
||||
};
|
||||
|
||||
typedef struct EncryptedInfo {
|
||||
char name[NAME_SZ]; /* encryption name */
|
||||
byte iv[IV_SZ]; /* encrypted IV */
|
||||
word32 ivSz; /* encrypted IV size */
|
||||
long consumed; /* tracks PEM bytes consumed */
|
||||
byte set; /* if encryption set */
|
||||
struct WOLFSSL_CTX* ctx; /* CTX owner */
|
||||
} EncryptedInfo;
|
||||
|
||||
|
||||
#ifdef WOLFSSL_CERT_GEN
|
||||
|
||||
|
@ -209,6 +235,7 @@ typedef struct Cert {
|
|||
} Cert;
|
||||
|
||||
|
||||
|
||||
/* Initialize and Set Certificate defaults:
|
||||
version = 3 (0x2)
|
||||
serial = 0 (Will be randomly generated)
|
||||
|
@ -299,6 +326,7 @@ WOLFSSL_API int wc_SetExtKeyUsageOID(Cert *cert, const char *oid, word32 sz,
|
|||
|
||||
#endif /* WOLFSSL_CERT_GEN */
|
||||
|
||||
|
||||
#if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)
|
||||
#ifndef WOLFSSL_PEMPUBKEY_TODER_DEFINED
|
||||
#ifndef NO_FILESYSTEM
|
||||
|
@ -322,6 +350,25 @@ WOLFSSL_API int wc_SetExtKeyUsageOID(Cert *cert, const char *oid, word32 sz,
|
|||
word32 outputSz, byte *cipherIno, int type);
|
||||
#endif
|
||||
|
||||
WOLFSSL_API int wc_PemToDer(const unsigned char* buff, long longSz, int type,
|
||||
DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey);
|
||||
|
||||
#ifdef WOLFSSL_CERT_GEN
|
||||
#ifndef NO_FILESYSTEM
|
||||
WOLFSSL_API int wolfSSL_PemCertToDer(const char* fileName,
|
||||
unsigned char* derBuf, int derSz);
|
||||
#endif
|
||||
#endif /* WOLFSSL_CERT_GEN */
|
||||
|
||||
#if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)
|
||||
#ifndef NO_FILESYSTEM
|
||||
WOLFSSL_API int wolfSSL_PemPubKeyToDer(const char* fileName,
|
||||
unsigned char* derBuf, int derSz);
|
||||
#endif
|
||||
WOLFSSL_API int wolfSSL_PubKeyPemToDer(const unsigned char*, int,
|
||||
unsigned char*, int);
|
||||
#endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
/* private key helpers */
|
||||
WOLFSSL_API int wc_EccPrivateKeyDecode(const byte*, word32*,
|
||||
|
|
|
@ -100,6 +100,7 @@ enum {
|
|||
ASN_NTRU_KEY_E = -159, /* ASN ntru key decode error, invalid input */
|
||||
ASN_CRIT_EXT_E = -160, /* ASN unsupported critical extension */
|
||||
ASN_ALT_NAME_E = -161, /* ASN alternate name error */
|
||||
ASN_NO_PEM_HEADER = -162, /* ASN no PEM header found */
|
||||
|
||||
ECC_BAD_ARG_E = -170, /* ECC input argument of wrong type */
|
||||
ASN_ECC_KEY_E = -171, /* ASN ECC bad input */
|
||||
|
|
Loading…
Reference in New Issue