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 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, const unsigned char *sig,
unsigned long sig_len, unsigned long sig_len,
const unsigned char *m, const unsigned char *m,
@@ -604,30 +605,48 @@ _libssh2_wincng_key_sha1_verify(_libssh2_wincng_key_ctx *ctx,
unsigned long flags) unsigned long flags)
{ {
BCRYPT_PKCS1_PADDING_INFO paddingInfoPKCS1; BCRYPT_PKCS1_PADDING_INFO paddingInfoPKCS1;
BCRYPT_ALG_HANDLE hAlgHash;
void *pPaddingInfo; void *pPaddingInfo;
unsigned char *data, *hash; unsigned char *data, *hash;
unsigned long datalen, hashlen; unsigned long datalen;
int ret; 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; datalen = m_len;
data = malloc(datalen); data = malloc(datalen);
if(!data) { if(!data) {
return -1; return -1;
} }
hashlen = SHA_DIGEST_LENGTH;
hash = malloc(hashlen); hash = malloc(hashlen);
if(!hash) { if(!hash) {
free(data); free(data);
return -1; return -1;
} }
memcpy(data, m, datalen); memcpy(data, m, datalen);
ret = _libssh2_wincng_hash(data, datalen, ret = _libssh2_wincng_hash(data, datalen,
_libssh2_wincng.hAlgHashSHA1, hAlgHash,
hash, hashlen); hash, hashlen);
_libssh2_wincng_safe_free(data, datalen); _libssh2_wincng_safe_free(data, datalen);
if(ret) { if(ret) {
@@ -643,7 +662,6 @@ _libssh2_wincng_key_sha1_verify(_libssh2_wincng_key_ctx *ctx,
} }
if(flags & BCRYPT_PAD_PKCS1) { if(flags & BCRYPT_PAD_PKCS1) {
paddingInfoPKCS1.pszAlgId = BCRYPT_SHA1_ALGORITHM;
pPaddingInfo = &paddingInfoPKCS1; pPaddingInfo = &paddingInfoPKCS1;
} }
else else
@@ -1209,12 +1227,24 @@ _libssh2_wincng_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
const unsigned char *m, const unsigned char *m,
unsigned long m_len) unsigned long m_len)
{ {
return _libssh2_wincng_key_sha1_verify(rsa, sig, sig_len, m, m_len, return _libssh2_wincng_key_sha_verify(rsa, SHA_DIGEST_LENGTH, sig, sig_len,
BCRYPT_PAD_PKCS1); m, m_len, BCRYPT_PAD_PKCS1);
} }
int 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, libssh2_rsa_ctx *rsa,
const unsigned char *hash, const unsigned char *hash,
size_t hash_len, size_t hash_len,
@@ -1226,14 +1256,25 @@ _libssh2_wincng_rsa_sha1_sign(LIBSSH2_SESSION *session,
unsigned long cbData, datalen, siglen; unsigned long cbData, datalen, siglen;
int ret; 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; datalen = (unsigned long)hash_len;
data = malloc(datalen); data = malloc(datalen);
if(!data) { if(!data) {
return -1; return -1;
} }
paddingInfo.pszAlgId = BCRYPT_SHA1_ALGORITHM;
memcpy(data, hash, datalen); memcpy(data, hash, datalen);
ret = BCryptSignHash(rsa->hKey, &paddingInfo, ret = BCryptSignHash(rsa->hKey, &paddingInfo,
@@ -1504,7 +1545,8 @@ _libssh2_wincng_dsa_sha1_verify(libssh2_dsa_ctx *dsa,
const unsigned char *m, const unsigned char *m,
unsigned long m_len) 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 int
@@ -2604,8 +2646,13 @@ _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
size_t key_method_len) size_t key_method_len)
{ {
(void)session; (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; return NULL;
} }

View File

@@ -63,7 +63,7 @@
#define LIBSSH2_3DES 1 #define LIBSSH2_3DES 1
#define LIBSSH2_RSA 1 #define LIBSSH2_RSA 1
#define LIBSSH2_RSA_SHA2 0 #define LIBSSH2_RSA_SHA2 1
#define LIBSSH2_DSA 1 #define LIBSSH2_DSA 1
#define LIBSSH2_ECDSA 0 #define LIBSSH2_ECDSA 0
#define LIBSSH2_ED25519 0 #define LIBSSH2_ED25519 0
@@ -262,9 +262,13 @@ typedef struct __libssh2_wincng_key_ctx {
_libssh2_wincng_rsa_new_private_frommemory(rsactx, s, filedata, \ _libssh2_wincng_rsa_new_private_frommemory(rsactx, s, filedata, \
filedata_len, passphrase) filedata_len, passphrase)
#define _libssh2_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) \ #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) \ #define _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) \
_libssh2_wincng_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) \ #define _libssh2_rsa_free(rsactx) \
_libssh2_wincng_rsa_free(rsactx) _libssh2_wincng_rsa_free(rsactx)
@@ -450,7 +454,8 @@ void
_libssh2_wincng_hmac_cleanup(_libssh2_wincng_hash_ctx *ctx); _libssh2_wincng_hmac_cleanup(_libssh2_wincng_hash_ctx *ctx);
int 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, const unsigned char *sig,
unsigned long sig_len, unsigned long sig_len,
const unsigned char *m, const unsigned char *m,
@@ -493,7 +498,7 @@ _libssh2_wincng_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
const unsigned char *m, const unsigned char *m,
unsigned long m_len); unsigned long m_len);
int int
_libssh2_wincng_rsa_sha1_sign(LIBSSH2_SESSION *session, _libssh2_wincng_rsa_sha_sign(LIBSSH2_SESSION *session,
libssh2_rsa_ctx *rsa, libssh2_rsa_ctx *rsa,
const unsigned char *hash, const unsigned char *hash,
size_t hash_len, size_t hash_len,