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