Skip to content

Commit

Permalink
Handle errors when signing SSH certificates
Browse files Browse the repository at this point in the history
  • Loading branch information
aveenismail committed Sep 3, 2024
1 parent bf1bf0d commit 4bf552c
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 24 deletions.
40 changes: 31 additions & 9 deletions common/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,14 @@ bool read_ed25519_key(uint8_t *in, size_t in_len, uint8_t *out,
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
BIO_push(b64, bio);

(void) BIO_write(bio, in + 28, in_len - 28 - 25);
(void) BIO_flush(bio);
if (BIO_write(bio, in + 28, in_len - 28 - 25) <= 0) {
BIO_free_all(b64);
return false;
}
if(BIO_flush(bio) != 1) {
BIO_free_all(b64);
return false;
}
ret = BIO_read(b64, decoded, decoded_len);

BIO_free_all(b64);
Expand Down Expand Up @@ -167,7 +173,9 @@ bool read_private_key(uint8_t *buf, size_t len, yh_algorithm *algo,
return false;
}

(void) BIO_write(bio, buf, len);
if(BIO_write(bio, buf, len) <= 0) {
return false;
}

private_key = PEM_read_bio_PrivateKey(bio, NULL, NULL, /*password*/ NULL);
BIO_free_all(bio);
Expand Down Expand Up @@ -372,7 +380,9 @@ bool read_public_key(uint8_t *buf, size_t len, yh_algorithm *algo,
return false;
}

(void) BIO_write(bio, buf, len);
if(BIO_write(bio, buf, len) <= 0) {
return false;
}

EVP_PKEY *pubkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
BIO_free_all(bio);
Expand Down Expand Up @@ -639,8 +649,14 @@ bool base64_decode(const char *in, uint8_t *out, size_t *len) {
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
BIO_push(b64, bio);

(void) BIO_write(bio, in, strlen(in));
(void) BIO_flush(bio);
if(BIO_write(bio, in, strlen(in)) <= 0) {
BIO_free_all(b64);
return false;
}
if(BIO_flush(bio) != 1) {
BIO_free_all(b64);
return false;
}
ret = BIO_read(b64, out, *len);

BIO_free_all(b64);
Expand Down Expand Up @@ -677,9 +693,15 @@ bool write_file(const uint8_t *buf, size_t buf_len, FILE *fp, format_t format) {
bio = BIO_push(b64, bio);

(void) BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
(void) BIO_write(bio, buf, buf_len);
(void) BIO_flush(bio);
(void) BIO_get_mem_ptr(bio, &bufferPtr);
if(BIO_write(bio, buf, buf_len) <= 0) {
return false;
}
if(BIO_flush(bio) != 1) {
return false;
}
if(BIO_get_mem_ptr(bio, &bufferPtr) != 1) {
return false;
}
p = (uint8_t *) bufferPtr->data;
length = bufferPtr->length;
} else if (format == _hex) {
Expand Down
6 changes: 3 additions & 3 deletions examples/ssh.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,9 +281,9 @@ int main(void) {

fprintf(stdout, "[email protected] ");
(void) BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
(void) BIO_write(bio, ssh_req + 4 + 256,
ssh_req_len + ssh_cert_len - 4 - 256);
(void) BIO_flush(bio);
assert(BIO_write(bio, ssh_req + 4 + 256,
ssh_req_len + ssh_cert_len - 4 - 256) > 0);
assert(BIO_flush(bio) == 1);
fprintf(stdout, "\n");

BIO_free_all(bio);
Expand Down
42 changes: 30 additions & 12 deletions src/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -2452,7 +2452,10 @@ static bool read_rsa_pubkey(const uint8_t *buf, size_t len,
if ((bio = BIO_new(BIO_s_mem())) == NULL)
return false;

(void) BIO_write(bio, buf, len);
if(BIO_write(bio, buf, len) <= 0) {
fprintf(stderr, "%s: Failed to read RSA public key\n", __func__);
return false;
}

RSA *rsa = NULL;
EVP_PKEY *pubkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
Expand Down Expand Up @@ -3082,6 +3085,7 @@ int yh_com_sign_ssh_certificate(yubihsm_context *ctx, Argument *argv,

uint8_t data[YH_MSG_BUF_SIZE + 1024] = {0};
size_t response_len = sizeof(data);
size_t in_len = 4 + 256; // 4 bytes time stamp + 256 bytes signature

if (argv[4].len > YH_MSG_BUF_SIZE) {
fprintf(stderr, "Failed to sign ssh certificate: %s\n",
Expand All @@ -3095,7 +3099,7 @@ int yh_com_sign_ssh_certificate(yubihsm_context *ctx, Argument *argv,
yh_rc yrc = yh_util_sign_ssh_certificate(argv[0].e, argv[1].w, argv[2].w,
argv[3].a, data, argv[4].len,
data + argv[4].len, &response_len);
if (yrc != YHR_SUCCESS) {
if (yrc != YHR_SUCCESS || response_len <= 0) {
fprintf(stderr, "Failed to get certificate signature: %s\n",
yh_strerror(yrc));
return -1;
Expand All @@ -3116,12 +3120,23 @@ int yh_com_sign_ssh_certificate(yubihsm_context *ctx, Argument *argv,

BUF_MEM *bufferPtr = 0;

int ret = 0;
(void) BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
(void) BIO_write(bio, data + 4 + 256,
argv[4].len + response_len - 4 -
256); // TODO(adma): FIXME, unmagify
(void) BIO_flush(bio);
(void) BIO_get_mem_ptr(bio, &bufferPtr);
if (BIO_write(bio, data + in_len, argv[4].len + response_len - in_len) <= 0) {
fprintf(stderr, "Failed to sign SSH certificate.\n");
ret = -1;
goto clean_bio;
}
if(BIO_flush(bio) != 1) {
fprintf(stderr, "Failed to sign SSH certificate.\n");
ret = -1;
goto clean_bio;
}
if(BIO_get_mem_ptr(bio, &bufferPtr) != 1) {
fprintf(stderr, "Failed to sign SSH certificate.\n");
ret = -1;
goto clean_bio;
}

const char *ssh_cert_str =
"[email protected] "; // TODO(adma): ECDSA
Expand All @@ -3130,24 +3145,27 @@ int yh_com_sign_ssh_certificate(yubihsm_context *ctx, Argument *argv,
strlen(ssh_cert_str) ||
ferror(ctx->out)) {
fprintf(stderr, "Unable to write data to file\n");
return -1;
ret = -1;
goto clean_bio;
}

if (fwrite(bufferPtr->data, 1, bufferPtr->length, ctx->out) !=
bufferPtr->length ||
ferror(ctx->out)) {
fprintf(stderr, "Unable to write data to file\n");
return -1;
ret = -1;
goto clean_bio;
}

if (fwrite("\n", 1, 1, ctx->out) != 1 || ferror(ctx->out)) {
fprintf(stderr, "Unable to write data to file\n");
return -1;
ret = -1;
}

(void) BIO_free_all(bio); // TODO: fix this leak.
clean_bio:
(void) BIO_free_all(bio);

return 0;
return ret;
}

static void time_elapsed(struct timeval *after, struct timeval *before,
Expand Down

0 comments on commit 4bf552c

Please sign in to comment.