1
0
mirror of https://github.com/libssh2/libssh2.git synced 2025-11-21 14:00:51 +03:00

Add RSA-SHA2 support for the WinCNG backend (#736)

Notes:
Added code to support RSA-SHA2 for WinCNG backend.

Credit:
skundu07
This commit is contained in:
skundu07
2022-09-23 22:41:20 +05:30
committed by GitHub
parent bd9c65d68c
commit 8b3a864c5b
2 changed files with 72 additions and 20 deletions

View File

@@ -596,7 +596,8 @@ _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,
@@ -604,30 +605,48 @@ _libssh2_wincng_key_sha1_verify(_libssh2_wincng_key_ctx *ctx,
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) {
@@ -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
@@ -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,
@@ -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,
@@ -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
@@ -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;
}

View File

@@ -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
@@ -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)
@@ -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,
@@ -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,