aboutsummaryrefslogtreecommitdiff
path: root/src/pki.c
diff options
context:
space:
mode:
authorBen Toews <mastahyeti@gmail.com>2019-02-13 08:49:39 -0700
committerAndreas Schneider <asn@cryptomilk.org>2019-04-17 10:21:42 +0200
commit7c0719e53dceb688009e12ba80a3e335205ecc51 (patch)
tree6e1ef6dc51338047be483d6235ad7e82a0f0ca24 /src/pki.c
parent04b284dae02858b151ab75704eb15facf3781551 (diff)
downloadlibssh-7c0719e53dceb688009e12ba80a3e335205ecc51.tar.gz
libssh-7c0719e53dceb688009e12ba80a3e335205ecc51.tar.xz
libssh-7c0719e53dceb688009e12ba80a3e335205ecc51.zip
pki: parse keys from certificates into ssh_key
Previously, we were just storing the raw certificate in ssh_key->cert. With this change, we parse out the nonce string at the beginning of the certificate. This leaves us with the certificate's public key at the start of the buffer. The existing public key parsing code can then parse this out into the key fieds of the ssh_key. Signed-off-by: Ben Toews <mastahyeti@gmail.com> Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Diffstat (limited to 'src/pki.c')
-rw-r--r--src/pki.c72
1 files changed, 51 insertions, 21 deletions
diff --git a/src/pki.c b/src/pki.c
index c27bb085..ef83282e 100644
--- a/src/pki.c
+++ b/src/pki.c
@@ -1243,43 +1243,73 @@ static int pki_import_cert_buffer(ssh_buffer buffer,
enum ssh_keytypes_e type,
ssh_key *pkey) {
ssh_buffer cert;
- ssh_string type_s;
- ssh_key key;
+ ssh_string tmp_s;
+ const char *type_c;
+ ssh_key key = NULL;
int rc;
- key = ssh_key_new();
- if (key == NULL) {
- return SSH_ERROR;
- }
- cert = ssh_buffer_new();
- if (cert == NULL) {
- ssh_key_free(key);
- return SSH_ERROR;
- }
-
- key->type = type;
- key->type_c = ssh_key_type_to_char(type);
- key->flags = SSH_KEY_FLAG_PUBLIC;
-
/*
* The cert blob starts with the key type as an ssh_string, but this
* string has been read out of the buffer to identify the key type.
* Simply add it again as first element before copying the rest.
*/
- type_s = ssh_string_from_char(key->type_c);
- if (type_s == NULL) {
+ cert = ssh_buffer_new();
+ if (cert == NULL) {
goto fail;
}
- rc = ssh_buffer_add_ssh_string(cert, type_s);
- ssh_string_free(type_s);
+ type_c = ssh_key_type_to_char(type);
+ tmp_s = ssh_string_from_char(type_c);
+ if (tmp_s == NULL) {
+ goto fail;
+ }
+ rc = ssh_buffer_add_ssh_string(cert, tmp_s);
+ SSH_STRING_FREE(tmp_s);
if (rc != 0) {
goto fail;
}
-
rc = ssh_buffer_add_buffer(cert, buffer);
if (rc != 0) {
goto fail;
}
+
+ /*
+ * After the key type, comes an ssh_string nonce. Just after this comes the
+ * cert public key, which can be parsed out of the buffer.
+ */
+ tmp_s = ssh_buffer_get_ssh_string(buffer);
+ if (tmp_s == NULL) {
+ goto fail;
+ }
+ SSH_STRING_FREE(tmp_s);
+
+ switch (type) {
+ case SSH_KEYTYPE_DSS_CERT01:
+ rc = pki_import_pubkey_buffer(buffer, SSH_KEYTYPE_DSS, &key);
+ break;
+ case SSH_KEYTYPE_RSA_CERT01:
+ rc = pki_import_pubkey_buffer(buffer, SSH_KEYTYPE_RSA, &key);
+ break;
+ case SSH_KEYTYPE_ECDSA_P256_CERT01:
+ rc = pki_import_pubkey_buffer(buffer, SSH_KEYTYPE_ECDSA_P256, &key);
+ break;
+ case SSH_KEYTYPE_ECDSA_P384_CERT01:
+ rc = pki_import_pubkey_buffer(buffer, SSH_KEYTYPE_ECDSA_P384, &key);
+ break;
+ case SSH_KEYTYPE_ECDSA_P521_CERT01:
+ rc = pki_import_pubkey_buffer(buffer, SSH_KEYTYPE_ECDSA_P521, &key);
+ break;
+ case SSH_KEYTYPE_ED25519_CERT01:
+ rc = pki_import_pubkey_buffer(buffer, SSH_KEYTYPE_ED25519, &key);
+ break;
+ default:
+ key = ssh_key_new();
+ }
+ if (rc != 0 || key == NULL) {
+ goto fail;
+ }
+
+ key->type = type;
+ key->type_c = type_c;
key->cert = (void*) cert;
*pkey = key;