summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2010-08-31 22:41:14 +1000
committerDamien Miller <djm@mindrot.org>2010-08-31 22:41:14 +1000
commiteb8b60e320cdade9f4c07e2abacfb92c52e01348 (patch)
tree4e5bc25790566402e5b7ae00cefd2c57e867ef09
parentda108ece6843f1268aa36d7c8ed0030dc53acd15 (diff)
- djm@cvs.openbsd.org 2010/08/31 11:54:45
[PROTOCOL PROTOCOL.agent PROTOCOL.certkeys auth2-jpake.c authfd.c] [authfile.c buffer.h dns.c kex.c kex.h key.c key.h monitor.c] [monitor_wrap.c myproposal.h packet.c packet.h pathnames.h readconf.c] [ssh-add.1 ssh-add.c ssh-agent.1 ssh-agent.c ssh-keygen.1 ssh-keygen.c] [ssh-keyscan.1 ssh-keyscan.c ssh-keysign.8 ssh.1 ssh.c ssh2.h] [ssh_config.5 sshconnect.c sshconnect2.c sshd.8 sshd.c sshd_config.5] [uuencode.c uuencode.h bufec.c kexecdh.c kexecdhc.c kexecdhs.c ssh-ecdsa.c] Implement Elliptic Curve Cryptography modes for key exchange (ECDH) and host/user keys (ECDSA) as specified by RFC5656. ECDH and ECDSA offer better performance than plain DH and DSA at the same equivalent symmetric key length, as well as much shorter keys. Only the mandatory sections of RFC5656 are implemented, specifically the three REQUIRED curves nistp256, nistp384 and nistp521 and only ECDH and ECDSA. Point compression (optional in RFC5656 is NOT implemented). Certificate host and user keys using the new ECDSA key types are supported. Note that this code has not been tested for interoperability and may be subject to change. feedback and ok markus@
-rw-r--r--ChangeLog23
-rw-r--r--PROTOCOL45
-rw-r--r--PROTOCOL.agent44
-rw-r--r--PROTOCOL.certkeys89
-rw-r--r--auth2-jpake.c7
-rw-r--r--authfd.c20
-rw-r--r--authfile.c32
-rw-r--r--bufec.c140
-rw-r--r--buffer.h9
-rw-r--r--dns.c3
-rw-r--r--kex.c10
-rw-r--r--kex.h16
-rw-r--r--kexecdh.c108
-rw-r--r--kexecdhc.c156
-rw-r--r--kexecdhs.c161
-rw-r--r--key.c541
-rw-r--r--key.h23
-rw-r--r--monitor.c3
-rw-r--r--monitor_wrap.c3
-rw-r--r--myproposal.h32
-rw-r--r--packet.c14
-rw-r--r--packet.h5
-rw-r--r--pathnames.h4
-rw-r--r--readconf.c8
-rw-r--r--ssh-add.113
-rw-r--r--ssh-add.c3
-rw-r--r--ssh-agent.111
-rw-r--r--ssh-agent.c60
-rw-r--r--ssh-ecdsa.c160
-rw-r--r--ssh-keygen.19
-rw-r--r--ssh-keygen.c40
-rw-r--r--ssh-keyscan.120
-rw-r--r--ssh-keyscan.c13
-rw-r--r--ssh-keysign.86
-rw-r--r--ssh.125
-rw-r--r--ssh.c27
-rw-r--r--ssh2.h6
-rw-r--r--ssh_config.523
-rw-r--r--sshconnect.c4
-rw-r--r--sshconnect2.c3
-rw-r--r--sshd.820
-rw-r--r--sshd.c7
-rw-r--r--sshd_config.512
-rw-r--r--uuencode.c4
-rw-r--r--uuencode.h4
45 files changed, 1793 insertions, 173 deletions
diff --git a/ChangeLog b/ChangeLog
index 2f4acd9d..889580e5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -25,6 +25,29 @@
* actually, we allow a single one at the end of the string for now because
we don't know how many deployed implementations get this wrong, but don't
count on this to remain indefinitely.
+ - djm@cvs.openbsd.org 2010/08/31 11:54:45
+ [PROTOCOL PROTOCOL.agent PROTOCOL.certkeys auth2-jpake.c authfd.c]
+ [authfile.c buffer.h dns.c kex.c kex.h key.c key.h monitor.c]
+ [monitor_wrap.c myproposal.h packet.c packet.h pathnames.h readconf.c]
+ [ssh-add.1 ssh-add.c ssh-agent.1 ssh-agent.c ssh-keygen.1 ssh-keygen.c]
+ [ssh-keyscan.1 ssh-keyscan.c ssh-keysign.8 ssh.1 ssh.c ssh2.h]
+ [ssh_config.5 sshconnect.c sshconnect2.c sshd.8 sshd.c sshd_config.5]
+ [uuencode.c uuencode.h bufec.c kexecdh.c kexecdhc.c kexecdhs.c ssh-ecdsa.c]
+ Implement Elliptic Curve Cryptography modes for key exchange (ECDH) and
+ host/user keys (ECDSA) as specified by RFC5656. ECDH and ECDSA offer
+ better performance than plain DH and DSA at the same equivalent symmetric
+ key length, as well as much shorter keys.
+
+ Only the mandatory sections of RFC5656 are implemented, specifically the
+ three REQUIRED curves nistp256, nistp384 and nistp521 and only ECDH and
+ ECDSA. Point compression (optional in RFC5656 is NOT implemented).
+
+ Certificate host and user keys using the new ECDSA key types are supported.
+
+ Note that this code has not been tested for interoperability and may be
+ subject to change.
+
+ feedback and ok markus@
20100827
- (dtucker) [contrib/redhat/sshd.init] Bug #1810: initlog is deprecated,
diff --git a/PROTOCOL b/PROTOCOL
index 5fc31ead..5d2a7118 100644
--- a/PROTOCOL
+++ b/PROTOCOL
@@ -12,7 +12,9 @@ are individually implemented as extensions described below.
The protocol used by OpenSSH's ssh-agent is described in the file
PROTOCOL.agent
-1. transport: Protocol 2 MAC algorithm "umac-64@openssh.com"
+1. Transport protocol changes
+
+1.1. transport: Protocol 2 MAC algorithm "umac-64@openssh.com"
This is a new transport-layer MAC method using the UMAC algorithm
(rfc4418). This method is identical to the "umac-64" method documented
@@ -20,7 +22,7 @@ in:
http://www.openssh.com/txt/draft-miller-secsh-umac-01.txt
-2. transport: Protocol 2 compression algorithm "zlib@openssh.com"
+1.2. transport: Protocol 2 compression algorithm "zlib@openssh.com"
This transport-layer compression method uses the zlib compression
algorithm (identical to the "zlib" method in rfc4253), but delays the
@@ -31,14 +33,27 @@ The method is documented in:
http://www.openssh.com/txt/draft-miller-secsh-compression-delayed-00.txt
-3. transport: New public key algorithms "ssh-rsa-cert-v00@openssh.com" and
- "ssh-dsa-cert-v00@openssh.com"
+1.3. transport: New public key algorithms "ssh-rsa-cert-v00@openssh.com",
+ "ssh-dsa-cert-v00@openssh.com",
+ "ecdsa-sha2-nistp256-cert-v01@openssh.com",
+ "ecdsa-sha2-nistp384-cert-v01@openssh.com" and
+ "ecdsa-sha2-nistp521-cert-v01@openssh.com"
-OpenSSH introduces two new public key algorithms to support certificate
+OpenSSH introduces new public key algorithms to support certificate
authentication for users and hostkeys. These methods are documented in
the file PROTOCOL.certkeys
-4. connection: Channel write close extension "eow@openssh.com"
+1.4. transport: Elliptic Curve cryptography
+
+OpenSSH supports ECC key exchange and public key authentication as
+specified in RFC5656. Only the ecdsa-sha2-nistp256, ecdsa-sha2-nistp384
+and ecdsa-sha2-nistp521 curves over GF(p) are supported. Elliptic
+curve points encoded using point compression are NOT accepted or
+generated.
+
+2. Connection protocol changes
+
+2.1. connection: Channel write close extension "eow@openssh.com"
The SSH connection protocol (rfc4254) provides the SSH_MSG_CHANNEL_EOF
message to allow an endpoint to signal its peer that it will send no
@@ -77,8 +92,8 @@ message is only sent to OpenSSH peers (identified by banner).
Other SSH implementations may be whitelisted to receive this message
upon request.
-5. connection: disallow additional sessions extension
- "no-more-sessions@openssh.com"
+2.2. connection: disallow additional sessions extension
+ "no-more-sessions@openssh.com"
Most SSH connections will only ever request a single session, but a
attacker may abuse a running ssh client to surreptitiously open
@@ -105,7 +120,7 @@ of this message, the no-more-sessions request is only sent to OpenSSH
servers (identified by banner). Other SSH implementations may be
whitelisted to receive this message upon request.
-6. connection: Tunnel forward extension "tun@openssh.com"
+2.3. connection: Tunnel forward extension "tun@openssh.com"
OpenSSH supports layer 2 and layer 3 tunnelling via the "tun@openssh.com"
channel type. This channel type supports forwarding of network packets
@@ -166,7 +181,9 @@ The contents of the "data" field for layer 2 packets is:
The "frame" field contains an IEEE 802.3 Ethernet frame, including
header.
-7. sftp: Reversal of arguments to SSH_FXP_SYMLINK
+3. SFTP protocol changes
+
+3.1. sftp: Reversal of arguments to SSH_FXP_SYMLINK
When OpenSSH's sftp-server was implemented, the order of the arguments
to the SSH_FXP_SYMLINK method was inadvertently reversed. Unfortunately,
@@ -179,7 +196,7 @@ SSH_FXP_SYMLINK as follows:
string targetpath
string linkpath
-8. sftp: Server extension announcement in SSH_FXP_VERSION
+3.2. sftp: Server extension announcement in SSH_FXP_VERSION
OpenSSH's sftp-server lists the extensions it supports using the
standard extension announcement mechanism in the SSH_FXP_VERSION server
@@ -200,7 +217,7 @@ ever changed in an incompatible way. The server MAY advertise the same
extension with multiple versions (though this is unlikely). Clients MUST
check the version number before attempting to use the extension.
-9. sftp: Extension request "posix-rename@openssh.com"
+3.3. sftp: Extension request "posix-rename@openssh.com"
This operation provides a rename operation with POSIX semantics, which
are different to those provided by the standard SSH_FXP_RENAME in
@@ -217,7 +234,7 @@ rename(oldpath, newpath) and will respond with a SSH_FXP_STATUS message.
This extension is advertised in the SSH_FXP_VERSION hello with version
"1".
-10. sftp: Extension requests "statvfs@openssh.com" and
+3.4. sftp: Extension requests "statvfs@openssh.com" and
"fstatvfs@openssh.com"
These requests correspond to the statvfs and fstatvfs POSIX system
@@ -258,4 +275,4 @@ The values of the f_flag bitmask are as follows:
Both the "statvfs@openssh.com" and "fstatvfs@openssh.com" extensions are
advertised in the SSH_FXP_VERSION hello with version "2".
-$OpenBSD: PROTOCOL,v 1.15 2010/02/26 20:29:54 djm Exp $
+$OpenBSD: PROTOCOL,v 1.16 2010/08/31 11:54:45 djm Exp $
diff --git a/PROTOCOL.agent b/PROTOCOL.agent
index b34fcd31..de94d037 100644
--- a/PROTOCOL.agent
+++ b/PROTOCOL.agent
@@ -159,8 +159,8 @@ successfully added or a SSH_AGENT_FAILURE if an error occurred.
2.2.3 Add protocol 2 key
-The OpenSSH agent supports DSA and RSA keys for protocol 2. DSA keys may
-be added using the following request
+The OpenSSH agent supports DSA, ECDSA and RSA keys for protocol 2. DSA
+keys may be added using the following request
byte SSH2_AGENTC_ADD_IDENTITY or
SSH2_AGENTC_ADD_ID_CONSTRAINED
@@ -182,6 +182,30 @@ DSA certificates may be added with:
string key_comment
constraint[] key_constraints
+ECDSA keys may be added using the following request
+
+ byte SSH2_AGENTC_ADD_IDENTITY or
+ SSH2_AGENTC_ADD_ID_CONSTRAINED
+ string "ecdsa-sha2-nistp256" |
+ "ecdsa-sha2-nistp384" |
+ "ecdsa-sha2-nistp521"
+ string ecdsa_curve_name
+ string ecdsa_public_key
+ mpint ecdsa_private
+ string key_comment
+ constraint[] key_constraints
+
+ECDSA certificates may be added with:
+ byte SSH2_AGENTC_ADD_IDENTITY or
+ SSH2_AGENTC_ADD_ID_CONSTRAINED
+ string "ecdsa-sha2-nistp256-cert-v01@openssh.com" |
+ "ecdsa-sha2-nistp384-cert-v01@openssh.com" |
+ "ecdsa-sha2-nistp521-cert-v01@openssh.com"
+ string certificate
+ mpint ecdsa_private_key
+ string key_comment
+ constraint[] key_constraints
+
RSA keys may be added with this request:
byte SSH2_AGENTC_ADD_IDENTITY or
@@ -214,7 +238,7 @@ order to the protocol 1 add keys message. As with the corresponding
protocol 1 "add key" request, the private key is overspecified to avoid
redundant processing.
-For both DSA and RSA key add requests, "key_constraints" may only be
+For DSA, ECDSA and RSA key add requests, "key_constraints" may only be
present if the request type is SSH2_AGENTC_ADD_ID_CONSTRAINED.
The agent will reply with a SSH_AGENT_SUCCESS if the key has been
@@ -294,8 +318,7 @@ Protocol 2 keys may be removed with the following request:
string key_blob
Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
-Algorithms" for either of the supported key types: "ssh-dss" or
-"ssh-rsa".
+Algorithms" for any of the supported protocol 2 key types.
The agent will delete any private key matching the specified public key
and return SSH_AGENT_SUCCESS. If no such key was found, the agent will
@@ -364,8 +387,7 @@ Followed by zero or more consecutive keys, encoded as:
string key_comment
Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
-Algorithms" for either of the supported key types: "ssh-dss" or
-"ssh-rsa".
+Algorithms" for any of the supported protocol 2 key types.
2.6 Private key operations
@@ -429,9 +451,9 @@ a protocol 2 key:
uint32 flags
Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
-Algorithms" for either of the supported key types: "ssh-dss" or
-"ssh-rsa". "flags" is a bit-mask, but at present only one possible value
-is defined (see below for its meaning):
+Algorithms" for any of the supported protocol 2 key types. "flags" is
+a bit-mask, but at present only one possible value is defined (see below
+for its meaning):
SSH_AGENT_OLD_SIGNATURE 1
@@ -535,4 +557,4 @@ Locking and unlocking affects both protocol 1 and protocol 2 keys.
SSH_AGENT_CONSTRAIN_LIFETIME 1
SSH_AGENT_CONSTRAIN_CONFIRM 2
-$OpenBSD: PROTOCOL.agent,v 1.5 2010/02/26 20:29:54 djm Exp $
+$OpenBSD: PROTOCOL.agent,v 1.6 2010/08/31 11:54:45 djm Exp $
diff --git a/PROTOCOL.certkeys b/PROTOCOL.certkeys
index 1d1be13d..2f976498 100644
--- a/PROTOCOL.certkeys
+++ b/PROTOCOL.certkeys
@@ -5,31 +5,37 @@ Background
----------
The SSH protocol currently supports a simple public key authentication
-mechanism. Unlike other public key implementations, SSH eschews the
-use of X.509 certificates and uses raw keys. This approach has some
-benefits relating to simplicity of configuration and minimisation
-of attack surface, but it does not support the important use-cases
-of centrally managed, passwordless authentication and centrally
-certified host keys.
+mechanism. Unlike other public key implementations, SSH eschews the use
+of X.509 certificates and uses raw keys. This approach has some benefits
+relating to simplicity of configuration and minimisation of attack
+surface, but it does not support the important use-cases of centrally
+managed, passwordless authentication and centrally certified host keys.
These protocol extensions build on the simple public key authentication
-system already in SSH to allow certificate-based authentication.
-The certificates used are not traditional X.509 certificates, with
-numerous options and complex encoding rules, but something rather
-more minimal: a key, some identity information and usage options
-that have been signed with some other trusted key.
+system already in SSH to allow certificate-based authentication. The
+certificates used are not traditional X.509 certificates, with numerous
+options and complex encoding rules, but something rather more minimal: a
+key, some identity information and usage options that have been signed
+with some other trusted key.
A sshd server may be configured to allow authentication via certified
-keys, by extending the existing ~/.ssh/authorized_keys mechanism
-to allow specification of certification authority keys in addition
-to raw user keys. The ssh client will support automatic verification
-of acceptance of certified host keys, by adding a similar ability
-to specify CA keys in ~/.ssh/known_hosts.
+keys, by extending the existing ~/.ssh/authorized_keys mechanism to
+allow specification of certification authority keys in addition to
+raw user keys. The ssh client will support automatic verification of
+acceptance of certified host keys, by adding a similar ability to
+specify CA keys in ~/.ssh/known_hosts.
-Certified keys are represented using two new key types:
-ssh-rsa-cert-v01@openssh.com and ssh-dss-cert-v01@openssh.com that
-include certification information along with the public key that is used
-to sign challenges. ssh-keygen performs the CA signing operation.
+Certified keys are represented using new key types:
+
+ ssh-rsa-cert-v01@openssh.com
+ ssh-dss-cert-v01@openssh.com
+ ecdsa-sha2-nistp256-cert-v01@openssh.com
+ ecdsa-sha2-nistp384-cert-v01@openssh.com
+ ecdsa-sha2-nistp521-cert-v01@openssh.com
+
+These include certification information along with the public key
+that is used to sign challenges. ssh-keygen performs the CA signing
+operation.
Protocol extensions
-------------------
@@ -47,10 +53,9 @@ in RFC4252 section 7.
New public key formats
----------------------
-The ssh-rsa-cert-v01@openssh.com and ssh-dss-cert-v01@openssh.com key
-types take a similar high-level format (note: data types and
-encoding are as per RFC4251 section 5). The serialised wire encoding of
-these certificates is also used for storing them on disk.
+The certificate key types take a similar high-level format (note: data
+types and encoding are as per RFC4251 section 5). The serialised wire
+encoding of these certificates is also used for storing them on disk.
#define SSH_CERT_TYPE_USER 1
#define SSH_CERT_TYPE_HOST 2
@@ -93,6 +98,26 @@ DSA certificate
string signature key
string signature
+ECDSA certificate
+
+ string "ecdsa-sha2-nistp256@openssh.com" |
+ "ecdsa-sha2-nistp384@openssh.com" |
+ "ecdsa-sha2-nistp521@openssh.com"
+ string nonce
+ string curve
+ string public_key
+ uint64 serial
+ uint32 type
+ string key id
+ string valid principals
+ uint64 valid after
+ uint64 valid before
+ string critical options
+ string extensions
+ string reserved
+ string signature key
+ string signature
+
The nonce field is a CA-provided random bitstring of arbitrary length
(but typically 16 or 32 bytes) included to make attacks that depend on
inducing collisions in the signature hash infeasible.
@@ -101,6 +126,9 @@ e and n are the RSA exponent and public modulus respectively.
p, q, g, y are the DSA parameters as described in FIPS-186-2.
+curve and public key are respectively the ECDSA "[identifier]" and "Q"
+defined in section 3.1 of RFC5656.
+
serial is an optional certificate serial number set by the CA to
provide an abbreviated way to refer to certificates from that CA.
If a CA does not wish to number its certificates it must set this
@@ -123,7 +151,8 @@ any principal of the specified type. XXX DNS wildcards?
"valid after" and "valid before" specify a validity period for the
certificate. Each represents a time in seconds since 1970-01-01
00:00:00. A certificate is considered valid if:
- valid after <= current time < valid before
+
+ valid after <= current time < valid before
criticial options is a set of zero or more key options encoded as
below. All such options are "critical" in the sense that an implementation
@@ -137,15 +166,17 @@ The reserved field is currently unused and is ignored in this version of
the protocol.
signature key contains the CA key used to sign the certificate.
-The valid key types for CA keys are ssh-rsa and ssh-dss. "Chained"
+The valid key types for CA keys are ssh-rsa, ssh-dss and the ECDSA types
+ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521. "Chained"
certificates, where the signature key type is a certificate type itself
are NOT supported. Note that it is possible for a RSA certificate key to
-be signed by a DSS CA key and vice-versa.
+be signed by a DSS or ECDSA CA key and vice-versa.
signature is computed over all preceding fields from the initial string
up to, and including the signature key. Signatures are computed and
encoded according to the rules defined for the CA's public key algorithm
-(RFC4253 section 6.6 for ssh-rsa and ssh-dss).
+(RFC4253 section 6.6 for ssh-rsa and ssh-dss, RFC5656 for the ECDSA
+types).
Critical options
----------------
@@ -222,4 +253,4 @@ permit-user-rc empty Flag indicating that execution of
of this script will not be permitted if
this option is not present.
-$OpenBSD: PROTOCOL.certkeys,v 1.7 2010/08/04 05:40:39 djm Exp $
+$OpenBSD: PROTOCOL.certkeys,v 1.8 2010/08/31 11:54:45 djm Exp $
diff --git a/auth2-jpake.c b/auth2-jpake.c
index 5de5506a..a460e821 100644
--- a/auth2-jpake.c
+++ b/auth2-jpake.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-jpake.c,v 1.3 2009/03/05 07:18:19 djm Exp $ */
+/* $OpenBSD: auth2-jpake.c,v 1.4 2010/08/31 11:54:45 djm Exp $ */
/*
* Copyright (c) 2008 Damien Miller. All rights reserved.
*
@@ -162,6 +162,11 @@ derive_rawsalt(const char *username, u_char *rawsalt, u_int len)
fatal("%s: DSA key missing priv_key", __func__);
buffer_put_bignum2(&b, k->dsa->priv_key);
break;
+ case KEY_ECDSA:
+ if (EC_KEY_get0_private_key(k->ecdsa) == NULL)
+ fatal("%s: ECDSA key missing priv_key", __func__);
+ buffer_put_bignum2(&b, EC_KEY_get0_private_key(k->ecdsa));
+ break;
default:
fatal("%s: unknown key type %d", __func__, k->type);
}
diff --git a/authfd.c b/authfd.c
index 739722fb..ec537d2e 100644
--- a/authfd.c
+++ b/authfd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: authfd.c,v 1.83 2010/04/16 01:47:26 djm Exp $ */
+/* $OpenBSD: authfd.c,v 1.84 2010/08/31 11:54:45 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -509,6 +509,19 @@ ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment)
buffer_len(&key->cert->certblob));
buffer_put_bignum2(b, key->dsa->priv_key);
break;
+ case KEY_ECDSA:
+ buffer_put_cstring(b, key_curve_nid_to_name(key->ecdsa_nid));
+ buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
+ EC_KEY_get0_public_key(key->ecdsa));
+ buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa));
+ break;
+ case KEY_ECDSA_CERT:
+ if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
+ fatal("%s: no cert/certblob", __func__);
+ buffer_put_string(b, buffer_ptr(&key->cert->certblob),
+ buffer_len(&key->cert->certblob));
+ buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa));
+ break;
}
buffer_put_cstring(b, comment);
}
@@ -541,6 +554,8 @@ ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key,
case KEY_DSA:
case KEY_DSA_CERT:
case KEY_DSA_CERT_V00:
+ case KEY_ECDSA:
+ case KEY_ECDSA_CERT:
type = constrained ?
SSH2_AGENTC_ADD_ID_CONSTRAINED :
SSH2_AGENTC_ADD_IDENTITY;
@@ -589,7 +604,8 @@ ssh_remove_identity(AuthenticationConnection *auth, Key *key)
buffer_put_bignum(&msg, key->rsa->e);
buffer_put_bignum(&msg, key->rsa->n);
} else if (key_type_plain(key->type) == KEY_DSA ||
- key_type_plain(key->type) == KEY_RSA) {
+ key_type_plain(key->type) == KEY_RSA ||
+ key_type_plain(key->type) == KEY_ECDSA) {
key_to_blob(key, &blob, &blen);
buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY);
buffer_put_string(&msg, blob, blen);
diff --git a/authfile.c b/authfile.c
index 2bd88784..865e7faf 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: authfile.c,v 1.82 2010/08/04 05:49:22 djm Exp $ */
+/* $OpenBSD: authfile.c,v 1.83 2010/08/31 11:54:45 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -213,6 +213,10 @@ key_save_private_pem(Key *key, const char *filename, const char *_passphrase,
success = PEM_write_DSAPrivateKey(fp, key->dsa,
cipher, passphrase, len, NULL, NULL);
break;
+ case KEY_ECDSA:
+ success = PEM_write_ECPrivateKey(fp, key->ecdsa,
+ cipher, passphrase, len, NULL, NULL);
+ break;
case KEY_RSA:
success = PEM_write_RSAPrivateKey(fp, key->rsa,
cipher, passphrase, len, NULL, NULL);
@@ -231,6 +235,7 @@ key_save_private(Key *key, const char *filename, const char *passphrase,
return key_save_private_rsa1(key, filename, passphrase,
comment);
case KEY_DSA:
+ case KEY_ECDSA:
case KEY_RSA:
return key_save_private_pem(key, filename, passphrase,
comment);
@@ -510,6 +515,29 @@ key_load_private_pem(int fd, int type, const char *passphrase,
#ifdef DEBUG_PK
DSA_print_fp(stderr, prv->dsa, 8);
#endif
+ } else if (pk->type == EVP_PKEY_EC &&
+ (type == KEY_UNSPEC||type==KEY_ECDSA)) {
+ prv = key_new(KEY_UNSPEC);
+ prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk);
+ prv->type = KEY_ECDSA;
+ prv->ecdsa_nid = key_ecdsa_group_to_nid(
+ EC_KEY_get0_group(prv->ecdsa));
+ if (key_curve_nid_to_name(prv->ecdsa_nid) == NULL) {
+ key_free(prv);
+ prv = NULL;
+ }
+ if (key_ec_validate_public(EC_KEY_get0_group(prv->ecdsa),
+ EC_KEY_get0_public_key(prv->ecdsa)) != 0 ||
+ key_ec_validate_private(prv->ecdsa) != 0) {
+ error("%s: bad ECDSA key", __func__);
+ key_free(prv);
+ prv = NULL;
+ }
+ name = "dsa w/o comment";
+#ifdef DEBUG_PK
+ if (prv->ecdsa != NULL)
+ key_dump_ec_key(prv->ecdsa);
+#endif
} else {
error("PEM_read_PrivateKey: mismatch or "
"unknown EVP_PKEY save_type %d", pk->save_type);
@@ -581,6 +609,7 @@ key_load_private_type(int type, const char *filename, const char *passphrase,
commentp);
/* closes fd */
case KEY_DSA:
+ case KEY_ECDSA:
case KEY_RSA:
case KEY_UNSPEC:
return key_load_private_pem(fd, type, passphrase, commentp);
@@ -721,6 +750,7 @@ key_load_private_cert(int type, const char *filename, const char *passphrase,
switch (type) {
case KEY_RSA:
case KEY_DSA:
+ case KEY_ECDSA:
break;
default:
error("%s: unsupported key type", __func__);
diff --git a/bufec.c b/bufec.c
new file mode 100644
index 00000000..dff9c69c
--- /dev/null
+++ b/bufec.c
@@ -0,0 +1,140 @@
+/* $OpenBSD: bufec.c,v 1.1 2010/08/31 11:54:45 djm Exp $ */
+/*
+ * Copyright (c) 2010 Damien Miller <djm@mindrot.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <sys/types.h>
+
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+
+#include <string.h>
+#include <stdarg.h>
+
+#include "xmalloc.h"
+#include "buffer.h"
+#include "log.h"
+#include "misc.h"
+
+/*
+ * Maximum supported EC GFp field length is 528 bits. SEC1 uncompressed
+ * encoding represents this as two bitstring points that should each
+ * be no longer than the field length, SEC1 specifies a 1 byte
+ * point type header.
+ * Being paranoid here may insulate us to parsing problems in
+ * EC_POINT_oct2point.
+ */
+#define BUFFER_MAX_ECPOINT_LEN ((528*2 / 8) + 1)
+
+/*
+ * Append an EC_POINT to the buffer as a string containing a SEC1 encoded
+ * uncompressed point. Fortunately OpenSSL handles the gory details for us.
+ */
+int
+buffer_put_ecpoint_ret(Buffer *buffer, const EC_GROUP *curve,
+ const EC_POINT *point)
+{
+ u_char *buf = NULL;
+ size_t len;
+ BN_CTX *bnctx;
+ int ret = -1;
+
+ /* Determine length */
+ if ((bnctx = BN_CTX_new()) == NULL)
+ fatal("%s: BN_CTX_new failed", __func__);
+ len = EC_POINT_point2oct(curve, point, POINT_CONVERSION_UNCOMPRESSED,
+ NULL, 0, bnctx);
+ if (len > BUFFER_MAX_ECPOINT_LEN) {
+