Skip to content

Commit

Permalink
Read PEM Keys
Browse files Browse the repository at this point in the history
1. Update wolfSSH_ReadKey_buffer() to decode PEM keys.
2. Add detection of PEM files to wolfSSH_ReadKey_file().
3. Add parameter labels to the prototypes of the ReadKey functions.
  • Loading branch information
ejohnstown committed Sep 18, 2023
1 parent c8f188e commit 07e7608
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 12 deletions.
72 changes: 64 additions & 8 deletions src/ssh.c
Original file line number Diff line number Diff line change
Expand Up @@ -1479,7 +1479,8 @@ union wolfSSH_key {
/* Reads a key from the buffer in to out. If the out buffer doesn't exist
it is created. The type of key is stored in outType. It'll be a pointer
to a constant string. Format indicates the format of the key, currently
either SSH format (a public key) or ASN.1 in DER format (a private key). */
either SSH format (a public key) or ASN.1 in DER or PEM format (a
private key). */
int wolfSSH_ReadKey_buffer(const byte* in, word32 inSz, int format,
byte** out, word32* outSz, const byte** outType, word32* outTypeSz,
void* heap)
Expand Down Expand Up @@ -1533,8 +1534,10 @@ int wolfSSH_ReadKey_buffer(const byte* in, word32 inSz, int format,
ret = Base64_Decode((byte*)key, (word32)WSTRLEN(key), *out, outSz);
}

if (ret != 0)
ret = WS_ERROR;
if (ret != 0) {
WLOG(WS_LOG_DEBUG, "Base64 decode of public key failed.");
ret = WS_PARSE_E;
}

WFREE(c, heap, DYNTYPE_STRING);
}
Expand All @@ -1548,7 +1551,8 @@ int wolfSSH_ReadKey_buffer(const byte* in, word32 inSz, int format,
}
else {
if (*outSz < inSz) {
return WS_ERROR;
WLOG(WS_LOG_DEBUG, "DER private key output size too small");
return WS_BUFFER_E;
}
newKey = *out;
}
Expand All @@ -1562,8 +1566,52 @@ int wolfSSH_ReadKey_buffer(const byte* in, word32 inSz, int format,
ret = WS_SUCCESS;
}
}
else
ret = WS_ERROR;
else if (format == WOLFSSH_FORMAT_PEM) {
word32 newKeySz = inSz; /* binary will be smaller than PEM */

if (*out == NULL) {
newKey = (byte*)WMALLOC(newKeySz, heap, DYNTYPE_PRIVKEY);
if (newKey == NULL) {
return WS_MEMORY_E;
}
*out = newKey;
}
else {
if (*outSz < inSz) {
WLOG(WS_LOG_DEBUG, "PEM private key output size too small");
return WS_BUFFER_E;
}
newKey = *out;
}

/* If it is PEM, convert to ASN1 then process. */
ret = wc_KeyPemToDer(in, inSz, newKey, newKeySz, NULL);
if (ret > 0) {
newKeySz = (word32)ret;
ret = WS_SUCCESS;
}
else {
WLOG(WS_LOG_DEBUG, "Base64 decode of public key failed.");
ret = WS_PARSE_E;
}

if (ret == WS_SUCCESS) {
ret = IdentifyKey(newKey, newKeySz, 1, heap);
if (ret > 0) {
*outSz = newKeySz;
*outType = (const byte*)IdToName(ret);
*outTypeSz = (word32)WSTRLEN((const char*)*outType);
ret = WS_SUCCESS;
}
else {
WLOG(WS_LOG_DEBUG, "unable to identify key");
}
}
}
else {
WLOG(WS_LOG_DEBUG, "Invalid key format");
ret = WS_BAD_ARGUMENT;
}

return ret;
}
Expand All @@ -1573,8 +1621,9 @@ int wolfSSH_ReadKey_buffer(const byte* in, word32 inSz, int format,

/* Reads a key from the file name into a buffer. If the key starts with the
string "ssh-rsa" or "ecdsa-sha2-nistp256", it is considered an SSH format
public key, otherwise it is considered an ASN.1 private key. The buffer
is passed to wolfSSH_ReadKey_buffer() for processing. */
public key, if it has "----BEGIN" it is considered PEM formatted,
otherwise it is considered an ASN.1 private key. The buffer is passed to
wolfSSH_ReadKey_buffer() for processing. */
int wolfSSH_ReadKey_file(const char* name,
byte** out, word32* outSz, const byte** outType, word32* outTypeSz,
byte* isPrivate, void* heap)
Expand Down Expand Up @@ -1625,6 +1674,13 @@ int wolfSSH_ReadKey_file(const char* name,
format = WOLFSSH_FORMAT_SSH;
in[inSz] = 0;
}
else if ((WSTRNSTR((const char*)in, "-----BEGIN ", inSz)
== (const char*)in)
&& (WSTRNSTR((const char*)in, "PRIVATE KEY-----", inSz)
!= NULL)) {
*isPrivate = 1;
format = WOLFSSH_FORMAT_PEM;
}
else {
*isPrivate = 1;
format = WOLFSSH_FORMAT_ASN1;
Expand Down
10 changes: 6 additions & 4 deletions wolfssh/ssh.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,12 @@ WOLFSSH_API void wolfSSH_SetHighwaterCb(WOLFSSH_CTX*, word32,
WOLFSSH_API void wolfSSH_SetHighwaterCtx(WOLFSSH*, void*);
WOLFSSH_API void* wolfSSH_GetHighwaterCtx(WOLFSSH*);

WOLFSSH_API int wolfSSH_ReadKey_buffer(const byte*, word32, int,
byte**, word32*, const byte**, word32*, void*);
WOLFSSH_API int wolfSSH_ReadKey_file(const char*,
byte**, word32*, const byte**, word32*, byte*, void*);
WOLFSSH_API int wolfSSH_ReadKey_buffer(const byte* in, word32 inSz, int format,
byte** out, word32* outSz, const byte** outType, word32* outTypeSz,
void* heap);
WOLFSSH_API int wolfSSH_ReadKey_file(const char* name,
byte** out, word32* outSz, const byte** outType, word32* outTypeSz,
byte* isPrivate, void* heap);


#define WS_CHANNEL_ID_SELF 0
Expand Down

0 comments on commit 07e7608

Please sign in to comment.