Re: Support for "ssh-rsa-sha256" and "ssh-dss-sha256" ?‏

no_spam_98 at yahoo.com no_spam_98 at yahoo.com
Tue May 28 10:39:38 EST 2013


Done.  Bug 2109.

Thanks.



>________________________________
> From: Damien Miller <djm at mindrot.org>
>To: Jeffrey Hawkins <rtswguru at hotmail.com> 
>Cc: "openssh-unix-dev at mindrot.org" <openssh-unix-dev at mindrot.org> 
>Sent: Friday, May 24, 2013 7:17 AM
>Subject: Re: Support for "ssh-rsa-sha256" and "ssh-dss-sha256" ?‏
> 
>
>On Tue, 14 May 2013, Jeffrey Hawkins wrote:
>
>> Functionality request for supporting Digital Signatures for RSA and DSS
>> Public Key Algorithms in alignment with NIST SP800-131A.
>> 
>> I
>> assume this has been asked before, but I could not find in the
>> archives.   Support of "ssh-rsa-sha256" and "ssh-dss-sha256" public key
>> algorithms for OpenSSH?  I know Suite B Algorithms and x509 SSH
>> Extension Algorithms are supported, but not a path some folks (us) want
>> to take.  Tectia supports similar algorithms  via their own extensions
>> in commercial SSH.
>
>Adding the signature code is easy (see below for a hacky diff - not for
>use), it's going through and duplicating all the ssh-rsa code to support
>ssh-rsa-sha256 and dealing with the corner cases that it tricky. E.g.
>when we find a PEM RSA key on disk, do we load it as a ssh-rsa key, a
>ssh-rsa-sha256 key or both? There are more difficulties to do with
>certificates too when they are signed with RSA keys - should the
>signature be ssh-rsa or ssh-rsa-sha256?
>
>There are probably some other traps that haven't occurred to me yet :(
>
>Please file a bug at https://bugzilla.mindrot.org/ so we can thrash this
>out.
>
>-d
>
>Index: compat.c
>===================================================================
>RCS file: /cvs/src/usr.bin/ssh/compat.c,v
>retrieving revision 1.81
>diff -u -p -r1.81 compat.c
>--- compat.c    17 May 2013 00:13:13 -0000    1.81
>+++ compat.c    24 May 2013 12:01:33 -0000
>@@ -93,6 +93,7 @@ compat_datafellows(const char *version)
>        { "Sun_SSH_1.0*",    SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
>        { "OpenSSH_4*",        0 },
>        { "OpenSSH_5*",        SSH_NEW_OPENSSH|SSH_BUG_DYNAMIC_RPORT},
>+        { "OpenSSH_6.2xxx*",    SSH_NEW_OPENSSH|SSH_NEW_RSA_SHA2},
>        { "OpenSSH*",        SSH_NEW_OPENSSH },
>        { "*MindTerm*",        0 },
>        { "2.1.0*",        SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
>Index: compat.h
>===================================================================
>RCS file: /cvs/src/usr.bin/ssh/compat.h,v
>retrieving revision 1.43
>diff -u -p -r1.43 compat.h
>--- compat.h    23 Sep 2011 07:45:05 -0000    1.43
>+++ compat.h    24 May 2013 12:01:33 -0000
>@@ -59,6 +59,7 @@
>#define SSH_BUG_RFWD_ADDR    0x02000000
>#define SSH_NEW_OPENSSH        0x04000000
>#define SSH_BUG_DYNAMIC_RPORT    0x08000000
>+#define SSH_NEW_RSA_SHA2    0x10000000
>
>void     enable_compat13(void);
>void     enable_compat20(void);
>Index: ssh-rsa.c
>===================================================================
>RCS file: /cvs/src/usr.bin/ssh/ssh-rsa.c,v
>retrieving revision 1.46
>diff -u -p -r1.46 ssh-rsa.c
>--- ssh-rsa.c    17 May 2013 00:13:14 -0000    1.46
>+++ ssh-rsa.c    24 May 2013 12:01:33 -0000
>@@ -32,7 +32,7 @@
>
>static int openssh_RSA_verify(int, u_char *, u_int, u_char *, u_int, RSA *);
>
>-/* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */
>+/* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 or SHA256 */
>int
>ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp,
>     const u_char *data, u_int datalen)
>@@ -44,14 +44,28 @@ ssh_rsa_sign(const Key *key, u_char **si
>    int ok, nid;
>    Buffer b;
>
>-    if (key == NULL || key->rsa == NULL || (key->type != KEY_RSA &&
>-        key->type != KEY_RSA_CERT && key->type != KEY_RSA_CERT_V00)) {
>-        error("ssh_rsa_sign: no RSA key");
>+    if (key == NULL || key->rsa == NULL) {
>+        error("%s: no RSA key", __func__);
>+        return -1;
>+    }
>+    nid = NID_sha1;
>+    if ((datafellows & SSH_BUG_RSASIGMD5) != 0)
>+        nid = NID_md5;
>+    else if ((datafellows & SSH_NEW_RSA_SHA2) != 0) {
>+        nid = NID_sha256;
>+    }
>+    switch (key->type) {
>+    case KEY_RSA:
>+    case KEY_RSA_CERT:
>+    case KEY_RSA_CERT_V00:
>+        break;
>+    default:
>+        error("%s: wrong type key %s (%d)",
>+            __func__, key_type(key), key->type);
>        return -1;
>    }
>-    nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
>    if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
>-        error("ssh_rsa_sign: EVP_get_digestbynid %d failed", nid);
>+        error("%s: EVP_get_digestbynid %d failed", __func__, nid);
>        return -1;
>    }
>    EVP_DigestInit(&md, evp_md);
>@@ -67,7 +81,7 @@ ssh_rsa_sign(const Key *key, u_char **si
>    if (ok != 1) {
>        int ecode = ERR_get_error();
>
>-        error("ssh_rsa_sign: RSA_sign failed: %s",
>+        error("%s: RSA_sign failed: %s", __func__,
>            ERR_error_string(ecode, NULL));
>        free(sig);
>        return -1;
>@@ -78,7 +92,7 @@ ssh_rsa_sign(const Key *key, u_char **si
>        memmove(sig + diff, sig, len);
>        memset(sig, 0, diff);
>    } else if (len > slen) {
>-        error("ssh_rsa_sign: slen %u slen2 %u", slen, len);
>+        error("%s: slen %u slen2 %u", __func__, slen, len);
>        free(sig);
>        return -1;
>    }
>@@ -112,21 +126,37 @@ ssh_rsa_verify(const Key *key, const u_c
>    u_int len, dlen, modlen;
>    int rlen, ret, nid;
>
>-    if (key == NULL || key->rsa == NULL || (key->type != KEY_RSA &&
>-        key->type != KEY_RSA_CERT && key->type != KEY_RSA_CERT_V00)) {
>-        error("ssh_rsa_verify: no RSA key");
>+    if (key == NULL || key->rsa == NULL) {
>+        error("%s: no RSA key", __func__);
>+        return -1;
>+    }
>+    nid = NID_sha1;
>+    if ((datafellows & SSH_BUG_RSASIGMD5) != 0)
>+        nid = NID_md5;
>+    else if ((datafellows & SSH_NEW_RSA_SHA2) != 0) {
>+        nid = NID_sha256;
>+    }
>+    switch (key->type) {
>+    case KEY_RSA:
>+    case KEY_RSA_CERT:
>+    case KEY_RSA_CERT_V00:
>+        break;
>+    default:
>+        error("%s: wrong type key %s (%d)",
>+            __func__, key_type(key), key->type);
>        return -1;
>    }
>    if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
>-        error("ssh_rsa_verify: RSA modulus too small: %d < minimum %d bits",
>-            BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE);
>+        error("%s: RSA modulus too small: %d < minimum %d bits",
>+            __func__, BN_num_bits(key->rsa->n),
>+            SSH_RSA_MINIMUM_MODULUS_SIZE);
>        return -1;
>    }
>    buffer_init(&b);
>    buffer_append(&b, signature, signaturelen);
>    ktype = buffer_get_cstring(&b, NULL);
>    if (strcmp("ssh-rsa", ktype) != 0) {
>-        error("ssh_rsa_verify: cannot handle type %s", ktype);
>+        error("%s: cannot handle type %s", __func__, ktype);
>        buffer_free(&b);
>        free(ktype);
>        return -1;
>@@ -136,28 +166,27 @@ ssh_rsa_verify(const Key *key, const u_c
>    rlen = buffer_len(&b);
>    buffer_free(&b);
>    if (rlen != 0) {
>-        error("ssh_rsa_verify: remaining bytes in signature %d", rlen);
>+        error("%s: remaining bytes in signature %d", __func__, rlen);
>        free(sigblob);
>        return -1;
>    }
>    /* RSA_verify expects a signature of RSA_size */
>    modlen = RSA_size(key->rsa);
>    if (len > modlen) {
>-        error("ssh_rsa_verify: len %u > modlen %u", len, modlen);
>+        error("%s: len %u > modlen %u", __func__, len, modlen);
>        free(sigblob);
>        return -1;
>    } else if (len < modlen) {
>        u_int diff = modlen - len;
>-        debug("ssh_rsa_verify: add padding: modlen %u > len %u",
>-            modlen, len);
>+        debug("%s: add padding: modlen %u > len %u",
>+            __func__, modlen, len);
>        sigblob = xrealloc(sigblob, 1, modlen);
>        memmove(sigblob + diff, sigblob, len);
>        memset(sigblob, 0, diff);
>        len = modlen;
>    }
>-    nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
>    if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
>-        error("ssh_rsa_verify: EVP_get_digestbynid %d failed", nid);
>+        error("%s: EVP_get_digestbynid %d failed", __func__, nid);
>        free(sigblob);
>        return -1;
>    }
>@@ -169,7 +198,7 @@ ssh_rsa_verify(const Key *key, const u_c
>    memset(digest, 'd', sizeof(digest));
>    memset(sigblob, 's', len);
>    free(sigblob);
>-    debug("ssh_rsa_verify: signature %scorrect", (ret==0) ? "in" : "");
>+    debug("%s: signature %scorrect", __func__, (ret==0) ? "in" : "");
>    return ret;
>}
>
>@@ -196,12 +225,27 @@ static const u_char id_sha1[] = {
>  */
>static const u_char id_md5[] = {
>    0x30, 0x20, /* type Sequence, length 0x20 (32) */
>-    0x30, 0x0c, /* type Sequence, length 0x09 */
>-    0x06, 0x08, /* type OID, length 0x05 */
>+    0x30, 0x0c, /* type Sequence, length 0x0c (12) */
>+    0x06, 0x08, /* type OID, length 0x08 */
>    0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* id-md5 */
>    0x05, 0x00, /* NULL */
>    0x04, 0x10  /* Octet string, length 0x10 (16), followed by md5 hash */
>};
>+/*
>+ * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html
>+ * id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840)
>+ *      organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2)
>+ *      id-sha256(1) }
>+ */
>+static const u_char id_sha256[] = {
>+    0x30, 0x31, /* type Sequence, length 0x31 (49) */
>+    0x30, 0x0d, /* type Sequence, length 0x0d (13) */
>+    0x06, 0x09, /* type OID, length 0x09 */
>+    0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, /* id-sha256 */
>+    0x05, 0x00, /* NULL */
>+    0x04, 0x20  /* Octet string, length 0x20 (32), followed by sha256 hash */
>+};
>+
>
>static int
>openssh_RSA_verify(int type, u_char *hash, u_int hashlen,
>@@ -218,6 +262,11 @@ openssh_RSA_verify(int type, u_char *has
>        oid = id_sha1;
>        oidlen = sizeof(id_sha1);
>        hlen = 20;
>+        break;
>+    case NID_sha256:
>+        oid = id_sha256;
>+        oidlen = sizeof(id_sha256);
>+        hlen = 32;
>        break;
>    case NID_md5:
>        oid = id_md5;
>Index: version.h
>===================================================================
>RCS file: /cvs/src/usr.bin/ssh/version.h,v
>retrieving revision 1.66
>diff -u -p -r1.66 version.h
>--- version.h    10 Feb 2013 21:19:34 -0000    1.66
>+++ version.h    24 May 2013 12:01:33 -0000
>@@ -1,3 +1,3 @@
>/* $OpenBSD: version.h,v 1.66 2013/02/10 21:19:34 markus Exp $ */
>
>-#define SSH_VERSION    "OpenSSH_6.2"
>+#define SSH_VERSION    "OpenSSH_6.2xxx"
>_______________________________________________
>openssh-unix-dev mailing list
>openssh-unix-dev at mindrot.org
>https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
>
>
>


More information about the openssh-unix-dev mailing list