Today, i checked the source code which name ssl.c in deps\wolfssl\src.The function PemtoDer, as flows:
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;
case DH_PARAM_TYPE: header=BEGIN_DH_PARAM; footer=END_DH_PARAM;
break;
case DSA_PARAM_TYPE: header=BEGIN_DSA_PARAM; footer=END_DSA_PARAM;
break;
case CERTREQ_TYPE: header=BEGIN_CERT_REQ; footer=END_CERT_REQ;
break;
case DSA_TYPE: header=BEGIN_DSA_PRIV; footer=END_DSA_PRIV;
break;
case ECC_TYPE: header=BEGIN_EC_PRIV; footer=END_EC_PRIV;
break;
case RSA_TYPE: header=BEGIN_RSA_PRIV; footer=END_RSA_PRIV;
break;
case ED25519_TYPE: header=BEGIN_EDDSA_PRIV; footer=END_EDDSA_PRIV;
break;
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 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 if (header == BEGIN_DSA_PRIV) {
header = BEGIN_EDDSA_PRIV; footer = END_EDDSA_PRIV;
} else
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)
*eccKey = header == BEGIN_EC_PRIV;
}
#if defined(OPENSSL_EXTRA) || 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;
word32 startSz;
char* newline;
if (line >= bufferEnd) {
return WOLFSSL_BAD_FILE;
}
lineSz = (word32)(bufferEnd - line);
start = XSTRNSTR(line, "DES", min(lineSz, PEM_LINE_LEN));
if (start == NULL) {
start = XSTRNSTR(line, "AES", min(lineSz, PEM_LINE_LEN));
}
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 == '\r' || *newline == '\n')
newline++;
headerEnd = newline;
encrypted_key = 1;
}
}
#endif /* OPENSSL_EXTRA || 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(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[80];
#endif
if (!info || !info->ctx || !info->ctx->passwd_cb)
return WOLFSSL_BAD_FILE; /* no callback error */
#ifdef WOLFSSL_SMALL_STACK
password = (char*)XMALLOC(80, heap, DYNAMIC_TYPE_STRING);
if (password == NULL)
return MEMORY_E;
#endif
passwordSz = info->ctx->passwd_cb(password, sizeof(password), 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;
}
when the type is CA_TYPE and TRUSTED_PEER_TYPE, no deal?