diff options
Diffstat (limited to 'src/pki_crypto.c')
-rw-r--r-- | src/pki_crypto.c | 66 |
1 files changed, 58 insertions, 8 deletions
diff --git a/src/pki_crypto.c b/src/pki_crypto.c index b41dcb3f..524cc0ff 100644 --- a/src/pki_crypto.c +++ b/src/pki_crypto.c @@ -1181,23 +1181,43 @@ fail: * * @param[in] privkey The private rsa key to use for signing. * + * @param[in] hash_type The hash algorithm to use. + * * @return A newly allocated rsa sig blob or NULL on error. */ -static ssh_string _RSA_do_sign(const unsigned char *digest, - int dlen, - RSA *privkey) +static ssh_string _RSA_do_sign_hash(const unsigned char *digest, + int dlen, + RSA *privkey, + enum ssh_digest_e hash_type) { ssh_string sig_blob; unsigned char *sig; unsigned int slen; int ok; + int nid = 0; + + switch (hash_type) { + case SSH_DIGEST_SHA1: + case SSH_DIGEST_AUTO: + nid = NID_sha1; + break; + case SSH_DIGEST_SHA256: + nid = NID_sha256; + break; + case SSH_DIGEST_SHA512: + nid = NID_sha512; + break; + default: + SSH_LOG(SSH_LOG_WARN, "Incomplatible hash type"); + return NULL; + } sig = malloc(RSA_size(privkey)); if (sig == NULL) { return NULL; } - ok = RSA_sign(NID_sha1, digest, dlen, sig, &slen, privkey); + ok = RSA_sign(nid, digest, dlen, sig, &slen, privkey); if (!ok) { SAFE_FREE(sig); return NULL; @@ -1216,6 +1236,26 @@ static ssh_string _RSA_do_sign(const unsigned char *digest, return sig_blob; } +/** + * @internal + * + * @brief Compute a digital signature. + * + * @param[in] digest The message digest. + * + * @param[in] dlen The length of the digest. + * + * @param[in] privkey The private rsa key to use for signing. + * + * @return A newly allocated rsa sig blob or NULL on error. + */ +static ssh_string _RSA_do_sign(const unsigned char *digest, + int dlen, + RSA *privkey) +{ + return _RSA_do_sign_hash(digest, dlen, privkey, SSH_DIGEST_AUTO); +} + static ssh_string pki_dsa_signature_to_blob(const ssh_signature sig) { char buffer[40] = { 0 }; @@ -1686,18 +1726,27 @@ int pki_signature_verify(ssh_session session, return SSH_OK; } -ssh_signature pki_do_sign(const ssh_key privkey, - const unsigned char *hash, - size_t hlen) { +ssh_signature pki_do_sign_hash(const ssh_key privkey, + const unsigned char *hash, + size_t hlen, + enum ssh_digest_e hash_type) +{ ssh_signature sig; int rc; + /* Only RSA supports different signature algorithm types now */ + if (privkey->type != SSH_KEYTYPE_RSA && hash_type != SSH_DIGEST_AUTO) { + SSH_LOG(SSH_LOG_WARN, "Incompatible signature algorithm passed"); + return NULL; + } + sig = ssh_signature_new(); if (sig == NULL) { return NULL; } sig->type = privkey->type; + sig->hash_type = hash_type; sig->type_c = privkey->type_c; switch(privkey->type) { @@ -1720,7 +1769,8 @@ ssh_signature pki_do_sign(const ssh_key privkey, break; case SSH_KEYTYPE_RSA: case SSH_KEYTYPE_RSA1: - sig->rsa_sig = _RSA_do_sign(hash, hlen, privkey->rsa); + sig->type_c = ssh_key_signature_to_char(privkey->type, hash_type); + sig->rsa_sig = _RSA_do_sign_hash(hash, hlen, privkey->rsa, hash_type); if (sig->rsa_sig == NULL) { ssh_signature_free(sig); return NULL; |