Skip to content

Commit

Permalink
Add RSA-SHA2 support for the WinCNG backend (libssh2#736)
Browse files Browse the repository at this point in the history
Notes:
Added code to support RSA-SHA2 for WinCNG backend.

Credit:
skundu07
  • Loading branch information
skundu07 authored Sep 23, 2022
1 parent bd9c65d commit 8b3a864
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 20 deletions.
79 changes: 63 additions & 16 deletions src/wincng.c
Original file line number Diff line number Diff line change
Expand Up @@ -596,38 +596,57 @@ _libssh2_wincng_hmac_cleanup(_libssh2_wincng_hash_ctx *ctx)
*/

int
_libssh2_wincng_key_sha1_verify(_libssh2_wincng_key_ctx *ctx,
_libssh2_wincng_key_sha_verify(_libssh2_wincng_key_ctx *ctx,
size_t hashlen,
const unsigned char *sig,
unsigned long sig_len,
const unsigned char *m,
unsigned long m_len,
unsigned long flags)
{
BCRYPT_PKCS1_PADDING_INFO paddingInfoPKCS1;
BCRYPT_ALG_HANDLE hAlgHash;
void *pPaddingInfo;
unsigned char *data, *hash;
unsigned long datalen, hashlen;
unsigned long datalen;
int ret;

if(hashlen == SHA_DIGEST_LENGTH) {
hAlgHash = _libssh2_wincng.hAlgHashSHA1;
paddingInfoPKCS1.pszAlgId = BCRYPT_SHA1_ALGORITHM;
}
else if(hashlen == SHA256_DIGEST_LENGTH) {
hAlgHash = _libssh2_wincng.hAlgHashSHA256;
paddingInfoPKCS1.pszAlgId = BCRYPT_SHA256_ALGORITHM;
}
else if(hashlen == SHA384_DIGEST_LENGTH) {
hAlgHash = _libssh2_wincng.hAlgHashSHA384;
paddingInfoPKCS1.pszAlgId = BCRYPT_SHA384_ALGORITHM;
}
else if(hashlen == SHA512_DIGEST_LENGTH) {
hAlgHash = _libssh2_wincng.hAlgHashSHA512;
paddingInfoPKCS1.pszAlgId = BCRYPT_SHA512_ALGORITHM;
}
else {
return -1;
}

datalen = m_len;
data = malloc(datalen);
if(!data) {
return -1;
}

hashlen = SHA_DIGEST_LENGTH;
hash = malloc(hashlen);
if(!hash) {
free(data);
return -1;
}

memcpy(data, m, datalen);

ret = _libssh2_wincng_hash(data, datalen,
_libssh2_wincng.hAlgHashSHA1,
hAlgHash,
hash, hashlen);

_libssh2_wincng_safe_free(data, datalen);

if(ret) {
Expand All @@ -643,7 +662,6 @@ _libssh2_wincng_key_sha1_verify(_libssh2_wincng_key_ctx *ctx,
}

if(flags & BCRYPT_PAD_PKCS1) {
paddingInfoPKCS1.pszAlgId = BCRYPT_SHA1_ALGORITHM;
pPaddingInfo = &paddingInfoPKCS1;
}
else
Expand Down Expand Up @@ -1209,12 +1227,24 @@ _libssh2_wincng_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
const unsigned char *m,
unsigned long m_len)
{
return _libssh2_wincng_key_sha1_verify(rsa, sig, sig_len, m, m_len,
BCRYPT_PAD_PKCS1);
return _libssh2_wincng_key_sha_verify(rsa, SHA_DIGEST_LENGTH, sig, sig_len,
m, m_len, BCRYPT_PAD_PKCS1);
}

int
_libssh2_wincng_rsa_sha1_sign(LIBSSH2_SESSION *session,
_libssh2_wincng_rsa_sha2_verify(libssh2_rsa_ctx* rsa,
size_t hash_len,
const unsigned char *sig,
unsigned long sig_len,
const unsigned char *m,
unsigned long m_len)
{
return _libssh2_wincng_key_sha_verify(rsa, hash_len, sig, sig_len, m,
m_len, BCRYPT_PAD_PKCS1);
}

int
_libssh2_wincng_rsa_sha_sign(LIBSSH2_SESSION *session,
libssh2_rsa_ctx *rsa,
const unsigned char *hash,
size_t hash_len,
Expand All @@ -1226,14 +1256,25 @@ _libssh2_wincng_rsa_sha1_sign(LIBSSH2_SESSION *session,
unsigned long cbData, datalen, siglen;
int ret;

if(hash_len == SHA_DIGEST_LENGTH)
paddingInfo.pszAlgId = BCRYPT_SHA1_ALGORITHM;
else if(hash_len == SHA256_DIGEST_LENGTH)
paddingInfo.pszAlgId = BCRYPT_SHA256_ALGORITHM;
else if(hash_len == SHA384_DIGEST_LENGTH)
paddingInfo.pszAlgId = BCRYPT_SHA384_ALGORITHM;
else if(hash_len == SHA512_DIGEST_LENGTH)
paddingInfo.pszAlgId = BCRYPT_SHA512_ALGORITHM;
else {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Unsupported hash digest length");
return -1;
}

datalen = (unsigned long)hash_len;
data = malloc(datalen);
if(!data) {
return -1;
}

paddingInfo.pszAlgId = BCRYPT_SHA1_ALGORITHM;

memcpy(data, hash, datalen);

ret = BCryptSignHash(rsa->hKey, &paddingInfo,
Expand Down Expand Up @@ -1504,7 +1545,8 @@ _libssh2_wincng_dsa_sha1_verify(libssh2_dsa_ctx *dsa,
const unsigned char *m,
unsigned long m_len)
{
return _libssh2_wincng_key_sha1_verify(dsa, sig_fixed, 40, m, m_len, 0);
return _libssh2_wincng_key_sha_verify(dsa, SHA_DIGEST_LENGTH, sig_fixed,
40, m, m_len, 0);
}

int
Expand Down Expand Up @@ -2604,8 +2646,13 @@ _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
size_t key_method_len)
{
(void)session;
(void)key_method;
(void)key_method_len;

#if LIBSSH2_RSA_SHA2
if(key_method_len == 7 &&
memcmp(key_method, "ssh-rsa", key_method_len) == 0) {
return "rsa-sha2-512,rsa-sha2-256,ssh-rsa";
}
#endif

return NULL;
}
Expand Down
13 changes: 9 additions & 4 deletions src/wincng.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
#define LIBSSH2_3DES 1

#define LIBSSH2_RSA 1
#define LIBSSH2_RSA_SHA2 0
#define LIBSSH2_RSA_SHA2 1
#define LIBSSH2_DSA 1
#define LIBSSH2_ECDSA 0
#define LIBSSH2_ED25519 0
Expand Down Expand Up @@ -262,9 +262,13 @@ typedef struct __libssh2_wincng_key_ctx {
_libssh2_wincng_rsa_new_private_frommemory(rsactx, s, filedata, \
filedata_len, passphrase)
#define _libssh2_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) \
_libssh2_wincng_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len)
_libssh2_wincng_rsa_sha_sign(s, rsactx, hash, hash_len, sig, sig_len)
#define _libssh2_rsa_sha2_sign(s, rsactx, hash, hash_len, sig, sig_len) \
_libssh2_wincng_rsa_sha_sign(s, rsactx, hash, hash_len, sig, sig_len)
#define _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) \
_libssh2_wincng_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len)
#define _libssh2_rsa_sha2_verify(rsactx, hash_len, sig, sig_len, m, m_len) \
_libssh2_wincng_rsa_sha2_verify(rsactx, hash_len, sig, sig_len, m, m_len)
#define _libssh2_rsa_free(rsactx) \
_libssh2_wincng_rsa_free(rsactx)

Expand Down Expand Up @@ -450,7 +454,8 @@ void
_libssh2_wincng_hmac_cleanup(_libssh2_wincng_hash_ctx *ctx);

int
_libssh2_wincng_key_sha1_verify(_libssh2_wincng_key_ctx *ctx,
_libssh2_wincng_key_sha_verify(_libssh2_wincng_key_ctx *ctx,
size_t hashlen,
const unsigned char *sig,
unsigned long sig_len,
const unsigned char *m,
Expand Down Expand Up @@ -493,7 +498,7 @@ _libssh2_wincng_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
const unsigned char *m,
unsigned long m_len);
int
_libssh2_wincng_rsa_sha1_sign(LIBSSH2_SESSION *session,
_libssh2_wincng_rsa_sha_sign(LIBSSH2_SESSION *session,
libssh2_rsa_ctx *rsa,
const unsigned char *hash,
size_t hash_len,
Expand Down

0 comments on commit 8b3a864

Please sign in to comment.