version 1.8, 2019/11/12 19:34:00 |
version 1.9, 2019/11/12 19:34:40 |
|
|
} |
} |
|
|
static int |
static int |
sshsk_ecdsa_inner_sig(struct sk_sign_response *resp, struct sshbuf **retp) |
sshsk_ecdsa_sig(struct sk_sign_response *resp, struct sshbuf *sig) |
{ |
{ |
struct sshbuf *inner_sig = NULL; |
struct sshbuf *inner_sig = NULL; |
int r = SSH_ERR_INTERNAL_ERROR; |
int r = SSH_ERR_INTERNAL_ERROR; |
|
|
*retp = NULL; |
|
/* Check response validity */ |
/* Check response validity */ |
if (resp->sig_r == NULL || resp->sig_r == NULL) { |
if (resp->sig_r == NULL || resp->sig_r == NULL) { |
error("%s: sk_sign response invalid", __func__); |
error("%s: sk_sign response invalid", __func__); |
|
|
r = SSH_ERR_ALLOC_FAIL; |
r = SSH_ERR_ALLOC_FAIL; |
goto out; |
goto out; |
} |
} |
/* Prepare inner signature object */ |
/* Prepare and append inner signature object */ |
if ((r = sshbuf_put_bignum2_bytes(inner_sig, |
if ((r = sshbuf_put_bignum2_bytes(inner_sig, |
resp->sig_r, resp->sig_r_len)) != 0 || |
resp->sig_r, resp->sig_r_len)) != 0 || |
(r = sshbuf_put_bignum2_bytes(inner_sig, |
(r = sshbuf_put_bignum2_bytes(inner_sig, |
|
|
debug("%s: buffer error: %s", __func__, ssh_err(r)); |
debug("%s: buffer error: %s", __func__, ssh_err(r)); |
goto out; |
goto out; |
} |
} |
|
if ((r = sshbuf_put_stringb(sig, inner_sig)) != 0) { |
|
debug("%s: buffer error: %s", __func__, ssh_err(r)); |
|
goto out; |
|
} |
#ifdef DEBUG_SK |
#ifdef DEBUG_SK |
fprintf(stderr, "%s: sig_r:\n", __func__); |
fprintf(stderr, "%s: sig_r:\n", __func__); |
sshbuf_dump_data(resp->sig_r, resp->sig_r_len, stderr); |
sshbuf_dump_data(resp->sig_r, resp->sig_r_len, stderr); |
fprintf(stderr, "%s: sig_s:\n", __func__); |
fprintf(stderr, "%s: sig_s:\n", __func__); |
sshbuf_dump_data(resp->sig_s, resp->sig_s_len, stderr); |
sshbuf_dump_data(resp->sig_s, resp->sig_s_len, stderr); |
|
fprintf(stderr, "%s: inner:\n", __func__); |
|
sshbuf_dump(inner_sig, stderr); |
#endif |
#endif |
*retp = inner_sig; |
|
inner_sig = NULL; |
|
r = 0; |
r = 0; |
out: |
out: |
sshbuf_free(inner_sig); |
sshbuf_free(inner_sig); |
return r; |
return r; |
} |
} |
|
|
static int |
static int |
sshsk_ed25519_inner_sig(struct sk_sign_response *resp, struct sshbuf **retp) |
sshsk_ed25519_sig(struct sk_sign_response *resp, struct sshbuf *sig) |
{ |
{ |
struct sshbuf *inner_sig = NULL; |
|
int r = SSH_ERR_INTERNAL_ERROR; |
int r = SSH_ERR_INTERNAL_ERROR; |
|
|
*retp = NULL; |
|
/* Check response validity */ |
/* Check response validity */ |
if (resp->sig_r == NULL) { |
if (resp->sig_r == NULL) { |
error("%s: sk_sign response invalid", __func__); |
error("%s: sk_sign response invalid", __func__); |
r = SSH_ERR_INVALID_FORMAT; |
r = SSH_ERR_INVALID_FORMAT; |
goto out; |
goto out; |
} |
} |
if ((inner_sig = sshbuf_new()) == NULL) { |
if ((r = sshbuf_put_string(sig, |
r = SSH_ERR_ALLOC_FAIL; |
|
goto out; |
|
} |
|
/* Prepare inner signature object */ |
|
if ((r = sshbuf_put_string(inner_sig, |
|
resp->sig_r, resp->sig_r_len)) != 0 || |
resp->sig_r, resp->sig_r_len)) != 0 || |
(r = sshbuf_put_u8(inner_sig, resp->flags)) != 0 || |
(r = sshbuf_put_u8(sig, resp->flags)) != 0 || |
(r = sshbuf_put_u32(inner_sig, resp->counter)) != 0) { |
(r = sshbuf_put_u32(sig, resp->counter)) != 0) { |
debug("%s: buffer error: %s", __func__, ssh_err(r)); |
debug("%s: buffer error: %s", __func__, ssh_err(r)); |
goto out; |
goto out; |
} |
} |
|
|
fprintf(stderr, "%s: sig_r:\n", __func__); |
fprintf(stderr, "%s: sig_r:\n", __func__); |
sshbuf_dump_data(resp->sig_r, resp->sig_r_len, stderr); |
sshbuf_dump_data(resp->sig_r, resp->sig_r_len, stderr); |
#endif |
#endif |
*retp = inner_sig; |
|
inner_sig = NULL; |
|
r = 0; |
r = 0; |
out: |
out: |
sshbuf_free(inner_sig); |
return 0; |
return r; |
|
} |
} |
|
|
int |
int |
|
|
debug("%s: sk_sign failed with code %d", __func__, r); |
debug("%s: sk_sign failed with code %d", __func__, r); |
goto out; |
goto out; |
} |
} |
/* Prepare inner signature object */ |
/* Assemble signature */ |
|
if ((sig = sshbuf_new()) == NULL) { |
|
r = SSH_ERR_ALLOC_FAIL; |
|
goto out; |
|
} |
|
if ((r = sshbuf_put_cstring(sig, sshkey_ssh_name_plain(key))) != 0) { |
|
debug("%s: buffer error (outer): %s", __func__, ssh_err(r)); |
|
goto out; |
|
} |
switch (type) { |
switch (type) { |
case KEY_ECDSA_SK: |
case KEY_ECDSA_SK: |
if ((r = sshsk_ecdsa_inner_sig(resp, &inner_sig)) != 0) |
if ((r = sshsk_ecdsa_sig(resp, sig)) != 0) |
goto out; |
goto out; |
break; |
break; |
case KEY_ED25519_SK: |
case KEY_ED25519_SK: |
if ((r = sshsk_ed25519_inner_sig(resp, &inner_sig)) != 0) |
if ((r = sshsk_ed25519_sig(resp, sig)) != 0) |
goto out; |
goto out; |
break; |
break; |
} |
} |
/* Assemble outer signature */ |
|
if ((sig = sshbuf_new()) == NULL) { |
|
r = SSH_ERR_ALLOC_FAIL; |
|
goto out; |
|
} |
|
if ((r = sshbuf_put_cstring(sig, sshkey_ssh_name_plain(key))) != 0 || |
|
(r = sshbuf_put_stringb(sig, inner_sig)) != 0) { |
|
debug("%s: buffer error (outer): %s", __func__, ssh_err(r)); |
|
goto out; |
|
} |
|
#ifdef DEBUG_SK |
#ifdef DEBUG_SK |
fprintf(stderr, "%s: sig_flags = 0x%02x, sig_counter = %u\n", |
fprintf(stderr, "%s: sig_flags = 0x%02x, sig_counter = %u\n", |
__func__, resp->flags, resp->counter); |
__func__, resp->flags, resp->counter); |
fprintf(stderr, "%s: hashed message:\n", __func__); |
fprintf(stderr, "%s: hashed message:\n", __func__); |
sshbuf_dump_data(message, sizeof(message), stderr); |
sshbuf_dump_data(message, sizeof(message), stderr); |
fprintf(stderr, "%s: inner:\n", __func__); |
|
sshbuf_dump(inner_sig, stderr); |
|
fprintf(stderr, "%s: sigbuf:\n", __func__); |
fprintf(stderr, "%s: sigbuf:\n", __func__); |
sshbuf_dump(sig, stderr); |
sshbuf_dump(sig, stderr); |
#endif |
#endif |