version 1.86, 2010/03/15 19:40:02 |
version 1.87, 2010/04/16 01:47:26 |
|
|
|
|
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; |
|
|
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"); |
|
|
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"); |
|
|
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"); |
|
|
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"); |
|
|
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++) |
|
|
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); |
|
|
|
|
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 && |
|
|
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 */ |
|
|
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, ' '); |
|
|
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; |
|
|
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: |
|
|
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"; |
} |
} |
|
|
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); |
} |
} |
|
|
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"); |
|
|
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; |
|
|
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) || |
|
|
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) || |
|
|
} 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); |
|
|
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; |
|
|
|
|
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; |
goto out; |
} |
} |
} |
} |
buffer_clear(&tmp); |
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; |
|
} |
|
} |
|
buffer_clear(&tmp); |
|
|
if ((key->cert->signature_key = key_from_blob(sig_key, |
if ((key->cert->signature_key = key_from_blob(sig_key, |
sklen)) == NULL) { |
sklen)) == NULL) { |
error("%s: Signature key invalid", __func__); |
error("%s: Signature key invalid", __func__); |
|
|
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) |
|
|
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) { |
|
|
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 || |
|
|
} |
} |
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 */ |
|
|
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); |
|
|
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); |
|
|
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 */ |
|
|
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 */ |
|
|
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 */ |
|
|
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: |
|
|
|
|
/* 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)); |
|
|
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; |
|
|
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); |
|
|
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); |
|
|
|
|
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)); |
|
|
|
arc4random_buf(&nonce, sizeof(nonce)); |
/* -v01 certs have non-critical options here */ |
buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce)); |
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)); |
|
|
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); |
|
|
} |
} |
} |
} |
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; |
|
} |
} |
} |