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