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:
79
src/wincng.c
79
src/wincng.c
@@ -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;
|
||||
}
|
||||
|
||||
13
src/wincng.h
13
src/wincng.h
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user