summaryrefslogtreecommitdiff
path: root/ssh-rsa.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2000-11-13 22:57:25 +1100
committerDamien Miller <djm@mindrot.org>2000-11-13 22:57:25 +1100
commit0bc1bd814e3c2b5e92d6f595930051960d17f47f (patch)
tree176c7dc2844ecc2c1de0f72d221449556ffa5209 /ssh-rsa.c
parent559d383037b0872fcde4e6c40188b649c574be74 (diff)
- (djm) Merge OpenBSD changes:
- markus@cvs.openbsd.org 2000/11/06 16:04:56 [channels.c channels.h clientloop.c nchan.c serverloop.c] [session.c ssh.c] agent forwarding and -R for ssh2, based on work from jhuuskon@messi.uku.fi - markus@cvs.openbsd.org 2000/11/06 16:13:27 [ssh.c sshconnect.c sshd.c] do not disabled rhosts(rsa) if server port > 1024; from pekkas@netcore.fi - markus@cvs.openbsd.org 2000/11/06 16:16:35 [sshconnect.c] downgrade client to 1.3 if server is 1.4; help from mdb@juniper.net - markus@cvs.openbsd.org 2000/11/09 18:04:40 [auth1.c] typo; from mouring@pconline.com - markus@cvs.openbsd.org 2000/11/12 12:03:28 [ssh-agent.c] off-by-one when removing a key from the agent - markus@cvs.openbsd.org 2000/11/12 12:50:39 [auth-rh-rsa.c auth2.c authfd.c authfd.h] [authfile.c hostfile.c kex.c kex.h key.c key.h myproposal.h] [readconf.c readconf.h rsa.c rsa.h servconf.c servconf.h ssh-add.c] [ssh-agent.c ssh-keygen.1 ssh-keygen.c ssh.1 ssh.c ssh_config] [sshconnect1.c sshconnect2.c sshd.8 sshd.c sshd_config ssh-dss.c] [ssh-dss.h ssh-rsa.c ssh-rsa.h dsa.c dsa.h] add support for RSA to SSH2. please test. there are now 3 types of keys: RSA1 is used by ssh-1 only, RSA and DSA are used by SSH2. you can use 'ssh-keygen -t rsa -f ssh2_rsa_file' to generate RSA keys for SSH2 and use the RSA keys for hostkeys or for user keys. SSH2 RSA or DSA keys are added to .ssh/authorised_keys2 as before. - (djm) Fix up Makefile and Redhat init script to create RSA host keys - (djm) Change to interim version
Diffstat (limited to 'ssh-rsa.c')
-rw-r--r--ssh-rsa.c163
1 files changed, 163 insertions, 0 deletions
diff --git a/ssh-rsa.c b/ssh-rsa.c
new file mode 100644
index 00000000..cc31154d
--- /dev/null
+++ b/ssh-rsa.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2000 Markus Friedl. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: ssh-rsa.c,v 1.1 2000/11/12 19:50:38 markus Exp $");
+
+#include "ssh.h"
+#include "xmalloc.h"
+#include "buffer.h"
+#include "bufaux.h"
+
+#include <openssl/evp.h>
+#include <openssl/dsa.h>
+#include <openssl/rsa.h>
+#include <openssl/err.h>
+
+#include "key.h"
+
+#define INTBLOB_LEN 20
+#define SIGBLOB_LEN (2*INTBLOB_LEN)
+
+/* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */
+int
+ssh_rsa_sign(
+ Key *key,
+ unsigned char **sigp, int *lenp,
+ unsigned char *data, int datalen)
+{
+ EVP_MD *evp_md = EVP_sha1();
+ EVP_MD_CTX md;
+ unsigned char *digest, *sig, *ret;
+ unsigned int slen, dlen, len;
+ int ok;
+ Buffer b;
+
+ if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) {
+ error("ssh_rsa_sign: no RSA key");
+ return -1;
+ }
+ slen = RSA_size(key->rsa);
+ sig = xmalloc(slen);
+
+ dlen = evp_md->md_size;
+ digest = xmalloc(dlen);
+ EVP_DigestInit(&md, evp_md);
+ EVP_DigestUpdate(&md, data, datalen);
+ EVP_DigestFinal(&md, digest, NULL);
+
+ ok = RSA_sign(NID_sha1, digest, dlen, sig, &len, key->rsa);
+ memset(digest, 'd', dlen);
+ xfree(digest);
+
+ if (ok != 1) {
+ int ecode = ERR_get_error();
+ error("ssh_rsa_sign: RSA_sign failed: %s", ERR_error_string(ecode, NULL));
+ xfree(sig);
+ return -1;
+ }
+ if (len < slen) {
+ int diff = slen - len;
+ debug("slen %d > len %d", slen, len);
+ memmove(sig + diff, sig, len);
+ memset(sig, 0, diff);
+ } else if (len > slen) {
+ error("ssh_rsa_sign: slen %d slen2 %d", slen, len);
+ xfree(sig);
+ return -1;
+ }
+ /* encode signature */
+ buffer_init(&b);
+ buffer_put_cstring(&b, "ssh-rsa");
+ buffer_put_string(&b, sig, slen);
+ len = buffer_len(&b);
+ ret = xmalloc(len);
+ memcpy(ret, buffer_ptr(&b), len);
+ buffer_free(&b);
+ memset(sig, 's', slen);
+ xfree(sig);
+
+ if (lenp != NULL)
+ *lenp = len;
+ if (sigp != NULL)
+ *sigp = ret;
+ debug2("ssh_rsa_sign: done");
+ return 0;
+}
+
+int
+ssh_rsa_verify(
+ Key *key,
+ unsigned char *signature, int signaturelen,
+ unsigned char *data, int datalen)
+{
+ Buffer b;
+ EVP_MD *evp_md = EVP_sha1();
+ EVP_MD_CTX md;
+ char *ktype;
+ unsigned char *sigblob, *digest;
+ unsigned int len, dlen;
+ int rlen;
+ int ret;
+
+ if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) {
+ error("ssh_rsa_verify: no RSA key");
+ return -1;
+ }
+ buffer_init(&b);
+ buffer_append(&b, (char *) signature, signaturelen);
+ ktype = buffer_get_string(&b, NULL);
+ if (strcmp("ssh-rsa", ktype) != 0) {
+ error("ssh_rsa_verify: cannot handle type %s", ktype);
+ buffer_free(&b);
+ xfree(ktype);
+ return -1;
+ }
+ xfree(ktype);
+ sigblob = (unsigned char *)buffer_get_string(&b, &len);
+ rlen = buffer_len(&b);
+ buffer_free(&b);
+ if(rlen != 0) {
+ error("ssh_rsa_verify: remaining bytes in signature %d", rlen);
+ return -1;
+ }
+
+ dlen = evp_md->md_size;
+ digest = xmalloc(dlen);
+ EVP_DigestInit(&md, evp_md);
+ EVP_DigestUpdate(&md, data, datalen);
+ EVP_DigestFinal(&md, digest, NULL);
+
+ ret = RSA_verify(NID_sha1, digest, dlen, sigblob, len, key->rsa);
+ memset(digest, 'd', dlen);
+ xfree(digest);
+ memset(sigblob, 's', len);
+ xfree(sigblob);
+ if (ret == 0) {
+ int ecode = ERR_get_error();
+ error("ssh_rsa_verify: RSA_verify failed: %s", ERR_error_string(ecode, NULL));
+ }
+ debug("ssh_rsa_verify: signature %scorrect", (ret==0) ? "in" : "");
+ return ret;
+}