mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-27 07:44:29 +02:00
- djm@cvs.openbsd.org 2010/04/16 01:47:26
[PROTOCOL.certkeys auth-options.c auth-options.h auth-rsa.c] [auth2-pubkey.c authfd.c key.c key.h myproposal.h ssh-add.c] [ssh-agent.c ssh-dss.c ssh-keygen.1 ssh-keygen.c ssh-rsa.c] [sshconnect.c sshconnect2.c sshd.c] revised certificate format ssh-{dss,rsa}-cert-v01@openssh.com with the following changes: move the nonce field to the beginning of the certificate where it can better protect against chosen-prefix attacks on the signature hash Rename "constraints" field to "critical options" Add a new non-critical "extensions" field Add a serial number The older format is still support for authentication and cert generation (use "ssh-keygen -t v00 -s ca_key ..." to generate a v00 certificate) ok markus@
This commit is contained in:
parent
031c9100df
commit
4e270b05dd
21
ChangeLog
21
ChangeLog
@ -41,6 +41,27 @@
|
|||||||
retry lookup for private key if there's no matching key with CKA_SIGN
|
retry lookup for private key if there's no matching key with CKA_SIGN
|
||||||
attribute enabled; this fixes fixes MuscleCard support (bugzilla #1736)
|
attribute enabled; this fixes fixes MuscleCard support (bugzilla #1736)
|
||||||
ok djm@
|
ok djm@
|
||||||
|
- djm@cvs.openbsd.org 2010/04/16 01:47:26
|
||||||
|
[PROTOCOL.certkeys auth-options.c auth-options.h auth-rsa.c]
|
||||||
|
[auth2-pubkey.c authfd.c key.c key.h myproposal.h ssh-add.c]
|
||||||
|
[ssh-agent.c ssh-dss.c ssh-keygen.1 ssh-keygen.c ssh-rsa.c]
|
||||||
|
[sshconnect.c sshconnect2.c sshd.c]
|
||||||
|
revised certificate format ssh-{dss,rsa}-cert-v01@openssh.com with the
|
||||||
|
following changes:
|
||||||
|
|
||||||
|
move the nonce field to the beginning of the certificate where it can
|
||||||
|
better protect against chosen-prefix attacks on the signature hash
|
||||||
|
|
||||||
|
Rename "constraints" field to "critical options"
|
||||||
|
|
||||||
|
Add a new non-critical "extensions" field
|
||||||
|
|
||||||
|
Add a serial number
|
||||||
|
|
||||||
|
The older format is still support for authentication and cert generation
|
||||||
|
(use "ssh-keygen -t v00 -s ca_key ..." to generate a v00 certificate)
|
||||||
|
|
||||||
|
ok markus@
|
||||||
|
|
||||||
20100410
|
20100410
|
||||||
- (dtucker) [configure.ac] Put the check for the existence of getaddrinfo
|
- (dtucker) [configure.ac] Put the check for the existence of getaddrinfo
|
||||||
|
@ -16,7 +16,7 @@ These protocol extensions build on the simple public key authentication
|
|||||||
system already in SSH to allow certificate-based authentication.
|
system already in SSH to allow certificate-based authentication.
|
||||||
The certificates used are not traditional X.509 certificates, with
|
The certificates used are not traditional X.509 certificates, with
|
||||||
numerous options and complex encoding rules, but something rather
|
numerous options and complex encoding rules, but something rather
|
||||||
more minimal: a key, some identity information and usage constraints
|
more minimal: a key, some identity information and usage options
|
||||||
that have been signed with some other trusted key.
|
that have been signed with some other trusted key.
|
||||||
|
|
||||||
A sshd server may be configured to allow authentication via certified
|
A sshd server may be configured to allow authentication via certified
|
||||||
@ -27,7 +27,7 @@ of acceptance of certified host keys, by adding a similar ability
|
|||||||
to specify CA keys in ~/.ssh/known_hosts.
|
to specify CA keys in ~/.ssh/known_hosts.
|
||||||
|
|
||||||
Certified keys are represented using two new key types:
|
Certified keys are represented using two new key types:
|
||||||
ssh-rsa-cert-v00@openssh.com and ssh-dss-cert-v00@openssh.com that
|
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
|
include certification information along with the public key that is used
|
||||||
to sign challenges. ssh-keygen performs the CA signing operation.
|
to sign challenges. ssh-keygen performs the CA signing operation.
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ in RFC4252 section 7.
|
|||||||
New public key formats
|
New public key formats
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
The ssh-rsa-cert-v00@openssh.com and ssh-dss-cert-v00@openssh.com key
|
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
|
types take a similar high-level format (note: data types and
|
||||||
encoding are as per RFC4251 section 5). The serialised wire encoding of
|
encoding are as per RFC4251 section 5). The serialised wire encoding of
|
||||||
these certificates is also used for storing them on disk.
|
these certificates is also used for storing them on disk.
|
||||||
@ -57,42 +57,55 @@ these certificates is also used for storing them on disk.
|
|||||||
|
|
||||||
RSA certificate
|
RSA certificate
|
||||||
|
|
||||||
string "ssh-rsa-cert-v00@openssh.com"
|
string "ssh-rsa-cert-v01@openssh.com"
|
||||||
|
string nonce
|
||||||
mpint e
|
mpint e
|
||||||
mpint n
|
mpint n
|
||||||
|
uint64 serial
|
||||||
uint32 type
|
uint32 type
|
||||||
string key id
|
string key id
|
||||||
string valid principals
|
string valid principals
|
||||||
uint64 valid after
|
uint64 valid after
|
||||||
uint64 valid before
|
uint64 valid before
|
||||||
string constraints
|
string critical options
|
||||||
string nonce
|
string extensions
|
||||||
string reserved
|
string reserved
|
||||||
string signature key
|
string signature key
|
||||||
string signature
|
string signature
|
||||||
|
|
||||||
DSA certificate
|
DSA certificate
|
||||||
|
|
||||||
string "ssh-dss-cert-v00@openssh.com"
|
string "ssh-dss-cert-v01@openssh.com"
|
||||||
|
string nonce
|
||||||
mpint p
|
mpint p
|
||||||
mpint q
|
mpint q
|
||||||
mpint g
|
mpint g
|
||||||
mpint y
|
mpint y
|
||||||
|
uint64 serial
|
||||||
uint32 type
|
uint32 type
|
||||||
string key id
|
string key id
|
||||||
string valid principals
|
string valid principals
|
||||||
uint64 valid after
|
uint64 valid after
|
||||||
uint64 valid before
|
uint64 valid before
|
||||||
string constraints
|
string critical options
|
||||||
string nonce
|
string extensions
|
||||||
string reserved
|
string reserved
|
||||||
string signature key
|
string signature key
|
||||||
string signature
|
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.
|
||||||
|
|
||||||
e and n are the RSA exponent and public modulus respectively.
|
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.
|
p, q, g, y are the DSA parameters as described in FIPS-186-2.
|
||||||
|
|
||||||
|
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 with to number its certificates it must set this
|
||||||
|
field to zero.
|
||||||
|
|
||||||
type specifies whether this certificate is for identification of a user
|
type specifies whether this certificate is for identification of a user
|
||||||
or a host using a SSH_CERT_TYPE_... value.
|
or a host using a SSH_CERT_TYPE_... value.
|
||||||
|
|
||||||
@ -112,13 +125,15 @@ certificate. Each represents a time in seconds since 1970-01-01
|
|||||||
00:00:00. A certificate is considered valid if:
|
00:00:00. A certificate is considered valid if:
|
||||||
valid after <= current time < valid before
|
valid after <= current time < valid before
|
||||||
|
|
||||||
constraints is a set of zero or more key constraints encoded as below.
|
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
|
||||||
|
must refuse to authorise a key that has an unrecognised option.
|
||||||
|
|
||||||
The nonce field is a CA-provided random bitstring of arbitrary length
|
extensions is a set of zero or more optional extensions. These extensions
|
||||||
(but typically 16 or 32 bytes) included to make attacks that depend on
|
are not critical, and an implementation that encounters one that it does
|
||||||
inducing collisions in the signature hash infeasible.
|
not recognise may safely ignore it. No extensions are defined at present.
|
||||||
|
|
||||||
The reserved field is current unused and is ignored in this version of
|
The reserved field is currently unused and is ignored in this version of
|
||||||
the protocol.
|
the protocol.
|
||||||
|
|
||||||
signature key contains the CA key used to sign the certificate.
|
signature key contains the CA key used to sign the certificate.
|
||||||
@ -132,22 +147,22 @@ up to, and including the signature key. Signatures are computed and
|
|||||||
encoded according to the rules defined for the CA's public key algorithm
|
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).
|
||||||
|
|
||||||
Constraints
|
Critical options
|
||||||
-----------
|
----------------
|
||||||
|
|
||||||
The constraints section of the certificate specifies zero or more
|
The critical options section of the certificate specifies zero or more
|
||||||
constraints on the certificates validity. The format of this field
|
options on the certificates validity. The format of this field
|
||||||
is a sequence of zero or more tuples:
|
is a sequence of zero or more tuples:
|
||||||
|
|
||||||
string name
|
string name
|
||||||
string data
|
string data
|
||||||
|
|
||||||
The name field identifies the constraint and the data field encodes
|
The name field identifies the option and the data field encodes
|
||||||
constraint-specific information (see below). All constraints are
|
option-specific information (see below). All options are
|
||||||
"critical", if an implementation does not recognise a constraint
|
"critical", if an implementation does not recognise a option
|
||||||
then the validating party should refuse to accept the certificate.
|
then the validating party should refuse to accept the certificate.
|
||||||
|
|
||||||
The supported constraints and the contents and structure of their
|
The supported options and the contents and structure of their
|
||||||
data fields are:
|
data fields are:
|
||||||
|
|
||||||
Name Format Description
|
Name Format Description
|
||||||
@ -159,35 +174,35 @@ force-command string Specifies a command that is executed
|
|||||||
|
|
||||||
permit-X11-forwarding empty Flag indicating that X11 forwarding
|
permit-X11-forwarding empty Flag indicating that X11 forwarding
|
||||||
should be permitted. X11 forwarding will
|
should be permitted. X11 forwarding will
|
||||||
be refused if this constraint is absent.
|
be refused if this option is absent.
|
||||||
|
|
||||||
permit-agent-forwarding empty Flag indicating that agent forwarding
|
permit-agent-forwarding empty Flag indicating that agent forwarding
|
||||||
should be allowed. Agent forwarding
|
should be allowed. Agent forwarding
|
||||||
must not be permitted unless this
|
must not be permitted unless this
|
||||||
constraint is present.
|
option is present.
|
||||||
|
|
||||||
permit-port-forwarding empty Flag indicating that port-forwarding
|
permit-port-forwarding empty Flag indicating that port-forwarding
|
||||||
should be allowed. If this constraint is
|
should be allowed. If this option is
|
||||||
not present then no port forwarding will
|
not present then no port forwarding will
|
||||||
be allowed.
|
be allowed.
|
||||||
|
|
||||||
permit-pty empty Flag indicating that PTY allocation
|
permit-pty empty Flag indicating that PTY allocation
|
||||||
should be permitted. In the absence of
|
should be permitted. In the absence of
|
||||||
this constraint PTY allocation will be
|
this option PTY allocation will be
|
||||||
disabled.
|
disabled.
|
||||||
|
|
||||||
permit-user-rc empty Flag indicating that execution of
|
permit-user-rc empty Flag indicating that execution of
|
||||||
~/.ssh/rc should be permitted. Execution
|
~/.ssh/rc should be permitted. Execution
|
||||||
of this script will not be permitted if
|
of this script will not be permitted if
|
||||||
this constraint is not present.
|
this option is not present.
|
||||||
|
|
||||||
source-address string Comma-separated list of source addresses
|
source-address string Comma-separated list of source addresses
|
||||||
from which this certificate is accepted
|
from which this certificate is accepted
|
||||||
for authentication. Addresses are
|
for authentication. Addresses are
|
||||||
specified in CIDR format (nn.nn.nn.nn/nn
|
specified in CIDR format (nn.nn.nn.nn/nn
|
||||||
or hhhh::hhhh/nn).
|
or hhhh::hhhh/nn).
|
||||||
If this constraint is not present then
|
If this option is not present then
|
||||||
certificates may be presented from any
|
certificates may be presented from any
|
||||||
source address.
|
source address.
|
||||||
|
|
||||||
$OpenBSD: PROTOCOL.certkeys,v 1.3 2010/03/03 22:50:40 djm Exp $
|
$OpenBSD: PROTOCOL.certkeys,v 1.4 2010/04/16 01:47:25 djm Exp $
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: auth-options.c,v 1.49 2010/03/16 15:46:52 stevesk Exp $ */
|
/* $OpenBSD: auth-options.c,v 1.50 2010/04/16 01:47:26 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -27,10 +27,10 @@
|
|||||||
#include "canohost.h"
|
#include "canohost.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "channels.h"
|
#include "channels.h"
|
||||||
#include "auth-options.h"
|
|
||||||
#include "servconf.h"
|
#include "servconf.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
|
#include "auth-options.h"
|
||||||
#include "hostfile.h"
|
#include "hostfile.h"
|
||||||
#include "auth.h"
|
#include "auth.h"
|
||||||
#ifdef GSSAPI
|
#ifdef GSSAPI
|
||||||
@ -377,11 +377,11 @@ bad_option:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set options from certificate constraints. These supersede user key options
|
* Set options from critical certificate options. These supersede user key
|
||||||
* so this must be called after auth_parse_options().
|
* options so this must be called after auth_parse_options().
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
auth_cert_constraints(Buffer *c_orig, struct passwd *pw)
|
auth_cert_options(Key *k, struct passwd *pw)
|
||||||
{
|
{
|
||||||
u_char *name = NULL, *data_blob = NULL;
|
u_char *name = NULL, *data_blob = NULL;
|
||||||
u_int nlen, dlen, clen;
|
u_int nlen, dlen, clen;
|
||||||
@ -400,12 +400,13 @@ auth_cert_constraints(Buffer *c_orig, struct passwd *pw)
|
|||||||
|
|
||||||
/* Make copy to avoid altering original */
|
/* Make copy to avoid altering original */
|
||||||
buffer_init(&c);
|
buffer_init(&c);
|
||||||
buffer_append(&c, buffer_ptr(c_orig), buffer_len(c_orig));
|
buffer_append(&c,
|
||||||
|
buffer_ptr(&k->cert->critical), buffer_len(&k->cert->critical));
|
||||||
|
|
||||||
while (buffer_len(&c) > 0) {
|
while (buffer_len(&c) > 0) {
|
||||||
if ((name = buffer_get_string_ret(&c, &nlen)) == NULL ||
|
if ((name = buffer_get_string_ret(&c, &nlen)) == NULL ||
|
||||||
(data_blob = buffer_get_string_ret(&c, &dlen)) == NULL) {
|
(data_blob = buffer_get_string_ret(&c, &dlen)) == NULL) {
|
||||||
error("Certificate constraints corrupt");
|
error("Certificate options corrupt");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
buffer_append(&data, data_blob, dlen);
|
buffer_append(&data, data_blob, dlen);
|
||||||
@ -439,7 +440,7 @@ auth_cert_constraints(Buffer *c_orig, struct passwd *pw)
|
|||||||
}
|
}
|
||||||
if (cert_forced_command != NULL) {
|
if (cert_forced_command != NULL) {
|
||||||
error("Certificate has multiple "
|
error("Certificate has multiple "
|
||||||
"force-command constraints");
|
"force-command options");
|
||||||
xfree(command);
|
xfree(command);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -459,7 +460,7 @@ auth_cert_constraints(Buffer *c_orig, struct passwd *pw)
|
|||||||
}
|
}
|
||||||
if (cert_source_address_done++) {
|
if (cert_source_address_done++) {
|
||||||
error("Certificate has multiple "
|
error("Certificate has multiple "
|
||||||
"source-address constraints");
|
"source-address options");
|
||||||
xfree(allowed);
|
xfree(allowed);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -502,7 +503,7 @@ auth_cert_constraints(Buffer *c_orig, struct passwd *pw)
|
|||||||
name = data_blob = NULL;
|
name = data_blob = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* successfully parsed all constraints */
|
/* successfully parsed all options */
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
no_port_forwarding_flag |= cert_no_port_forwarding_flag;
|
no_port_forwarding_flag |= cert_no_port_forwarding_flag;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: auth-options.h,v 1.18 2010/02/26 20:29:54 djm Exp $ */
|
/* $OpenBSD: auth-options.h,v 1.19 2010/04/16 01:47:26 djm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
@ -34,6 +34,6 @@ extern int key_is_cert_authority;
|
|||||||
|
|
||||||
int auth_parse_options(struct passwd *, char *, char *, u_long);
|
int auth_parse_options(struct passwd *, char *, char *, u_long);
|
||||||
void auth_clear_options(void);
|
void auth_clear_options(void);
|
||||||
int auth_cert_constraints(Buffer *, struct passwd *);
|
int auth_cert_options(Key *, struct passwd *);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: auth-rsa.c,v 1.74 2010/03/04 10:36:03 djm Exp $ */
|
/* $OpenBSD: auth-rsa.c,v 1.75 2010/04/16 01:47:26 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -34,11 +34,11 @@
|
|||||||
#include "uidswap.h"
|
#include "uidswap.h"
|
||||||
#include "match.h"
|
#include "match.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "auth-options.h"
|
|
||||||
#include "pathnames.h"
|
#include "pathnames.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "servconf.h"
|
#include "servconf.h"
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
|
#include "auth-options.h"
|
||||||
#include "hostfile.h"
|
#include "hostfile.h"
|
||||||
#include "auth.h"
|
#include "auth.h"
|
||||||
#ifdef GSSAPI
|
#ifdef GSSAPI
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: auth2-pubkey.c,v 1.22 2010/03/10 23:27:17 djm Exp $ */
|
/* $OpenBSD: auth2-pubkey.c,v 1.23 2010/04/16 01:47:26 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||||
*
|
*
|
||||||
@ -235,7 +235,7 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
|
|||||||
}
|
}
|
||||||
if (auth_parse_options(pw, key_options, file, linenum) != 1)
|
if (auth_parse_options(pw, key_options, file, linenum) != 1)
|
||||||
continue;
|
continue;
|
||||||
if (key->type == KEY_RSA_CERT || key->type == KEY_DSA_CERT) {
|
if (key_is_cert(key)) {
|
||||||
if (!key_is_cert_authority)
|
if (!key_is_cert_authority)
|
||||||
continue;
|
continue;
|
||||||
if (!key_equal(found, key->cert->signature_key))
|
if (!key_equal(found, key->cert->signature_key))
|
||||||
@ -251,8 +251,7 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
|
|||||||
auth_debug_add("%s", reason);
|
auth_debug_add("%s", reason);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (auth_cert_constraints(&key->cert->constraints,
|
if (auth_cert_options(key, pw) != 0) {
|
||||||
pw) != 0) {
|
|
||||||
xfree(fp);
|
xfree(fp);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -307,7 +306,7 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
|
|||||||
auth_debug_add("%s", reason);
|
auth_debug_add("%s", reason);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (auth_cert_constraints(&key->cert->constraints, pw) != 0)
|
if (auth_cert_options(key, pw) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
verbose("Accepted certificate ID \"%s\" signed by %s CA %s via %s",
|
verbose("Accepted certificate ID \"%s\" signed by %s CA %s via %s",
|
||||||
|
6
authfd.c
6
authfd.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: authfd.c,v 1.82 2010/02/26 20:29:54 djm Exp $ */
|
/* $OpenBSD: authfd.c,v 1.83 2010/04/16 01:47:26 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -483,6 +483,7 @@ ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment)
|
|||||||
buffer_put_bignum2(b, key->rsa->p);
|
buffer_put_bignum2(b, key->rsa->p);
|
||||||
buffer_put_bignum2(b, key->rsa->q);
|
buffer_put_bignum2(b, key->rsa->q);
|
||||||
break;
|
break;
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
|
if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
|
||||||
fatal("%s: no cert/certblob", __func__);
|
fatal("%s: no cert/certblob", __func__);
|
||||||
@ -500,6 +501,7 @@ ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment)
|
|||||||
buffer_put_bignum2(b, key->dsa->pub_key);
|
buffer_put_bignum2(b, key->dsa->pub_key);
|
||||||
buffer_put_bignum2(b, key->dsa->priv_key);
|
buffer_put_bignum2(b, key->dsa->priv_key);
|
||||||
break;
|
break;
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT:
|
||||||
if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
|
if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
|
||||||
fatal("%s: no cert/certblob", __func__);
|
fatal("%s: no cert/certblob", __func__);
|
||||||
@ -535,8 +537,10 @@ ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key,
|
|||||||
break;
|
break;
|
||||||
case KEY_RSA:
|
case KEY_RSA:
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
case KEY_DSA:
|
case KEY_DSA:
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT:
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
type = constrained ?
|
type = constrained ?
|
||||||
SSH2_AGENTC_ADD_ID_CONSTRAINED :
|
SSH2_AGENTC_ADD_ID_CONSTRAINED :
|
||||||
SSH2_AGENTC_ADD_IDENTITY;
|
SSH2_AGENTC_ADD_IDENTITY;
|
||||||
|
177
key.c
177
key.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: key.c,v 1.86 2010/03/15 19:40:02 stevesk Exp $ */
|
/* $OpenBSD: key.c,v 1.87 2010/04/16 01:47:26 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* read_bignum():
|
* read_bignum():
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -61,7 +61,8 @@ cert_new(void)
|
|||||||
|
|
||||||
cert = xcalloc(1, sizeof(*cert));
|
cert = xcalloc(1, sizeof(*cert));
|
||||||
buffer_init(&cert->certblob);
|
buffer_init(&cert->certblob);
|
||||||
buffer_init(&cert->constraints);
|
buffer_init(&cert->critical);
|
||||||
|
buffer_init(&cert->extensions);
|
||||||
cert->key_id = NULL;
|
cert->key_id = NULL;
|
||||||
cert->principals = NULL;
|
cert->principals = NULL;
|
||||||
cert->signature_key = NULL;
|
cert->signature_key = NULL;
|
||||||
@ -82,6 +83,7 @@ key_new(int type)
|
|||||||
switch (k->type) {
|
switch (k->type) {
|
||||||
case KEY_RSA1:
|
case KEY_RSA1:
|
||||||
case KEY_RSA:
|
case KEY_RSA:
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
if ((rsa = RSA_new()) == NULL)
|
if ((rsa = RSA_new()) == NULL)
|
||||||
fatal("key_new: RSA_new failed");
|
fatal("key_new: RSA_new failed");
|
||||||
@ -92,6 +94,7 @@ key_new(int type)
|
|||||||
k->rsa = rsa;
|
k->rsa = rsa;
|
||||||
break;
|
break;
|
||||||
case KEY_DSA:
|
case KEY_DSA:
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT:
|
||||||
if ((dsa = DSA_new()) == NULL)
|
if ((dsa = DSA_new()) == NULL)
|
||||||
fatal("key_new: DSA_new failed");
|
fatal("key_new: DSA_new failed");
|
||||||
@ -124,6 +127,7 @@ key_add_private(Key *k)
|
|||||||
switch (k->type) {
|
switch (k->type) {
|
||||||
case KEY_RSA1:
|
case KEY_RSA1:
|
||||||
case KEY_RSA:
|
case KEY_RSA:
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
if ((k->rsa->d = BN_new()) == NULL)
|
if ((k->rsa->d = BN_new()) == NULL)
|
||||||
fatal("key_new_private: BN_new failed");
|
fatal("key_new_private: BN_new failed");
|
||||||
@ -139,6 +143,7 @@ key_add_private(Key *k)
|
|||||||
fatal("key_new_private: BN_new failed");
|
fatal("key_new_private: BN_new failed");
|
||||||
break;
|
break;
|
||||||
case KEY_DSA:
|
case KEY_DSA:
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT:
|
||||||
if ((k->dsa->priv_key = BN_new()) == NULL)
|
if ((k->dsa->priv_key = BN_new()) == NULL)
|
||||||
fatal("key_new_private: BN_new failed");
|
fatal("key_new_private: BN_new failed");
|
||||||
@ -165,7 +170,8 @@ cert_free(struct KeyCert *cert)
|
|||||||
u_int i;
|
u_int i;
|
||||||
|
|
||||||
buffer_free(&cert->certblob);
|
buffer_free(&cert->certblob);
|
||||||
buffer_free(&cert->constraints);
|
buffer_free(&cert->critical);
|
||||||
|
buffer_free(&cert->extensions);
|
||||||
if (cert->key_id != NULL)
|
if (cert->key_id != NULL)
|
||||||
xfree(cert->key_id);
|
xfree(cert->key_id);
|
||||||
for (i = 0; i < cert->nprincipals; i++)
|
for (i = 0; i < cert->nprincipals; i++)
|
||||||
@ -184,12 +190,14 @@ key_free(Key *k)
|
|||||||
switch (k->type) {
|
switch (k->type) {
|
||||||
case KEY_RSA1:
|
case KEY_RSA1:
|
||||||
case KEY_RSA:
|
case KEY_RSA:
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
if (k->rsa != NULL)
|
if (k->rsa != NULL)
|
||||||
RSA_free(k->rsa);
|
RSA_free(k->rsa);
|
||||||
k->rsa = NULL;
|
k->rsa = NULL;
|
||||||
break;
|
break;
|
||||||
case KEY_DSA:
|
case KEY_DSA:
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT:
|
||||||
if (k->dsa != NULL)
|
if (k->dsa != NULL)
|
||||||
DSA_free(k->dsa);
|
DSA_free(k->dsa);
|
||||||
@ -238,11 +246,13 @@ key_equal_public(const Key *a, const Key *b)
|
|||||||
|
|
||||||
switch (a->type) {
|
switch (a->type) {
|
||||||
case KEY_RSA1:
|
case KEY_RSA1:
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
case KEY_RSA:
|
case KEY_RSA:
|
||||||
return a->rsa != NULL && b->rsa != NULL &&
|
return a->rsa != NULL && b->rsa != NULL &&
|
||||||
BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
|
BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
|
||||||
BN_cmp(a->rsa->n, b->rsa->n) == 0;
|
BN_cmp(a->rsa->n, b->rsa->n) == 0;
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT:
|
||||||
case KEY_DSA:
|
case KEY_DSA:
|
||||||
return a->dsa != NULL && b->dsa != NULL &&
|
return a->dsa != NULL && b->dsa != NULL &&
|
||||||
@ -304,6 +314,8 @@ key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length)
|
|||||||
case KEY_RSA:
|
case KEY_RSA:
|
||||||
key_to_blob(k, &blob, &len);
|
key_to_blob(k, &blob, &len);
|
||||||
break;
|
break;
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT:
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
/* We want a fingerprint of the _key_ not of the cert */
|
/* We want a fingerprint of the _key_ not of the cert */
|
||||||
@ -631,6 +643,8 @@ key_read(Key *ret, char **cpp)
|
|||||||
case KEY_UNSPEC:
|
case KEY_UNSPEC:
|
||||||
case KEY_RSA:
|
case KEY_RSA:
|
||||||
case KEY_DSA:
|
case KEY_DSA:
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT:
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
space = strchr(cp, ' ');
|
space = strchr(cp, ' ');
|
||||||
@ -757,11 +771,13 @@ key_write(const Key *key, FILE *f)
|
|||||||
error("key_write: failed for RSA key");
|
error("key_write: failed for RSA key");
|
||||||
return 0;
|
return 0;
|
||||||
case KEY_DSA:
|
case KEY_DSA:
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT:
|
||||||
if (key->dsa == NULL)
|
if (key->dsa == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
case KEY_RSA:
|
case KEY_RSA:
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
if (key->rsa == NULL)
|
if (key->rsa == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
@ -793,6 +809,10 @@ key_type(const Key *k)
|
|||||||
return "RSA";
|
return "RSA";
|
||||||
case KEY_DSA:
|
case KEY_DSA:
|
||||||
return "DSA";
|
return "DSA";
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
|
return "RSA-CERT-V00";
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
|
return "DSA-CERT-V00";
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
return "RSA-CERT";
|
return "RSA-CERT";
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT:
|
||||||
@ -822,10 +842,14 @@ key_ssh_name(const Key *k)
|
|||||||
return "ssh-rsa";
|
return "ssh-rsa";
|
||||||
case KEY_DSA:
|
case KEY_DSA:
|
||||||
return "ssh-dss";
|
return "ssh-dss";
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT_V00:
|
||||||
return "ssh-rsa-cert-v00@openssh.com";
|
return "ssh-rsa-cert-v00@openssh.com";
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT_V00:
|
||||||
return "ssh-dss-cert-v00@openssh.com";
|
return "ssh-dss-cert-v00@openssh.com";
|
||||||
|
case KEY_RSA_CERT:
|
||||||
|
return "ssh-rsa-cert-v01@openssh.com";
|
||||||
|
case KEY_DSA_CERT:
|
||||||
|
return "ssh-dss-cert-v01@openssh.com";
|
||||||
}
|
}
|
||||||
return "ssh-unknown";
|
return "ssh-unknown";
|
||||||
}
|
}
|
||||||
@ -836,9 +860,11 @@ key_size(const Key *k)
|
|||||||
switch (k->type) {
|
switch (k->type) {
|
||||||
case KEY_RSA1:
|
case KEY_RSA1:
|
||||||
case KEY_RSA:
|
case KEY_RSA:
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
return BN_num_bits(k->rsa->n);
|
return BN_num_bits(k->rsa->n);
|
||||||
case KEY_DSA:
|
case KEY_DSA:
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT:
|
||||||
return BN_num_bits(k->dsa->p);
|
return BN_num_bits(k->dsa->p);
|
||||||
}
|
}
|
||||||
@ -882,6 +908,8 @@ key_generate(int type, u_int bits)
|
|||||||
case KEY_RSA1:
|
case KEY_RSA1:
|
||||||
k->rsa = rsa_generate_private_key(bits);
|
k->rsa = rsa_generate_private_key(bits);
|
||||||
break;
|
break;
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT:
|
||||||
fatal("key_generate: cert keys cannot be generated directly");
|
fatal("key_generate: cert keys cannot be generated directly");
|
||||||
@ -912,9 +940,12 @@ key_cert_copy(const Key *from_key, struct Key *to_key)
|
|||||||
buffer_append(&to->certblob, buffer_ptr(&from->certblob),
|
buffer_append(&to->certblob, buffer_ptr(&from->certblob),
|
||||||
buffer_len(&from->certblob));
|
buffer_len(&from->certblob));
|
||||||
|
|
||||||
buffer_append(&to->constraints, buffer_ptr(&from->constraints),
|
buffer_append(&to->critical,
|
||||||
buffer_len(&from->constraints));
|
buffer_ptr(&from->critical), buffer_len(&from->critical));
|
||||||
|
buffer_append(&to->extensions,
|
||||||
|
buffer_ptr(&from->extensions), buffer_len(&from->extensions));
|
||||||
|
|
||||||
|
to->serial = from->serial;
|
||||||
to->type = from->type;
|
to->type = from->type;
|
||||||
to->key_id = from->key_id == NULL ? NULL : xstrdup(from->key_id);
|
to->key_id = from->key_id == NULL ? NULL : xstrdup(from->key_id);
|
||||||
to->valid_after = from->valid_after;
|
to->valid_after = from->valid_after;
|
||||||
@ -940,6 +971,7 @@ key_from_private(const Key *k)
|
|||||||
Key *n = NULL;
|
Key *n = NULL;
|
||||||
switch (k->type) {
|
switch (k->type) {
|
||||||
case KEY_DSA:
|
case KEY_DSA:
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT:
|
||||||
n = key_new(k->type);
|
n = key_new(k->type);
|
||||||
if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) ||
|
if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) ||
|
||||||
@ -950,6 +982,7 @@ key_from_private(const Key *k)
|
|||||||
break;
|
break;
|
||||||
case KEY_RSA:
|
case KEY_RSA:
|
||||||
case KEY_RSA1:
|
case KEY_RSA1:
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
n = key_new(k->type);
|
n = key_new(k->type);
|
||||||
if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) ||
|
if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) ||
|
||||||
@ -979,8 +1012,12 @@ key_type_from_name(char *name)
|
|||||||
} else if (strcmp(name, "ssh-dss") == 0) {
|
} else if (strcmp(name, "ssh-dss") == 0) {
|
||||||
return KEY_DSA;
|
return KEY_DSA;
|
||||||
} else if (strcmp(name, "ssh-rsa-cert-v00@openssh.com") == 0) {
|
} else if (strcmp(name, "ssh-rsa-cert-v00@openssh.com") == 0) {
|
||||||
return KEY_RSA_CERT;
|
return KEY_RSA_CERT_V00;
|
||||||
} else if (strcmp(name, "ssh-dss-cert-v00@openssh.com") == 0) {
|
} else if (strcmp(name, "ssh-dss-cert-v00@openssh.com") == 0) {
|
||||||
|
return KEY_DSA_CERT_V00;
|
||||||
|
} else if (strcmp(name, "ssh-rsa-cert-v01@openssh.com") == 0) {
|
||||||
|
return KEY_RSA_CERT;
|
||||||
|
} else if (strcmp(name, "ssh-dss-cert-v01@openssh.com") == 0) {
|
||||||
return KEY_DSA_CERT;
|
return KEY_DSA_CERT;
|
||||||
}
|
}
|
||||||
debug2("key_type_from_name: unknown key type '%s'", name);
|
debug2("key_type_from_name: unknown key type '%s'", name);
|
||||||
@ -1012,26 +1049,31 @@ key_names_valid2(const char *names)
|
|||||||
static int
|
static int
|
||||||
cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen)
|
cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen)
|
||||||
{
|
{
|
||||||
u_char *principals, *constraints, *sig_key, *sig;
|
u_char *principals, *critical, *exts, *sig_key, *sig;
|
||||||
u_int signed_len, plen, clen, sklen, slen, kidlen;
|
u_int signed_len, plen, clen, sklen, slen, kidlen, elen;
|
||||||
Buffer tmp;
|
Buffer tmp;
|
||||||
char *principal;
|
char *principal;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
int v00 = key->type == KEY_DSA_CERT_V00 ||
|
||||||
|
key->type == KEY_RSA_CERT_V00;
|
||||||
|
|
||||||
buffer_init(&tmp);
|
buffer_init(&tmp);
|
||||||
|
|
||||||
/* Copy the entire key blob for verification and later serialisation */
|
/* Copy the entire key blob for verification and later serialisation */
|
||||||
buffer_append(&key->cert->certblob, blob, blen);
|
buffer_append(&key->cert->certblob, blob, blen);
|
||||||
|
|
||||||
principals = constraints = sig_key = sig = NULL;
|
elen = 0; /* Not touched for v00 certs */
|
||||||
if (buffer_get_int_ret(&key->cert->type, b) != 0 ||
|
principals = exts = critical = sig_key = sig = NULL;
|
||||||
|
if ((!v00 && buffer_get_int64_ret(&key->cert->serial, b) != 0) ||
|
||||||
|
buffer_get_int_ret(&key->cert->type, b) != 0 ||
|
||||||
(key->cert->key_id = buffer_get_string_ret(b, &kidlen)) == NULL ||
|
(key->cert->key_id = buffer_get_string_ret(b, &kidlen)) == NULL ||
|
||||||
(principals = buffer_get_string_ret(b, &plen)) == NULL ||
|
(principals = buffer_get_string_ret(b, &plen)) == NULL ||
|
||||||
buffer_get_int64_ret(&key->cert->valid_after, b) != 0 ||
|
buffer_get_int64_ret(&key->cert->valid_after, b) != 0 ||
|
||||||
buffer_get_int64_ret(&key->cert->valid_before, b) != 0 ||
|
buffer_get_int64_ret(&key->cert->valid_before, b) != 0 ||
|
||||||
(constraints = buffer_get_string_ret(b, &clen)) == NULL ||
|
(critical = buffer_get_string_ret(b, &clen)) == NULL ||
|
||||||
/* skip nonce */ buffer_get_string_ptr_ret(b, NULL) == NULL ||
|
(!v00 && (exts = buffer_get_string_ret(b, &elen)) == NULL) ||
|
||||||
/* skip reserved */ buffer_get_string_ptr_ret(b, NULL) == NULL ||
|
(v00 && buffer_get_string_ptr_ret(b, NULL) == NULL) || /* nonce */
|
||||||
|
buffer_get_string_ptr_ret(b, NULL) == NULL || /* reserved */
|
||||||
(sig_key = buffer_get_string_ret(b, &sklen)) == NULL) {
|
(sig_key = buffer_get_string_ret(b, &sklen)) == NULL) {
|
||||||
error("%s: parse error", __func__);
|
error("%s: parse error", __func__);
|
||||||
goto out;
|
goto out;
|
||||||
@ -1078,13 +1120,25 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen)
|
|||||||
|
|
||||||
buffer_clear(&tmp);
|
buffer_clear(&tmp);
|
||||||
|
|
||||||
buffer_append(&key->cert->constraints, constraints, clen);
|
buffer_append(&key->cert->critical, critical, clen);
|
||||||
buffer_append(&tmp, constraints, clen);
|
buffer_append(&tmp, critical, clen);
|
||||||
/* validate structure */
|
/* validate structure */
|
||||||
while (buffer_len(&tmp) != 0) {
|
while (buffer_len(&tmp) != 0) {
|
||||||
if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL ||
|
if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL ||
|
||||||
buffer_get_string_ptr_ret(&tmp, NULL) == NULL) {
|
buffer_get_string_ptr_ret(&tmp, NULL) == NULL) {
|
||||||
error("%s: Constraints data invalid", __func__);
|
error("%s: critical option data invalid", __func__);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer_clear(&tmp);
|
||||||
|
|
||||||
|
buffer_append(&key->cert->extensions, exts, elen);
|
||||||
|
buffer_append(&tmp, exts, elen);
|
||||||
|
/* validate structure */
|
||||||
|
while (buffer_len(&tmp) != 0) {
|
||||||
|
if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL ||
|
||||||
|
buffer_get_string_ptr_ret(&tmp, NULL) == NULL) {
|
||||||
|
error("%s: extension data invalid", __func__);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1121,8 +1175,10 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen)
|
|||||||
buffer_free(&tmp);
|
buffer_free(&tmp);
|
||||||
if (principals != NULL)
|
if (principals != NULL)
|
||||||
xfree(principals);
|
xfree(principals);
|
||||||
if (constraints != NULL)
|
if (critical != NULL)
|
||||||
xfree(constraints);
|
xfree(critical);
|
||||||
|
if (exts != NULL)
|
||||||
|
xfree(exts);
|
||||||
if (sig_key != NULL)
|
if (sig_key != NULL)
|
||||||
xfree(sig_key);
|
xfree(sig_key);
|
||||||
if (sig != NULL)
|
if (sig != NULL)
|
||||||
@ -1151,8 +1207,11 @@ key_from_blob(const u_char *blob, u_int blen)
|
|||||||
type = key_type_from_name(ktype);
|
type = key_type_from_name(ktype);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case KEY_RSA:
|
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
|
(void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case KEY_RSA:
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
key = key_new(type);
|
key = key_new(type);
|
||||||
if (buffer_get_bignum2_ret(&b, key->rsa->e) == -1 ||
|
if (buffer_get_bignum2_ret(&b, key->rsa->e) == -1 ||
|
||||||
buffer_get_bignum2_ret(&b, key->rsa->n) == -1) {
|
buffer_get_bignum2_ret(&b, key->rsa->n) == -1) {
|
||||||
@ -1166,8 +1225,11 @@ key_from_blob(const u_char *blob, u_int blen)
|
|||||||
RSA_print_fp(stderr, key->rsa, 8);
|
RSA_print_fp(stderr, key->rsa, 8);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case KEY_DSA:
|
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT:
|
||||||
|
(void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case KEY_DSA:
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
key = key_new(type);
|
key = key_new(type);
|
||||||
if (buffer_get_bignum2_ret(&b, key->dsa->p) == -1 ||
|
if (buffer_get_bignum2_ret(&b, key->dsa->p) == -1 ||
|
||||||
buffer_get_bignum2_ret(&b, key->dsa->q) == -1 ||
|
buffer_get_bignum2_ret(&b, key->dsa->q) == -1 ||
|
||||||
@ -1213,6 +1275,8 @@ key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
|
|||||||
}
|
}
|
||||||
buffer_init(&b);
|
buffer_init(&b);
|
||||||
switch (key->type) {
|
switch (key->type) {
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT:
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
/* Use the existing blob */
|
/* Use the existing blob */
|
||||||
@ -1255,9 +1319,11 @@ key_sign(
|
|||||||
const u_char *data, u_int datalen)
|
const u_char *data, u_int datalen)
|
||||||
{
|
{
|
||||||
switch (key->type) {
|
switch (key->type) {
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT:
|
||||||
case KEY_DSA:
|
case KEY_DSA:
|
||||||
return ssh_dss_sign(key, sigp, lenp, data, datalen);
|
return ssh_dss_sign(key, sigp, lenp, data, datalen);
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
case KEY_RSA:
|
case KEY_RSA:
|
||||||
return ssh_rsa_sign(key, sigp, lenp, data, datalen);
|
return ssh_rsa_sign(key, sigp, lenp, data, datalen);
|
||||||
@ -1281,9 +1347,11 @@ key_verify(
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
switch (key->type) {
|
switch (key->type) {
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT:
|
||||||
case KEY_DSA:
|
case KEY_DSA:
|
||||||
return ssh_dss_verify(key, signature, signaturelen, data, datalen);
|
return ssh_dss_verify(key, signature, signaturelen, data, datalen);
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
case KEY_RSA:
|
case KEY_RSA:
|
||||||
return ssh_rsa_verify(key, signature, signaturelen, data, datalen);
|
return ssh_rsa_verify(key, signature, signaturelen, data, datalen);
|
||||||
@ -1306,6 +1374,7 @@ key_demote(const Key *k)
|
|||||||
pk->rsa = NULL;
|
pk->rsa = NULL;
|
||||||
|
|
||||||
switch (k->type) {
|
switch (k->type) {
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
key_cert_copy(k, pk);
|
key_cert_copy(k, pk);
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
@ -1318,6 +1387,7 @@ key_demote(const Key *k)
|
|||||||
if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL)
|
if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL)
|
||||||
fatal("key_demote: BN_dup failed");
|
fatal("key_demote: BN_dup failed");
|
||||||
break;
|
break;
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT:
|
||||||
key_cert_copy(k, pk);
|
key_cert_copy(k, pk);
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
@ -1344,8 +1414,17 @@ key_demote(const Key *k)
|
|||||||
int
|
int
|
||||||
key_is_cert(const Key *k)
|
key_is_cert(const Key *k)
|
||||||
{
|
{
|
||||||
return k != NULL &&
|
if (k == NULL)
|
||||||
(k->type == KEY_RSA_CERT || k->type == KEY_DSA_CERT);
|
return 0;
|
||||||
|
switch (k->type) {
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
|
case KEY_RSA_CERT:
|
||||||
|
case KEY_DSA_CERT:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the cert-less equivalent to a certified key type */
|
/* Return the cert-less equivalent to a certified key type */
|
||||||
@ -1353,8 +1432,10 @@ int
|
|||||||
key_type_plain(int type)
|
key_type_plain(int type)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
return KEY_RSA;
|
return KEY_RSA;
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT:
|
||||||
return KEY_DSA;
|
return KEY_DSA;
|
||||||
default:
|
default:
|
||||||
@ -1364,16 +1445,16 @@ key_type_plain(int type)
|
|||||||
|
|
||||||
/* Convert a KEY_RSA or KEY_DSA to their _CERT equivalent */
|
/* Convert a KEY_RSA or KEY_DSA to their _CERT equivalent */
|
||||||
int
|
int
|
||||||
key_to_certified(Key *k)
|
key_to_certified(Key *k, int legacy)
|
||||||
{
|
{
|
||||||
switch (k->type) {
|
switch (k->type) {
|
||||||
case KEY_RSA:
|
case KEY_RSA:
|
||||||
k->cert = cert_new();
|
k->cert = cert_new();
|
||||||
k->type = KEY_RSA_CERT;
|
k->type = legacy ? KEY_RSA_CERT_V00 : KEY_RSA_CERT;
|
||||||
return 0;
|
return 0;
|
||||||
case KEY_DSA:
|
case KEY_DSA:
|
||||||
k->cert = cert_new();
|
k->cert = cert_new();
|
||||||
k->type = KEY_DSA_CERT;
|
k->type = legacy ? KEY_DSA_CERT_V00 : KEY_DSA_CERT;
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
error("%s: key has incorrect type %s", __func__, key_type(k));
|
error("%s: key has incorrect type %s", __func__, key_type(k));
|
||||||
@ -1386,10 +1467,12 @@ int
|
|||||||
key_drop_cert(Key *k)
|
key_drop_cert(Key *k)
|
||||||
{
|
{
|
||||||
switch (k->type) {
|
switch (k->type) {
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
cert_free(k->cert);
|
cert_free(k->cert);
|
||||||
k->type = KEY_RSA;
|
k->type = KEY_RSA;
|
||||||
return 0;
|
return 0;
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT:
|
||||||
cert_free(k->cert);
|
cert_free(k->cert);
|
||||||
k->type = KEY_DSA;
|
k->type = KEY_DSA;
|
||||||
@ -1430,13 +1513,21 @@ key_certify(Key *k, Key *ca)
|
|||||||
buffer_clear(&k->cert->certblob);
|
buffer_clear(&k->cert->certblob);
|
||||||
buffer_put_cstring(&k->cert->certblob, key_ssh_name(k));
|
buffer_put_cstring(&k->cert->certblob, key_ssh_name(k));
|
||||||
|
|
||||||
|
/* -v01 certs put nonce first */
|
||||||
|
if (k->type == KEY_DSA_CERT || k->type == KEY_RSA_CERT) {
|
||||||
|
arc4random_buf(&nonce, sizeof(nonce));
|
||||||
|
buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce));
|
||||||
|
}
|
||||||
|
|
||||||
switch (k->type) {
|
switch (k->type) {
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT:
|
||||||
buffer_put_bignum2(&k->cert->certblob, k->dsa->p);
|
buffer_put_bignum2(&k->cert->certblob, k->dsa->p);
|
||||||
buffer_put_bignum2(&k->cert->certblob, k->dsa->q);
|
buffer_put_bignum2(&k->cert->certblob, k->dsa->q);
|
||||||
buffer_put_bignum2(&k->cert->certblob, k->dsa->g);
|
buffer_put_bignum2(&k->cert->certblob, k->dsa->g);
|
||||||
buffer_put_bignum2(&k->cert->certblob, k->dsa->pub_key);
|
buffer_put_bignum2(&k->cert->certblob, k->dsa->pub_key);
|
||||||
break;
|
break;
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
buffer_put_bignum2(&k->cert->certblob, k->rsa->e);
|
buffer_put_bignum2(&k->cert->certblob, k->rsa->e);
|
||||||
buffer_put_bignum2(&k->cert->certblob, k->rsa->n);
|
buffer_put_bignum2(&k->cert->certblob, k->rsa->n);
|
||||||
@ -1448,6 +1539,10 @@ key_certify(Key *k, Key *ca)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -v01 certs have a serial number next */
|
||||||
|
if (k->type == KEY_DSA_CERT || k->type == KEY_RSA_CERT)
|
||||||
|
buffer_put_int64(&k->cert->certblob, k->cert->serial);
|
||||||
|
|
||||||
buffer_put_int(&k->cert->certblob, k->cert->type);
|
buffer_put_int(&k->cert->certblob, k->cert->type);
|
||||||
buffer_put_cstring(&k->cert->certblob, k->cert->key_id);
|
buffer_put_cstring(&k->cert->certblob, k->cert->key_id);
|
||||||
|
|
||||||
@ -1461,11 +1556,19 @@ key_certify(Key *k, Key *ca)
|
|||||||
buffer_put_int64(&k->cert->certblob, k->cert->valid_after);
|
buffer_put_int64(&k->cert->certblob, k->cert->valid_after);
|
||||||
buffer_put_int64(&k->cert->certblob, k->cert->valid_before);
|
buffer_put_int64(&k->cert->certblob, k->cert->valid_before);
|
||||||
buffer_put_string(&k->cert->certblob,
|
buffer_put_string(&k->cert->certblob,
|
||||||
buffer_ptr(&k->cert->constraints),
|
buffer_ptr(&k->cert->critical), buffer_len(&k->cert->critical));
|
||||||
buffer_len(&k->cert->constraints));
|
|
||||||
|
/* -v01 certs have non-critical options here */
|
||||||
|
if (k->type == KEY_DSA_CERT || k->type == KEY_RSA_CERT) {
|
||||||
|
buffer_put_string(&k->cert->certblob,
|
||||||
|
buffer_ptr(&k->cert->extensions),
|
||||||
|
buffer_len(&k->cert->extensions));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -v00 certs put the nonce at the end */
|
||||||
|
if (k->type == KEY_DSA_CERT_V00 || k->type == KEY_RSA_CERT_V00)
|
||||||
|
buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce));
|
||||||
|
|
||||||
arc4random_buf(&nonce, sizeof(nonce));
|
|
||||||
buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce));
|
|
||||||
buffer_put_string(&k->cert->certblob, NULL, 0); /* reserved */
|
buffer_put_string(&k->cert->certblob, NULL, 0); /* reserved */
|
||||||
buffer_put_string(&k->cert->certblob, ca_blob, ca_len);
|
buffer_put_string(&k->cert->certblob, ca_blob, ca_len);
|
||||||
xfree(ca_blob);
|
xfree(ca_blob);
|
||||||
@ -1536,3 +1639,15 @@ key_cert_check_authority(const Key *k, int want_host, int require_principal,
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
key_cert_is_legacy(Key *k)
|
||||||
|
{
|
||||||
|
switch (k->type) {
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
11
key.h
11
key.h
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: key.h,v 1.29 2010/03/15 19:40:02 stevesk Exp $ */
|
/* $OpenBSD: key.h,v 1.30 2010/04/16 01:47:26 djm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||||
@ -37,6 +37,8 @@ enum types {
|
|||||||
KEY_DSA,
|
KEY_DSA,
|
||||||
KEY_RSA_CERT,
|
KEY_RSA_CERT,
|
||||||
KEY_DSA_CERT,
|
KEY_DSA_CERT,
|
||||||
|
KEY_RSA_CERT_V00,
|
||||||
|
KEY_DSA_CERT_V00,
|
||||||
KEY_UNSPEC
|
KEY_UNSPEC
|
||||||
};
|
};
|
||||||
enum fp_type {
|
enum fp_type {
|
||||||
@ -56,11 +58,13 @@ enum fp_rep {
|
|||||||
struct KeyCert {
|
struct KeyCert {
|
||||||
Buffer certblob; /* Kept around for use on wire */
|
Buffer certblob; /* Kept around for use on wire */
|
||||||
u_int type; /* SSH2_CERT_TYPE_USER or SSH2_CERT_TYPE_HOST */
|
u_int type; /* SSH2_CERT_TYPE_USER or SSH2_CERT_TYPE_HOST */
|
||||||
|
u_int64_t serial;
|
||||||
char *key_id;
|
char *key_id;
|
||||||
u_int nprincipals;
|
u_int nprincipals;
|
||||||
char **principals;
|
char **principals;
|
||||||
u_int64_t valid_after, valid_before;
|
u_int64_t valid_after, valid_before;
|
||||||
Buffer constraints;
|
Buffer critical;
|
||||||
|
Buffer extensions;
|
||||||
Key *signature_key;
|
Key *signature_key;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -92,12 +96,13 @@ Key *key_from_private(const Key *);
|
|||||||
int key_type_from_name(char *);
|
int key_type_from_name(char *);
|
||||||
int key_is_cert(const Key *);
|
int key_is_cert(const Key *);
|
||||||
int key_type_plain(int);
|
int key_type_plain(int);
|
||||||
int key_to_certified(Key *);
|
int key_to_certified(Key *, int);
|
||||||
int key_drop_cert(Key *);
|
int key_drop_cert(Key *);
|
||||||
int key_certify(Key *, Key *);
|
int key_certify(Key *, Key *);
|
||||||
void key_cert_copy(const Key *, struct Key *);
|
void key_cert_copy(const Key *, struct Key *);
|
||||||
int key_cert_check_authority(const Key *, int, int, const char *,
|
int key_cert_check_authority(const Key *, int, int, const char *,
|
||||||
const char **);
|
const char **);
|
||||||
|
int key_cert_is_legacy(Key *);
|
||||||
|
|
||||||
Key *key_from_blob(const u_char *, u_int);
|
Key *key_from_blob(const u_char *, u_int);
|
||||||
int key_to_blob(const Key *, u_char **, u_int *);
|
int key_to_blob(const Key *, u_char **, u_int *);
|
||||||
|
11
myproposal.h
11
myproposal.h
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: myproposal.h,v 1.24 2010/02/26 20:29:54 djm Exp $ */
|
/* $OpenBSD: myproposal.h,v 1.25 2010/04/16 01:47:26 djm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||||
@ -40,9 +40,12 @@
|
|||||||
"diffie-hellman-group1-sha1"
|
"diffie-hellman-group1-sha1"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define KEX_DEFAULT_PK_ALG "ssh-rsa-cert-v00@openssh.com," \
|
#define KEX_DEFAULT_PK_ALG \
|
||||||
"ssh-dss-cert-v00@openssh.com," \
|
"ssh-rsa-cert-v01@openssh.com," \
|
||||||
"ssh-rsa,ssh-dss"
|
"ssh-dss-cert-v01@openssh.com," \
|
||||||
|
"ssh-rsa-cert-v00@openssh.com," \
|
||||||
|
"ssh-dss-cert-v00@openssh.com," \
|
||||||
|
"ssh-rsa,ssh-dss"
|
||||||
|
|
||||||
#define KEX_DEFAULT_ENCRYPT \
|
#define KEX_DEFAULT_ENCRYPT \
|
||||||
"aes128-ctr,aes192-ctr,aes256-ctr," \
|
"aes128-ctr,aes192-ctr,aes256-ctr," \
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: ssh-add.c,v 1.94 2010/03/01 11:07:06 otto Exp $ */
|
/* $OpenBSD: ssh-add.c,v 1.95 2010/04/16 01:47:26 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -204,7 +204,7 @@ add_file(AuthenticationConnection *ac, const char *filename)
|
|||||||
xasprintf(&certpath, "%s-cert.pub", filename);
|
xasprintf(&certpath, "%s-cert.pub", filename);
|
||||||
if ((cert = key_load_public(certpath, NULL)) != NULL) {
|
if ((cert = key_load_public(certpath, NULL)) != NULL) {
|
||||||
/* Graft with private bits */
|
/* Graft with private bits */
|
||||||
if (key_to_certified(private) != 0)
|
if (key_to_certified(private, key_cert_is_legacy(cert)) != 0)
|
||||||
fatal("%s: key_to_certified failed", __func__);
|
fatal("%s: key_to_certified failed", __func__);
|
||||||
key_cert_copy(cert, private);
|
key_cert_copy(cert, private);
|
||||||
key_free(cert);
|
key_free(cert);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: ssh-agent.c,v 1.165 2010/02/26 20:29:54 djm Exp $ */
|
/* $OpenBSD: ssh-agent.c,v 1.166 2010/04/16 01:47:26 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -500,6 +500,7 @@ process_add_identity(SocketEntry *e, int version)
|
|||||||
buffer_get_bignum2(&e->request, k->dsa->pub_key);
|
buffer_get_bignum2(&e->request, k->dsa->pub_key);
|
||||||
buffer_get_bignum2(&e->request, k->dsa->priv_key);
|
buffer_get_bignum2(&e->request, k->dsa->priv_key);
|
||||||
break;
|
break;
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT:
|
||||||
cert = buffer_get_string(&e->request, &len);
|
cert = buffer_get_string(&e->request, &len);
|
||||||
if ((k = key_from_blob(cert, len)) == NULL)
|
if ((k = key_from_blob(cert, len)) == NULL)
|
||||||
@ -520,6 +521,7 @@ process_add_identity(SocketEntry *e, int version)
|
|||||||
/* Generate additional parameters */
|
/* Generate additional parameters */
|
||||||
rsa_generate_additional_parameters(k->rsa);
|
rsa_generate_additional_parameters(k->rsa);
|
||||||
break;
|
break;
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
cert = buffer_get_string(&e->request, &len);
|
cert = buffer_get_string(&e->request, &len);
|
||||||
if ((k = key_from_blob(cert, len)) == NULL)
|
if ((k = key_from_blob(cert, len)) == NULL)
|
||||||
@ -540,6 +542,7 @@ process_add_identity(SocketEntry *e, int version)
|
|||||||
/* enable blinding */
|
/* enable blinding */
|
||||||
switch (k->type) {
|
switch (k->type) {
|
||||||
case KEY_RSA:
|
case KEY_RSA:
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
case KEY_RSA1:
|
case KEY_RSA1:
|
||||||
if (RSA_blinding_on(k->rsa, NULL) != 1) {
|
if (RSA_blinding_on(k->rsa, NULL) != 1) {
|
||||||
|
12
ssh-dss.c
12
ssh-dss.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: ssh-dss.c,v 1.25 2010/02/26 20:29:54 djm Exp $ */
|
/* $OpenBSD: ssh-dss.c,v 1.26 2010/04/16 01:47:26 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||||
*
|
*
|
||||||
@ -53,9 +53,8 @@ ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp,
|
|||||||
u_int rlen, slen, len, dlen;
|
u_int rlen, slen, len, dlen;
|
||||||
Buffer b;
|
Buffer b;
|
||||||
|
|
||||||
if (key == NULL ||
|
if (key == NULL || key->dsa == NULL || (key->type != KEY_DSA &&
|
||||||
(key->type != KEY_DSA && key->type != KEY_DSA_CERT) ||
|
key->type != KEY_DSA_CERT && key->type != KEY_DSA_CERT_V00)) {
|
||||||
key->dsa == NULL) {
|
|
||||||
error("ssh_dss_sign: no DSA key");
|
error("ssh_dss_sign: no DSA key");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -118,9 +117,8 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen,
|
|||||||
int rlen, ret;
|
int rlen, ret;
|
||||||
Buffer b;
|
Buffer b;
|
||||||
|
|
||||||
if (key == NULL ||
|
if (key == NULL || key->dsa == NULL || (key->type != KEY_DSA &&
|
||||||
(key->type != KEY_DSA && key->type != KEY_DSA_CERT) ||
|
key->type != KEY_DSA_CERT && key->type != KEY_DSA_CERT_V00)) {
|
||||||
key->dsa == NULL) {
|
|
||||||
error("ssh_dss_verify: no DSA key");
|
error("ssh_dss_verify: no DSA key");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
27
ssh-keygen.1
27
ssh-keygen.1
@ -1,4 +1,4 @@
|
|||||||
.\" $OpenBSD: ssh-keygen.1,v 1.92 2010/03/13 23:38:13 jmc Exp $
|
.\" $OpenBSD: ssh-keygen.1,v 1.93 2010/04/16 01:47:26 djm Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" -*- nroff -*-
|
.\" -*- nroff -*-
|
||||||
.\"
|
.\"
|
||||||
@ -37,7 +37,7 @@
|
|||||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: March 13 2010 $
|
.Dd $Mdocdate: April 16 2010 $
|
||||||
.Dt SSH-KEYGEN 1
|
.Dt SSH-KEYGEN 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -110,8 +110,9 @@
|
|||||||
.Fl I Ar certificate_identity
|
.Fl I Ar certificate_identity
|
||||||
.Op Fl h
|
.Op Fl h
|
||||||
.Op Fl n Ar principals
|
.Op Fl n Ar principals
|
||||||
.Op Fl O Ar constraint
|
.Op Fl O Ar option
|
||||||
.Op Fl V Ar validity_interval
|
.Op Fl V Ar validity_interval
|
||||||
|
.Op Fl z Ar serial_number
|
||||||
.Ar
|
.Ar
|
||||||
.Nm ssh-keygen
|
.Nm ssh-keygen
|
||||||
.Fl L
|
.Fl L
|
||||||
@ -299,13 +300,13 @@ Multiple principals may be specified, separated by commas.
|
|||||||
Please see the
|
Please see the
|
||||||
.Sx CERTIFICATES
|
.Sx CERTIFICATES
|
||||||
section for details.
|
section for details.
|
||||||
.It Fl O Ar constraint
|
.It Fl O Ar option
|
||||||
Specify a certificate constraint when signing a key.
|
Specify a certificate option when signing a key.
|
||||||
This option may be specified multiple times.
|
This option may be specified multiple times.
|
||||||
Please see the
|
Please see the
|
||||||
.Sx CERTIFICATES
|
.Sx CERTIFICATES
|
||||||
section for details.
|
section for details.
|
||||||
The constraints that are valid for user certificates are:
|
The options that are valid for user certificates are:
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
.It Ic clear
|
.It Ic clear
|
||||||
Clear all enabled permissions.
|
Clear all enabled permissions.
|
||||||
@ -355,7 +356,7 @@ is a comma-separated list of one or more address/netmask pairs in CIDR
|
|||||||
format.
|
format.
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
At present, no constraints are valid for host keys.
|
At present, no options are valid for host keys.
|
||||||
.It Fl P Ar passphrase
|
.It Fl P Ar passphrase
|
||||||
Provides the (old) passphrase.
|
Provides the (old) passphrase.
|
||||||
.It Fl p
|
.It Fl p
|
||||||
@ -441,6 +442,10 @@ Specify desired generator when testing candidate moduli for DH-GEX.
|
|||||||
.It Fl y
|
.It Fl y
|
||||||
This option will read a private
|
This option will read a private
|
||||||
OpenSSH format file and print an OpenSSH public key to stdout.
|
OpenSSH format file and print an OpenSSH public key to stdout.
|
||||||
|
.It Fl z Ar serial_number
|
||||||
|
Specifies a serial number to be embedded in the certificate to distinguish
|
||||||
|
this certificate from others from the same CA.
|
||||||
|
The default serial number is zero.
|
||||||
.El
|
.El
|
||||||
.Sh MODULI GENERATION
|
.Sh MODULI GENERATION
|
||||||
.Nm
|
.Nm
|
||||||
@ -501,7 +506,7 @@ that both ends of a connection share common moduli.
|
|||||||
supports signing of keys to produce certificates that may be used for
|
supports signing of keys to produce certificates that may be used for
|
||||||
user or host authentication.
|
user or host authentication.
|
||||||
Certificates consist of a public key, some identity information, zero or
|
Certificates consist of a public key, some identity information, zero or
|
||||||
more principal (user or host) names and an optional set of constraints that
|
more principal (user or host) names and an optional set of options that
|
||||||
are signed by a Certification Authority (CA) key.
|
are signed by a Certification Authority (CA) key.
|
||||||
Clients or servers may then trust only the CA key and verify its signature
|
Clients or servers may then trust only the CA key and verify its signature
|
||||||
on a certificate rather than trusting many user/host keys.
|
on a certificate rather than trusting many user/host keys.
|
||||||
@ -541,11 +546,11 @@ To generate a certificate for a specified set of principals:
|
|||||||
.Dl "$ ssh-keygen -s ca_key -I key_id -h -n host.domain user_key.pub"
|
.Dl "$ ssh-keygen -s ca_key -I key_id -h -n host.domain user_key.pub"
|
||||||
.Pp
|
.Pp
|
||||||
Additional limitations on the validity and use of user certificates may
|
Additional limitations on the validity and use of user certificates may
|
||||||
be specified through certificate constraints.
|
be specified through certificate options..
|
||||||
A constrained certificate may disable features of the SSH session, may be
|
A certificate option may disable features of the SSH session, may be
|
||||||
valid only when presented from particular source addresses or may
|
valid only when presented from particular source addresses or may
|
||||||
force the use of a specific command.
|
force the use of a specific command.
|
||||||
For a list of valid certificate constraints, see the documentation for the
|
For a list of valid certificate options, see the documentation for the
|
||||||
.Fl O
|
.Fl O
|
||||||
option above.
|
option above.
|
||||||
.Pp
|
.Pp
|
||||||
|
233
ssh-keygen.c
233
ssh-keygen.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: ssh-keygen.c,v 1.185 2010/03/15 19:40:02 stevesk Exp $ */
|
/* $OpenBSD: ssh-keygen.c,v 1.186 2010/04/16 01:47:26 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -105,6 +105,9 @@ char *identity_comment = NULL;
|
|||||||
/* Path to CA key when certifying keys. */
|
/* Path to CA key when certifying keys. */
|
||||||
char *ca_key_path = NULL;
|
char *ca_key_path = NULL;
|
||||||
|
|
||||||
|
/* Certificate serial number */
|
||||||
|
long long cert_serial = 0;
|
||||||
|
|
||||||
/* Key type when certifying */
|
/* Key type when certifying */
|
||||||
u_int cert_key_type = SSH2_CERT_TYPE_USER;
|
u_int cert_key_type = SSH2_CERT_TYPE_USER;
|
||||||
|
|
||||||
@ -118,18 +121,18 @@ char *cert_principals = NULL;
|
|||||||
u_int64_t cert_valid_from = 0;
|
u_int64_t cert_valid_from = 0;
|
||||||
u_int64_t cert_valid_to = ~0ULL;
|
u_int64_t cert_valid_to = ~0ULL;
|
||||||
|
|
||||||
/* Certificate constraints */
|
/* Certificate options */
|
||||||
#define CONSTRAINT_X_FWD (1)
|
#define CRITOPT_X_FWD (1)
|
||||||
#define CONSTRAINT_AGENT_FWD (1<<1)
|
#define CRITOPT_AGENT_FWD (1<<1)
|
||||||
#define CONSTRAINT_PORT_FWD (1<<2)
|
#define CRITOPT_PORT_FWD (1<<2)
|
||||||
#define CONSTRAINT_PTY (1<<3)
|
#define CRITOPT_PTY (1<<3)
|
||||||
#define CONSTRAINT_USER_RC (1<<4)
|
#define CRITOPT_USER_RC (1<<4)
|
||||||
#define CONSTRAINT_DEFAULT (CONSTRAINT_X_FWD|CONSTRAINT_AGENT_FWD| \
|
#define CRITOPT_DEFAULT (CRITOPT_X_FWD|CRITOPT_AGENT_FWD| \
|
||||||
CONSTRAINT_PORT_FWD|CONSTRAINT_PTY| \
|
CRITOPT_PORT_FWD|CRITOPT_PTY| \
|
||||||
CONSTRAINT_USER_RC)
|
CRITOPT_USER_RC)
|
||||||
u_int32_t constraint_flags = CONSTRAINT_DEFAULT;
|
u_int32_t critical_flags = CRITOPT_DEFAULT;
|
||||||
char *constraint_command = NULL;
|
char *critical_command = NULL;
|
||||||
char *constraint_src_addr = NULL;
|
char *critical_src_addr = NULL;
|
||||||
|
|
||||||
/* Dump public key file in format used by real and the original SSH 2 */
|
/* Dump public key file in format used by real and the original SSH 2 */
|
||||||
int convert_to_ssh2 = 0;
|
int convert_to_ssh2 = 0;
|
||||||
@ -161,9 +164,13 @@ ask_filename(struct passwd *pw, const char *prompt)
|
|||||||
case KEY_RSA1:
|
case KEY_RSA1:
|
||||||
name = _PATH_SSH_CLIENT_IDENTITY;
|
name = _PATH_SSH_CLIENT_IDENTITY;
|
||||||
break;
|
break;
|
||||||
|
case KEY_DSA_CERT:
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
case KEY_DSA:
|
case KEY_DSA:
|
||||||
name = _PATH_SSH_CLIENT_ID_DSA;
|
name = _PATH_SSH_CLIENT_ID_DSA;
|
||||||
break;
|
break;
|
||||||
|
case KEY_RSA_CERT:
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
case KEY_RSA:
|
case KEY_RSA:
|
||||||
name = _PATH_SSH_CLIENT_ID_RSA;
|
name = _PATH_SSH_CLIENT_ID_RSA;
|
||||||
break;
|
break;
|
||||||
@ -1104,7 +1111,7 @@ fmt_validity(u_int64_t valid_from, u_int64_t valid_to)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_flag_constraint(Buffer *c, const char *name)
|
add_flag_option(Buffer *c, const char *name)
|
||||||
{
|
{
|
||||||
debug3("%s: %s", __func__, name);
|
debug3("%s: %s", __func__, name);
|
||||||
buffer_put_cstring(c, name);
|
buffer_put_cstring(c, name);
|
||||||
@ -1112,7 +1119,7 @@ add_flag_constraint(Buffer *c, const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_string_constraint(Buffer *c, const char *name, const char *value)
|
add_string_option(Buffer *c, const char *name, const char *value)
|
||||||
{
|
{
|
||||||
Buffer b;
|
Buffer b;
|
||||||
|
|
||||||
@ -1127,24 +1134,23 @@ add_string_constraint(Buffer *c, const char *name, const char *value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
prepare_constraint_buf(Buffer *c)
|
prepare_options_buf(Buffer *c)
|
||||||
{
|
{
|
||||||
|
|
||||||
buffer_clear(c);
|
buffer_clear(c);
|
||||||
if ((constraint_flags & CONSTRAINT_X_FWD) != 0)
|
if ((critical_flags & CRITOPT_X_FWD) != 0)
|
||||||
add_flag_constraint(c, "permit-X11-forwarding");
|
add_flag_option(c, "permit-X11-forwarding");
|
||||||
if ((constraint_flags & CONSTRAINT_AGENT_FWD) != 0)
|
if ((critical_flags & CRITOPT_AGENT_FWD) != 0)
|
||||||
add_flag_constraint(c, "permit-agent-forwarding");
|
add_flag_option(c, "permit-agent-forwarding");
|
||||||
if ((constraint_flags & CONSTRAINT_PORT_FWD) != 0)
|
if ((critical_flags & CRITOPT_PORT_FWD) != 0)
|
||||||
add_flag_constraint(c, "permit-port-forwarding");
|
add_flag_option(c, "permit-port-forwarding");
|
||||||
if ((constraint_flags & CONSTRAINT_PTY) != 0)
|
if ((critical_flags & CRITOPT_PTY) != 0)
|
||||||
add_flag_constraint(c, "permit-pty");
|
add_flag_option(c, "permit-pty");
|
||||||
if ((constraint_flags & CONSTRAINT_USER_RC) != 0)
|
if ((critical_flags & CRITOPT_USER_RC) != 0)
|
||||||
add_flag_constraint(c, "permit-user-rc");
|
add_flag_option(c, "permit-user-rc");
|
||||||
if (constraint_command != NULL)
|
if (critical_command != NULL)
|
||||||
add_string_constraint(c, "force-command", constraint_command);
|
add_string_option(c, "force-command", critical_command);
|
||||||
if (constraint_src_addr != NULL)
|
if (critical_src_addr != NULL)
|
||||||
add_string_constraint(c, "source-address", constraint_src_addr);
|
add_string_option(c, "source-address", critical_src_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1155,12 +1161,32 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
|
|||||||
Key *ca, *public;
|
Key *ca, *public;
|
||||||
char *otmp, *tmp, *cp, *out, *comment, **plist = NULL;
|
char *otmp, *tmp, *cp, *out, *comment, **plist = NULL;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
int v00 = 0; /* legacy keys */
|
||||||
|
|
||||||
tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
|
tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
|
||||||
if ((ca = load_identity(tmp)) == NULL)
|
if ((ca = load_identity(tmp)) == NULL)
|
||||||
fatal("Couldn't load CA key \"%s\"", tmp);
|
fatal("Couldn't load CA key \"%s\"", tmp);
|
||||||
xfree(tmp);
|
xfree(tmp);
|
||||||
|
|
||||||
|
if (key_type_name != NULL) {
|
||||||
|
switch (key_type_from_name(key_type_name)) {
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
|
v00 = 1;
|
||||||
|
break;
|
||||||
|
case KEY_UNSPEC:
|
||||||
|
if (strcasecmp(key_type_name, "v00") == 0) {
|
||||||
|
v00 = 1;
|
||||||
|
break;
|
||||||
|
} else if (strcasecmp(key_type_name, "v01") == 0)
|
||||||
|
break;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "unknown key type %s\n", key_type_name);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
/* Split list of principals */
|
/* Split list of principals */
|
||||||
n = 0;
|
n = 0;
|
||||||
@ -1183,15 +1209,16 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
|
|||||||
__func__, tmp, key_type(public));
|
__func__, tmp, key_type(public));
|
||||||
|
|
||||||
/* Prepare certificate to sign */
|
/* Prepare certificate to sign */
|
||||||
if (key_to_certified(public) != 0)
|
if (key_to_certified(public, v00) != 0)
|
||||||
fatal("Could not upgrade key %s to certificate", tmp);
|
fatal("Could not upgrade key %s to certificate", tmp);
|
||||||
public->cert->type = cert_key_type;
|
public->cert->type = cert_key_type;
|
||||||
|
public->cert->serial = (u_int64_t)cert_serial;
|
||||||
public->cert->key_id = xstrdup(cert_key_id);
|
public->cert->key_id = xstrdup(cert_key_id);
|
||||||
public->cert->nprincipals = n;
|
public->cert->nprincipals = n;
|
||||||
public->cert->principals = plist;
|
public->cert->principals = plist;
|
||||||
public->cert->valid_after = cert_valid_from;
|
public->cert->valid_after = cert_valid_from;
|
||||||
public->cert->valid_before = cert_valid_to;
|
public->cert->valid_before = cert_valid_to;
|
||||||
prepare_constraint_buf(&public->cert->constraints);
|
prepare_options_buf(&public->cert->critical);
|
||||||
public->cert->signature_key = key_from_private(ca);
|
public->cert->signature_key = key_from_private(ca);
|
||||||
|
|
||||||
if (key_certify(public, ca) != 0)
|
if (key_certify(public, ca) != 0)
|
||||||
@ -1212,13 +1239,14 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
|
|||||||
fprintf(f, " %s\n", comment);
|
fprintf(f, " %s\n", comment);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
if (!quiet)
|
if (!quiet) {
|
||||||
logit("Signed %s key %s: id \"%s\"%s%s valid %s",
|
logit("Signed %s key %s: id \"%s\" serial %llu%s%s "
|
||||||
cert_key_type == SSH2_CERT_TYPE_USER?"user":"host",
|
"valid %s", key_cert_type(public),
|
||||||
out, cert_key_id,
|
out, public->cert->key_id, public->cert->serial,
|
||||||
cert_principals != NULL ? " for " : "",
|
cert_principals != NULL ? " for " : "",
|
||||||
cert_principals != NULL ? cert_principals : "",
|
cert_principals != NULL ? cert_principals : "",
|
||||||
fmt_validity(cert_valid_from, cert_valid_to));
|
fmt_validity(cert_valid_from, cert_valid_to));
|
||||||
|
}
|
||||||
|
|
||||||
key_free(public);
|
key_free(public);
|
||||||
xfree(out);
|
xfree(out);
|
||||||
@ -1321,50 +1349,50 @@ parse_cert_times(char *timespec)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_cert_constraint(char *opt)
|
add_cert_option(char *opt)
|
||||||
{
|
{
|
||||||
char *val;
|
char *val;
|
||||||
|
|
||||||
if (strcmp(opt, "clear") == 0)
|
if (strcmp(opt, "clear") == 0)
|
||||||
constraint_flags = 0;
|
critical_flags = 0;
|
||||||
else if (strcasecmp(opt, "no-x11-forwarding") == 0)
|
else if (strcasecmp(opt, "no-x11-forwarding") == 0)
|
||||||
constraint_flags &= ~CONSTRAINT_X_FWD;
|
critical_flags &= ~CRITOPT_X_FWD;
|
||||||
else if (strcasecmp(opt, "permit-x11-forwarding") == 0)
|
else if (strcasecmp(opt, "permit-x11-forwarding") == 0)
|
||||||
constraint_flags |= CONSTRAINT_X_FWD;
|
critical_flags |= CRITOPT_X_FWD;
|
||||||
else if (strcasecmp(opt, "no-agent-forwarding") == 0)
|
else if (strcasecmp(opt, "no-agent-forwarding") == 0)
|
||||||
constraint_flags &= ~CONSTRAINT_AGENT_FWD;
|
critical_flags &= ~CRITOPT_AGENT_FWD;
|
||||||
else if (strcasecmp(opt, "permit-agent-forwarding") == 0)
|
else if (strcasecmp(opt, "permit-agent-forwarding") == 0)
|
||||||
constraint_flags |= CONSTRAINT_AGENT_FWD;
|
critical_flags |= CRITOPT_AGENT_FWD;
|
||||||
else if (strcasecmp(opt, "no-port-forwarding") == 0)
|
else if (strcasecmp(opt, "no-port-forwarding") == 0)
|
||||||
constraint_flags &= ~CONSTRAINT_PORT_FWD;
|
critical_flags &= ~CRITOPT_PORT_FWD;
|
||||||
else if (strcasecmp(opt, "permit-port-forwarding") == 0)
|
else if (strcasecmp(opt, "permit-port-forwarding") == 0)
|
||||||
constraint_flags |= CONSTRAINT_PORT_FWD;
|
critical_flags |= CRITOPT_PORT_FWD;
|
||||||
else if (strcasecmp(opt, "no-pty") == 0)
|
else if (strcasecmp(opt, "no-pty") == 0)
|
||||||
constraint_flags &= ~CONSTRAINT_PTY;
|
critical_flags &= ~CRITOPT_PTY;
|
||||||
else if (strcasecmp(opt, "permit-pty") == 0)
|
else if (strcasecmp(opt, "permit-pty") == 0)
|
||||||
constraint_flags |= CONSTRAINT_PTY;
|
critical_flags |= CRITOPT_PTY;
|
||||||
else if (strcasecmp(opt, "no-user-rc") == 0)
|
else if (strcasecmp(opt, "no-user-rc") == 0)
|
||||||
constraint_flags &= ~CONSTRAINT_USER_RC;
|
critical_flags &= ~CRITOPT_USER_RC;
|
||||||
else if (strcasecmp(opt, "permit-user-rc") == 0)
|
else if (strcasecmp(opt, "permit-user-rc") == 0)
|
||||||
constraint_flags |= CONSTRAINT_USER_RC;
|
critical_flags |= CRITOPT_USER_RC;
|
||||||
else if (strncasecmp(opt, "force-command=", 14) == 0) {
|
else if (strncasecmp(opt, "force-command=", 14) == 0) {
|
||||||
val = opt + 14;
|
val = opt + 14;
|
||||||
if (*val == '\0')
|
if (*val == '\0')
|
||||||
fatal("Empty force-command constraint");
|
fatal("Empty force-command option");
|
||||||
if (constraint_command != NULL)
|
if (critical_command != NULL)
|
||||||
fatal("force-command already specified");
|
fatal("force-command already specified");
|
||||||
constraint_command = xstrdup(val);
|
critical_command = xstrdup(val);
|
||||||
} else if (strncasecmp(opt, "source-address=", 15) == 0) {
|
} else if (strncasecmp(opt, "source-address=", 15) == 0) {
|
||||||
val = opt + 15;
|
val = opt + 15;
|
||||||
if (*val == '\0')
|
if (*val == '\0')
|
||||||
fatal("Empty source-address constraint");
|
fatal("Empty source-address option");
|
||||||
if (constraint_src_addr != NULL)
|
if (critical_src_addr != NULL)
|
||||||
fatal("source-address already specified");
|
fatal("source-address already specified");
|
||||||
if (addr_match_cidr_list(NULL, val) != 0)
|
if (addr_match_cidr_list(NULL, val) != 0)
|
||||||
fatal("Invalid source-address list");
|
fatal("Invalid source-address list");
|
||||||
constraint_src_addr = xstrdup(val);
|
critical_src_addr = xstrdup(val);
|
||||||
} else
|
} else
|
||||||
fatal("Unsupported certificate constraint \"%s\"", opt);
|
fatal("Unsupported certificate option \"%s\"", opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1373,9 +1401,9 @@ do_show_cert(struct passwd *pw)
|
|||||||
Key *key;
|
Key *key;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
char *key_fp, *ca_fp;
|
char *key_fp, *ca_fp;
|
||||||
Buffer constraints, constraint;
|
Buffer options, option;
|
||||||
u_char *name, *data;
|
u_char *name, *data;
|
||||||
u_int i, dlen;
|
u_int i, dlen, v00;
|
||||||
|
|
||||||
if (!have_identity)
|
if (!have_identity)
|
||||||
ask_filename(pw, "Enter file in which the key is");
|
ask_filename(pw, "Enter file in which the key is");
|
||||||
@ -1387,17 +1415,21 @@ do_show_cert(struct passwd *pw)
|
|||||||
fatal("%s is not a public key", identity_file);
|
fatal("%s is not a public key", identity_file);
|
||||||
if (!key_is_cert(key))
|
if (!key_is_cert(key))
|
||||||
fatal("%s is not a certificate", identity_file);
|
fatal("%s is not a certificate", identity_file);
|
||||||
|
v00 = key->type == KEY_RSA_CERT_V00 || key->type == KEY_DSA_CERT_V00;
|
||||||
|
|
||||||
key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
|
key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
|
||||||
ca_fp = key_fingerprint(key->cert->signature_key,
|
ca_fp = key_fingerprint(key->cert->signature_key,
|
||||||
SSH_FP_MD5, SSH_FP_HEX);
|
SSH_FP_MD5, SSH_FP_HEX);
|
||||||
|
|
||||||
printf("%s:\n", identity_file);
|
printf("%s:\n", identity_file);
|
||||||
printf(" %s %s certificate %s\n", key_type(key),
|
printf(" Type: %s %s certificate\n", key_ssh_name(key),
|
||||||
key_cert_type(key), key_fp);
|
key_cert_type(key));
|
||||||
printf(" Signed by %s CA %s\n",
|
printf(" Public key: %s %s\n", key_type(key), key_fp);
|
||||||
|
printf(" Signing CA: %s %s\n",
|
||||||
key_type(key->cert->signature_key), ca_fp);
|
key_type(key->cert->signature_key), ca_fp);
|
||||||
printf(" Key ID \"%s\"\n", key->cert->key_id);
|
printf(" Key ID: \"%s\"\n", key->cert->key_id);
|
||||||
|
if (!v00)
|
||||||
|
printf(" Serial: %llu\n", key->cert->serial);
|
||||||
printf(" Valid: %s\n",
|
printf(" Valid: %s\n",
|
||||||
fmt_validity(key->cert->valid_after, key->cert->valid_before));
|
fmt_validity(key->cert->valid_after, key->cert->valid_before));
|
||||||
printf(" Principals: ");
|
printf(" Principals: ");
|
||||||
@ -1409,20 +1441,20 @@ do_show_cert(struct passwd *pw)
|
|||||||
key->cert->principals[i]);
|
key->cert->principals[i]);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
printf(" Constraints: ");
|
printf(" Critical Options: ");
|
||||||
if (buffer_len(&key->cert->constraints) == 0)
|
if (buffer_len(&key->cert->critical) == 0)
|
||||||
printf("(none)\n");
|
printf("(none)\n");
|
||||||
else {
|
else {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
buffer_init(&constraints);
|
buffer_init(&options);
|
||||||
buffer_append(&constraints,
|
buffer_append(&options,
|
||||||
buffer_ptr(&key->cert->constraints),
|
buffer_ptr(&key->cert->critical),
|
||||||
buffer_len(&key->cert->constraints));
|
buffer_len(&key->cert->critical));
|
||||||
buffer_init(&constraint);
|
buffer_init(&option);
|
||||||
while (buffer_len(&constraints) != 0) {
|
while (buffer_len(&options) != 0) {
|
||||||
name = buffer_get_string(&constraints, NULL);
|
name = buffer_get_string(&options, NULL);
|
||||||
data = buffer_get_string_ptr(&constraints, &dlen);
|
data = buffer_get_string_ptr(&options, &dlen);
|
||||||
buffer_append(&constraint, data, dlen);
|
buffer_append(&option, data, dlen);
|
||||||
printf(" %s", name);
|
printf(" %s", name);
|
||||||
if (strcmp(name, "permit-X11-forwarding") == 0 ||
|
if (strcmp(name, "permit-X11-forwarding") == 0 ||
|
||||||
strcmp(name, "permit-agent-forwarding") == 0 ||
|
strcmp(name, "permit-agent-forwarding") == 0 ||
|
||||||
@ -1432,22 +1464,43 @@ do_show_cert(struct passwd *pw)
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
else if (strcmp(name, "force-command") == 0 ||
|
else if (strcmp(name, "force-command") == 0 ||
|
||||||
strcmp(name, "source-address") == 0) {
|
strcmp(name, "source-address") == 0) {
|
||||||
data = buffer_get_string(&constraint, NULL);
|
data = buffer_get_string(&option, NULL);
|
||||||
printf(" %s\n", data);
|
printf(" %s\n", data);
|
||||||
xfree(data);
|
xfree(data);
|
||||||
} else {
|
} else {
|
||||||
printf(" UNKNOWN CONSTRAINT (len %u)\n",
|
printf(" UNKNOWN OPTION (len %u)\n",
|
||||||
buffer_len(&constraint));
|
buffer_len(&option));
|
||||||
buffer_clear(&constraint);
|
buffer_clear(&option);
|
||||||
}
|
}
|
||||||
xfree(name);
|
xfree(name);
|
||||||
if (buffer_len(&constraint) != 0)
|
if (buffer_len(&option) != 0)
|
||||||
fatal("Constraint corrupt: extra data at end");
|
fatal("Option corrupt: extra data at end");
|
||||||
|
}
|
||||||
|
buffer_free(&option);
|
||||||
|
buffer_free(&options);
|
||||||
|
}
|
||||||
|
if (!v00) {
|
||||||
|
printf(" Extensions: ");
|
||||||
|
if (buffer_len(&key->cert->extensions) == 0)
|
||||||
|
printf("(none)\n");
|
||||||
|
else {
|
||||||
|
printf("\n");
|
||||||
|
buffer_init(&options);
|
||||||
|
buffer_append(&options,
|
||||||
|
buffer_ptr(&key->cert->extensions),
|
||||||
|
buffer_len(&key->cert->extensions));
|
||||||
|
buffer_init(&option);
|
||||||
|
while (buffer_len(&options) != 0) {
|
||||||
|
name = buffer_get_string(&options, NULL);
|
||||||
|
(void)buffer_get_string_ptr(&options, &dlen);
|
||||||
|
printf(" %s UNKNOWN OPTION "
|
||||||
|
"(len %u)\n", name, dlen);
|
||||||
|
xfree(name);
|
||||||
|
}
|
||||||
|
buffer_free(&option);
|
||||||
|
buffer_free(&options);
|
||||||
}
|
}
|
||||||
buffer_free(&constraint);
|
|
||||||
buffer_free(&constraints);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1478,7 +1531,7 @@ usage(void)
|
|||||||
fprintf(stderr, " -M memory Amount of memory (MB) to use for generating DH-GEX moduli.\n");
|
fprintf(stderr, " -M memory Amount of memory (MB) to use for generating DH-GEX moduli.\n");
|
||||||
fprintf(stderr, " -n name,... User/host principal names to include in certificate\n");
|
fprintf(stderr, " -n name,... User/host principal names to include in certificate\n");
|
||||||
fprintf(stderr, " -N phrase Provide new passphrase.\n");
|
fprintf(stderr, " -N phrase Provide new passphrase.\n");
|
||||||
fprintf(stderr, " -O cnstr Specify a certificate constraint.\n");
|
fprintf(stderr, " -O cnstr Specify a certificate option.\n");
|
||||||
fprintf(stderr, " -P phrase Provide old passphrase.\n");
|
fprintf(stderr, " -P phrase Provide old passphrase.\n");
|
||||||
fprintf(stderr, " -p Change passphrase of private key file.\n");
|
fprintf(stderr, " -p Change passphrase of private key file.\n");
|
||||||
fprintf(stderr, " -q Quiet.\n");
|
fprintf(stderr, " -q Quiet.\n");
|
||||||
@ -1541,7 +1594,7 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "degiqpclBHLhvxXyF:b:f:t:D:I:P:N:n:"
|
while ((opt = getopt(argc, argv, "degiqpclBHLhvxXyF:b:f:t:D:I:P:N:n:"
|
||||||
"O:C:r:g:R:T:G:M:S:s:a:V:W:")) != -1) {
|
"O:C:r:g:R:T:G:M:S:s:a:V:W:z:")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'b':
|
case 'b':
|
||||||
bits = (u_int32_t)strtonum(optarg, 768, 32768, &errstr);
|
bits = (u_int32_t)strtonum(optarg, 768, 32768, &errstr);
|
||||||
@ -1597,7 +1650,7 @@ main(int argc, char **argv)
|
|||||||
identity_new_passphrase = optarg;
|
identity_new_passphrase = optarg;
|
||||||
break;
|
break;
|
||||||
case 'O':
|
case 'O':
|
||||||
add_cert_constraint(optarg);
|
add_cert_option(optarg);
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
identity_comment = optarg;
|
identity_comment = optarg;
|
||||||
@ -1612,7 +1665,7 @@ main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
cert_key_type = SSH2_CERT_TYPE_HOST;
|
cert_key_type = SSH2_CERT_TYPE_HOST;
|
||||||
constraint_flags = 0;
|
critical_flags = 0;
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
case 'X':
|
case 'X':
|
||||||
@ -1661,9 +1714,8 @@ main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr);
|
memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr);
|
||||||
if (errstr) {
|
if (errstr)
|
||||||
fatal("Memory limit is %s: %s", errstr, optarg);
|
fatal("Memory limit is %s: %s", errstr, optarg);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'G':
|
case 'G':
|
||||||
do_gen_candidates = 1;
|
do_gen_candidates = 1;
|
||||||
@ -1685,6 +1737,11 @@ main(int argc, char **argv)
|
|||||||
case 'V':
|
case 'V':
|
||||||
parse_cert_times(optarg);
|
parse_cert_times(optarg);
|
||||||
break;
|
break;
|
||||||
|
case 'z':
|
||||||
|
cert_serial = strtonum(optarg, 0, LLONG_MAX, &errstr);
|
||||||
|
if (errstr)
|
||||||
|
fatal("Invalid serial number: %s", errstr);
|
||||||
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
|
12
ssh-rsa.c
12
ssh-rsa.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: ssh-rsa.c,v 1.40 2010/02/26 20:29:54 djm Exp $ */
|
/* $OpenBSD: ssh-rsa.c,v 1.41 2010/04/16 01:47:26 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org>
|
* Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org>
|
||||||
*
|
*
|
||||||
@ -46,9 +46,8 @@ ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp,
|
|||||||
int ok, nid;
|
int ok, nid;
|
||||||
Buffer b;
|
Buffer b;
|
||||||
|
|
||||||
if (key == NULL ||
|
if (key == NULL || key->rsa == NULL || (key->type != KEY_RSA &&
|
||||||
(key->type != KEY_RSA && key->type != KEY_RSA_CERT) ||
|
key->type != KEY_RSA_CERT && key->type != KEY_RSA_CERT_V00)) {
|
||||||
key->rsa == NULL) {
|
|
||||||
error("ssh_rsa_sign: no RSA key");
|
error("ssh_rsa_sign: no RSA key");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -115,9 +114,8 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
|
|||||||
u_int len, dlen, modlen;
|
u_int len, dlen, modlen;
|
||||||
int rlen, ret, nid;
|
int rlen, ret, nid;
|
||||||
|
|
||||||
if (key == NULL ||
|
if (key == NULL || key->rsa == NULL || (key->type != KEY_RSA &&
|
||||||
(key->type != KEY_RSA && key->type != KEY_RSA_CERT) ||
|
key->type != KEY_RSA_CERT && key->type != KEY_RSA_CERT_V00)) {
|
||||||
key->rsa == NULL) {
|
|
||||||
error("ssh_rsa_verify: no RSA key");
|
error("ssh_rsa_verify: no RSA key");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: sshconnect.c,v 1.222 2010/04/14 22:27:42 djm Exp $ */
|
/* $OpenBSD: sshconnect.c,v 1.223 2010/04/16 01:47:26 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -586,9 +586,9 @@ check_host_cert(const char *host, const Key *host_key)
|
|||||||
error("%s", reason);
|
error("%s", reason);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (buffer_len(&host_key->cert->constraints) != 0) {
|
if (buffer_len(&host_key->cert->critical) != 0) {
|
||||||
error("Certificate for %s contains unsupported constraint(s)",
|
error("Certificate for %s contains unsupported "
|
||||||
host);
|
"critical options(s)", host);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: sshconnect2.c,v 1.181 2010/04/10 02:10:56 djm Exp $ */
|
/* $OpenBSD: sshconnect2.c,v 1.182 2010/04/16 01:47:26 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||||
* Copyright (c) 2008 Damien Miller. All rights reserved.
|
* Copyright (c) 2008 Damien Miller. All rights reserved.
|
||||||
@ -1140,8 +1140,11 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
|
|||||||
u_int skip = 0;
|
u_int skip = 0;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
int have_sig = 1;
|
int have_sig = 1;
|
||||||
|
char *fp;
|
||||||
|
|
||||||
debug3("sign_and_send_pubkey");
|
fp = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX);
|
||||||
|
debug3("sign_and_send_pubkey: %s %s", key_type(id->key), fp);
|
||||||
|
xfree(fp);
|
||||||
|
|
||||||
if (key_to_blob(id->key, &blob, &bloblen) == 0) {
|
if (key_to_blob(id->key, &blob, &bloblen) == 0) {
|
||||||
/* we cannot handle this key */
|
/* we cannot handle this key */
|
||||||
|
15
sshd.c
15
sshd.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: sshd.c,v 1.374 2010/03/07 11:57:13 dtucker Exp $ */
|
/* $OpenBSD: sshd.c,v 1.375 2010/04/16 01:47:26 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -744,6 +744,8 @@ list_hostkey_types(void)
|
|||||||
if (key == NULL)
|
if (key == NULL)
|
||||||
continue;
|
continue;
|
||||||
switch (key->type) {
|
switch (key->type) {
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
case KEY_RSA_CERT:
|
case KEY_RSA_CERT:
|
||||||
case KEY_DSA_CERT:
|
case KEY_DSA_CERT:
|
||||||
if (buffer_len(&b) > 0)
|
if (buffer_len(&b) > 0)
|
||||||
@ -767,10 +769,17 @@ get_hostkey_by_type(int type, int need_private)
|
|||||||
Key *key;
|
Key *key;
|
||||||
|
|
||||||
for (i = 0; i < options.num_host_key_files; i++) {
|
for (i = 0; i < options.num_host_key_files; i++) {
|
||||||
if (type == KEY_RSA_CERT || type == KEY_DSA_CERT)
|
switch (type) {
|
||||||
|
case KEY_RSA_CERT_V00:
|
||||||
|
case KEY_DSA_CERT_V00:
|
||||||
|
case KEY_RSA_CERT:
|
||||||
|
case KEY_DSA_CERT:
|
||||||
key = sensitive_data.host_certificates[i];
|
key = sensitive_data.host_certificates[i];
|
||||||
else
|
break;
|
||||||
|
default:
|
||||||
key = sensitive_data.host_keys[i];
|
key = sensitive_data.host_keys[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (key != NULL && key->type == type)
|
if (key != NULL && key->type == type)
|
||||||
return need_private ?
|
return need_private ?
|
||||||
sensitive_data.host_keys[i] : key;
|
sensitive_data.host_keys[i] : key;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user