version 1.196, 2010/08/04 05:40:39 |
version 1.204, 2010/10/28 11:22:09 |
|
|
/* Number of bits in the RSA/DSA key. This value can be set on the command line. */ |
/* Number of bits in the RSA/DSA key. This value can be set on the command line. */ |
#define DEFAULT_BITS 2048 |
#define DEFAULT_BITS 2048 |
#define DEFAULT_BITS_DSA 1024 |
#define DEFAULT_BITS_DSA 1024 |
|
#define DEFAULT_BITS_ECDSA 256 |
u_int32_t bits = 0; |
u_int32_t bits = 0; |
|
|
/* |
/* |
|
|
|
|
char *key_type_name = NULL; |
char *key_type_name = NULL; |
|
|
|
/* Load key from this PKCS#11 provider */ |
|
char *pkcs11provider = NULL; |
|
|
/* argv0 */ |
/* argv0 */ |
extern char *__progname; |
extern char *__progname; |
|
|
case KEY_DSA: |
case KEY_DSA: |
name = _PATH_SSH_CLIENT_ID_DSA; |
name = _PATH_SSH_CLIENT_ID_DSA; |
break; |
break; |
|
case KEY_ECDSA_CERT: |
|
case KEY_ECDSA: |
|
name = _PATH_SSH_CLIENT_ID_ECDSA; |
|
break; |
case KEY_RSA_CERT: |
case KEY_RSA_CERT: |
case KEY_RSA_CERT_V00: |
case KEY_RSA_CERT_V00: |
case KEY_RSA: |
case KEY_RSA: |
|
|
if (!PEM_write_DSA_PUBKEY(stdout, k->dsa)) |
if (!PEM_write_DSA_PUBKEY(stdout, k->dsa)) |
fatal("PEM_write_DSA_PUBKEY failed"); |
fatal("PEM_write_DSA_PUBKEY failed"); |
break; |
break; |
|
case KEY_ECDSA: |
|
if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa)) |
|
fatal("PEM_write_EC_PUBKEY failed"); |
|
break; |
default: |
default: |
fatal("%s: unsupported key type %s", __func__, key_type(k)); |
fatal("%s: unsupported key type %s", __func__, key_type(k)); |
} |
} |
|
|
fatal("PEM_write_DSAPublicKey failed"); |
fatal("PEM_write_DSAPublicKey failed"); |
break; |
break; |
#endif |
#endif |
|
/* XXX ECDSA? */ |
default: |
default: |
fatal("%s: unsupported key type %s", __func__, key_type(k)); |
fatal("%s: unsupported key type %s", __func__, key_type(k)); |
} |
} |
|
|
(*k)->type = KEY_DSA; |
(*k)->type = KEY_DSA; |
(*k)->dsa = EVP_PKEY_get1_DSA(pubkey); |
(*k)->dsa = EVP_PKEY_get1_DSA(pubkey); |
break; |
break; |
|
case EVP_PKEY_EC: |
|
*k = key_new(KEY_UNSPEC); |
|
(*k)->type = KEY_ECDSA; |
|
(*k)->ecdsa = EVP_PKEY_get1_EC_KEY(pubkey); |
|
(*k)->ecdsa_nid = key_ecdsa_key_to_nid((*k)->ecdsa); |
|
break; |
default: |
default: |
fatal("%s: unsupported pubkey type %d", __func__, |
fatal("%s: unsupported pubkey type %d", __func__, |
EVP_PKEY_type(pubkey->type)); |
EVP_PKEY_type(pubkey->type)); |
|
|
fclose(fp); |
fclose(fp); |
return; |
return; |
} |
} |
|
/* XXX ECDSA */ |
#endif |
#endif |
fatal("%s: unrecognised raw private key format", __func__); |
fatal("%s: unrecognised raw private key format", __func__); |
} |
} |
|
|
ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, |
ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, |
NULL, 0, NULL, NULL); |
NULL, 0, NULL, NULL); |
break; |
break; |
|
case KEY_ECDSA: |
|
ok = PEM_write_ECPrivateKey(stdout, k->ecdsa, NULL, |
|
NULL, 0, NULL, NULL); |
|
break; |
case KEY_RSA: |
case KEY_RSA: |
ok = PEM_write_RSAPrivateKey(stdout, k->rsa, NULL, |
ok = PEM_write_RSAPrivateKey(stdout, k->rsa, NULL, |
NULL, 0, NULL, NULL); |
NULL, 0, NULL, NULL); |
|
|
} |
} |
|
|
static void |
static void |
do_download(struct passwd *pw, char *pkcs11provider) |
do_download(struct passwd *pw) |
{ |
{ |
#ifdef ENABLE_PKCS11 |
#ifdef ENABLE_PKCS11 |
Key **keys = NULL; |
Key **keys = NULL; |
|
|
add_string_option(c, "source-address", certflags_src_addr); |
add_string_option(c, "source-address", certflags_src_addr); |
} |
} |
|
|
|
static Key * |
|
load_pkcs11_key(char *path) |
|
{ |
|
#ifdef ENABLE_PKCS11 |
|
Key **keys = NULL, *public, *private = NULL; |
|
int i, nkeys; |
|
|
|
if ((public = key_load_public(path, NULL)) == NULL) |
|
fatal("Couldn't load CA public key \"%s\"", path); |
|
|
|
nkeys = pkcs11_add_provider(pkcs11provider, identity_passphrase, &keys); |
|
debug3("%s: %d keys", __func__, nkeys); |
|
if (nkeys <= 0) |
|
fatal("cannot read public key from pkcs11"); |
|
for (i = 0; i < nkeys; i++) { |
|
if (key_equal_public(public, keys[i])) { |
|
private = keys[i]; |
|
continue; |
|
} |
|
key_free(keys[i]); |
|
} |
|
xfree(keys); |
|
key_free(public); |
|
return private; |
|
#else |
|
fatal("no pkcs11 support"); |
|
#endif /* ENABLE_PKCS11 */ |
|
} |
|
|
static void |
static void |
do_ca_sign(struct passwd *pw, int argc, char **argv) |
do_ca_sign(struct passwd *pw, int argc, char **argv) |
{ |
{ |
|
|
FILE *f; |
FILE *f; |
int v00 = 0; /* legacy keys */ |
int v00 = 0; /* legacy keys */ |
|
|
tmp = tilde_expand_filename(ca_key_path, pw->pw_uid); |
|
if ((ca = load_identity(tmp)) == NULL) |
|
fatal("Couldn't load CA key \"%s\"", tmp); |
|
xfree(tmp); |
|
|
|
if (key_type_name != NULL) { |
if (key_type_name != NULL) { |
switch (key_type_from_name(key_type_name)) { |
switch (key_type_from_name(key_type_name)) { |
case KEY_RSA_CERT_V00: |
case KEY_RSA_CERT_V00: |
|
|
} |
} |
} |
} |
|
|
|
pkcs11_init(1); |
|
tmp = tilde_expand_filename(ca_key_path, pw->pw_uid); |
|
if (pkcs11provider != NULL) { |
|
if ((ca = load_pkcs11_key(tmp)) == NULL) |
|
fatal("No PKCS#11 key matching %s found", ca_key_path); |
|
} else if ((ca = load_identity(tmp)) == NULL) |
|
fatal("Couldn't load CA key \"%s\"", tmp); |
|
xfree(tmp); |
|
|
for (i = 0; i < argc; i++) { |
for (i = 0; i < argc; i++) { |
/* Split list of principals */ |
/* Split list of principals */ |
n = 0; |
n = 0; |
|
|
tmp = tilde_expand_filename(argv[i], pw->pw_uid); |
tmp = tilde_expand_filename(argv[i], pw->pw_uid); |
if ((public = key_load_public(tmp, &comment)) == NULL) |
if ((public = key_load_public(tmp, &comment)) == NULL) |
fatal("%s: unable to open \"%s\"", __func__, tmp); |
fatal("%s: unable to open \"%s\"", __func__, tmp); |
if (public->type != KEY_RSA && public->type != KEY_DSA) |
if (public->type != KEY_RSA && public->type != KEY_DSA && |
|
public->type != KEY_ECDSA) |
fatal("%s: key \"%s\" type %s cannot be certified", |
fatal("%s: key \"%s\" type %s cannot be certified", |
__func__, tmp, key_type(public)); |
__func__, tmp, key_type(public)); |
|
|
|
|
key_free(public); |
key_free(public); |
xfree(out); |
xfree(out); |
} |
} |
|
pkcs11_terminate(); |
exit(0); |
exit(0); |
} |
} |
|
|
|
|
main(int argc, char **argv) |
main(int argc, char **argv) |
{ |
{ |
char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2; |
char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2; |
char out_file[MAXPATHLEN], *pkcs11provider = NULL; |
char out_file[MAXPATHLEN], *rr_hostname = NULL; |
char *rr_hostname = NULL; |
|
Key *private, *public; |
Key *private, *public; |
struct passwd *pw; |
struct passwd *pw; |
struct stat st; |
struct stat st; |
|
|
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ |
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ |
sanitise_stdfd(); |
sanitise_stdfd(); |
|
|
SSLeay_add_all_algorithms(); |
OpenSSL_add_all_algorithms(); |
log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); |
log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); |
|
|
/* we need this for the home * directory. */ |
/* we need this for the home * directory. */ |
|
|
"O:C:r:g:R:T:G:M:S:s:a:V:W:z:")) != -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, 256, 32768, &errstr); |
if (errstr) |
if (errstr) |
fatal("Bits has bad value %s (%s)", |
fatal("Bits has bad value %s (%s)", |
optarg, errstr); |
optarg, errstr); |
|
|
} |
} |
} |
} |
if (pkcs11provider != NULL) |
if (pkcs11provider != NULL) |
do_download(pw, pkcs11provider); |
do_download(pw); |
|
|
if (do_gen_candidates) { |
if (do_gen_candidates) { |
FILE *out = fopen(out_file, "w"); |
FILE *out = fopen(out_file, "w"); |
|
|
fprintf(stderr, "unknown key type %s\n", key_type_name); |
fprintf(stderr, "unknown key type %s\n", key_type_name); |
exit(1); |
exit(1); |
} |
} |
if (bits == 0) |
if (bits == 0) { |
bits = (type == KEY_DSA) ? DEFAULT_BITS_DSA : DEFAULT_BITS; |
if (type == KEY_DSA) |
|
bits = DEFAULT_BITS_DSA; |
|
else if (type == KEY_ECDSA) |
|
bits = DEFAULT_BITS_ECDSA; |
|
else |
|
bits = DEFAULT_BITS; |
|
} |
maxbits = (type == KEY_DSA) ? |
maxbits = (type == KEY_DSA) ? |
OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS; |
OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS; |
if (bits > maxbits) { |
if (bits > maxbits) { |
|
|
} |
} |
if (type == KEY_DSA && bits != 1024) |
if (type == KEY_DSA && bits != 1024) |
fatal("DSA keys must be 1024 bits"); |
fatal("DSA keys must be 1024 bits"); |
|
else if (type != KEY_ECDSA && bits < 768) |
|
fatal("Key must at least be 768 bits"); |
|
else if (type == KEY_ECDSA && key_ecdsa_bits_to_nid(bits) == -1) |
|
fatal("Invalid ECDSA key length - valid lengths are " |
|
"256, 384 or 521 bits"); |
if (!quiet) |
if (!quiet) |
printf("Generating public/private %s key pair.\n", key_type_name); |
printf("Generating public/private %s key pair.\n", key_type_name); |
private = key_generate(type, bits); |
private = key_generate(type, bits); |