aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libssh/pki.h2
-rw-r--r--include/libssh/pki_priv.h2
-rw-r--r--src/pki.c43
-rw-r--r--src/pki_crypto.c37
-rw-r--r--src/pki_gcrypt.c58
5 files changed, 142 insertions, 0 deletions
diff --git a/include/libssh/pki.h b/include/libssh/pki.h
index ce7d5007..29041920 100644
--- a/include/libssh/pki.h
+++ b/include/libssh/pki.h
@@ -83,6 +83,8 @@ ssh_string ssh_pki_do_sign(ssh_session session, ssh_buffer sigbuf,
ssh_string ssh_pki_do_sign_agent(ssh_session session,
struct ssh_buffer_struct *buf,
const ssh_key pubkey);
+ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session,
+ const ssh_key privkey);
/* Temporary functions, to be removed after migration to ssh_key */
ssh_public_key ssh_pki_convert_key_to_publickey(ssh_key key);
diff --git a/include/libssh/pki_priv.h b/include/libssh/pki_priv.h
index f89bfdf4..e86a96c4 100644
--- a/include/libssh/pki_priv.h
+++ b/include/libssh/pki_priv.h
@@ -59,4 +59,6 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
/* SSH Signing Functions */
struct signature_struct *pki_do_sign(const ssh_key privatekey,
const unsigned char *hash);
+ssh_signature pki_do_sign_sessionid(const ssh_key key,
+ const unsigned char *hash);
#endif /* PKI_PRIV_H_ */
diff --git a/src/pki.c b/src/pki.c
index 675d221f..f209fe47 100644
--- a/src/pki.c
+++ b/src/pki.c
@@ -1081,6 +1081,49 @@ ssh_string ssh_pki_do_sign_agent(ssh_session session,
}
#endif /* _WIN32 */
+#ifdef WITH_SERVER
+ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session,
+ const ssh_key privkey)
+{
+ struct ssh_crypto_struct *crypto =
+ session->current_crypto ? session->current_crypto :
+ session->next_crypto;
+ unsigned char hash[SHA_DIGEST_LEN + 1] = {0};
+ ssh_signature sig;
+ ssh_string sig_blob;
+ SHACTX ctx;
+ int rc;
+
+ if (session == NULL || privkey == NULL || !ssh_key_is_private(privkey)) {
+ return NULL;
+ }
+
+ ctx = sha1_init();
+ if (ctx == NULL) {
+ return NULL;
+ }
+ sha1_update(ctx, crypto->session_id, SHA_DIGEST_LEN);
+ sha1_final(hash + 1, ctx);
+ hash[0] = 0;
+
+#ifdef DEBUG_CRYPTO
+ ssh_print_hexa("Hash being signed", hash + 1, SHA_DIGEST_LEN);
+#endif
+
+ sig = pki_do_sign_sessionid(privkey, hash);
+ if (sig == NULL) {
+ return NULL;
+ }
+
+ rc = ssh_pki_export_signature_blob(sig, &sig_blob);
+ ssh_signature_free(sig);
+ if (rc < 0) {
+ return NULL;
+ }
+
+ return sig_blob;
+}
+#endif /* WITH_SERVER */
/**
* @}
diff --git a/src/pki_crypto.c b/src/pki_crypto.c
index 3e53a3cc..18ac876b 100644
--- a/src/pki_crypto.c
+++ b/src/pki_crypto.c
@@ -716,4 +716,41 @@ struct signature_struct *pki_do_sign(ssh_key privatekey,
return sign;
}
+#ifdef WITH_SERVER
+ssh_signature pki_do_sign_sessionid(const ssh_key key,
+ const unsigned char *hash)
+{
+ ssh_signature sig;
+
+ sig = ssh_signature_new();
+ if (sig == NULL) {
+ return NULL;
+ }
+ sig->type = key->type;
+
+ switch(key->type) {
+ case SSH_KEYTYPE_DSS:
+ sig->dsa_sig = DSA_do_sign(hash + 1, SHA_DIGEST_LEN, key->dsa);
+ if (sig->dsa_sig == NULL) {
+ ssh_signature_free(sig);
+ return NULL;
+ }
+ break;
+ case SSH_KEYTYPE_RSA:
+ case SSH_KEYTYPE_RSA1:
+ sig->rsa_sig = _RSA_do_sign(hash + 1, SHA_DIGEST_LEN, key->rsa);
+ if (sig->rsa_sig == NULL) {
+ ssh_signature_free(sig);
+ return NULL;
+ }
+ break;
+ case SSH_KEYTYPE_ECDSA:
+ case SSH_KEYTYPE_UNKNOWN:
+ return NULL;
+ }
+
+ return sig;
+}
+#endif /* WITH_SERVER */
+
#endif /* _PKI_CRYPTO_H */
diff --git a/src/pki_gcrypt.c b/src/pki_gcrypt.c
index 1bcfae2c..9e554677 100644
--- a/src/pki_gcrypt.c
+++ b/src/pki_gcrypt.c
@@ -1355,6 +1355,64 @@ struct signature_struct *pki_do_sign(ssh_key privatekey,
return sign;
}
+#ifdef WITH_SERVER
+ssh_signature pki_do_sign_sessionid(const ssh_key key,
+ const unsigned char *hash)
+{
+ ssh_signature sig;
+ gcry_sexp_t sexp;
+ gcry_error_t err;
+
+ sig = ssh_signature_new();
+ if (sig == NULL) {
+ return NULL;
+ }
+ sig->type = key->type;
+
+ switch(key->type) {
+ case SSH_KEYTYPE_DSS:
+ err = gcry_sexp_build(&sexp,
+ NULL,
+ "%b",
+ SHA_DIGEST_LEN + 1,
+ hash);
+ if (err) {
+ ssh_signature_free(sig);
+ return NULL;
+ }
+ err = gcry_pk_sign(&sig->dsa_sig, sexp, key->dsa);
+ gcry_sexp_release(sexp);
+ if (err) {
+ ssh_signature_free(sig);
+ return NULL;
+ }
+ break;
+ case SSH_KEYTYPE_RSA:
+ case SSH_KEYTYPE_RSA1:
+ err = gcry_sexp_build(&sexp,
+ NULL,
+ "(data(flags pkcs1)(hash sha1 %b))",
+ SHA_DIGEST_LEN,
+ hash + 1);
+ if (err) {
+ ssh_signature_free(sig);
+ return NULL;
+ }
+ err = gcry_pk_sign(&sig->rsa_sig, sexp, key->rsa);
+ gcry_sexp_release(sexp);
+ if (err) {
+ ssh_signature_free(sig);
+ return NULL;
+ }
+ break;
+ case SSH_KEYTYPE_ECDSA:
+ case SSH_KEYTYPE_UNKNOWN:
+ return NULL;
+ }
+
+ return sig;
+}
+#endif /* WITH_SERVER */
#endif /* HAVE_LIBGCRYPT */
/**