static int pki_import_pubkey_buffer(ssh_buffer buffer, enum ssh_keytypes_e type, ssh_key *pkey) { ssh_key key; int rc; key = ssh_key_new(); if (key == NULL) { return SSH_ERROR; } key->type = type; key->type_c = ssh_key_type_to_char(type); key->flags = SSH_KEY_FLAG_PUBLIC; switch (type) { case SSH_KEYTYPE_DSS: { ssh_string p; ssh_string q; ssh_string g; ssh_string pubkey; p = ssh_buffer_get_ssh_string(buffer); if (p == NULL) { goto fail; } q = ssh_buffer_get_ssh_string(buffer); if (q == NULL) { ssh_string_burn(p); ssh_string_free(p); goto fail; } g = ssh_buffer_get_ssh_string(buffer); if (g == NULL) { ssh_string_burn(p); ssh_string_free(p); ssh_string_burn(q); ssh_string_free(q); goto fail; } pubkey = ssh_buffer_get_ssh_string(buffer); if (pubkey == NULL) { ssh_string_burn(p); ssh_string_free(p); ssh_string_burn(q); ssh_string_free(q); ssh_string_burn(g); ssh_string_free(g); goto fail; } rc = pki_pubkey_build_dss(key, p, q, g, pubkey); #ifdef DEBUG_CRYPTO ssh_print_hexa("p", ssh_string_data(p), ssh_string_len(p)); ssh_print_hexa("q", ssh_string_data(q), ssh_string_len(q)); ssh_print_hexa("g", ssh_string_data(g), ssh_string_len(g)); #endif ssh_string_burn(p); ssh_string_free(p); ssh_string_burn(q); ssh_string_free(q); ssh_string_burn(g); ssh_string_free(g); ssh_string_burn(pubkey); ssh_string_free(pubkey); if (rc == SSH_ERROR) { goto fail; } } break; case SSH_KEYTYPE_RSA: case SSH_KEYTYPE_RSA1: { ssh_string e; ssh_string n; e = ssh_buffer_get_ssh_string(buffer); if (e == NULL) { goto fail; } n = ssh_buffer_get_ssh_string(buffer); if (n == NULL) { ssh_string_burn(e); ssh_string_free(e); goto fail; } rc = pki_pubkey_build_rsa(key, e, n); #ifdef DEBUG_CRYPTO ssh_print_hexa("e", ssh_string_data(e), ssh_string_len(e)); ssh_print_hexa("n", ssh_string_data(n), ssh_string_len(n)); #endif ssh_string_burn(e); ssh_string_free(e); ssh_string_burn(n); ssh_string_free(n); if (rc == SSH_ERROR) { goto fail; } } break; case SSH_KEYTYPE_ECDSA: #ifdef HAVE_ECC { ssh_string e; ssh_string i; int nid; i = ssh_buffer_get_ssh_string(buffer); if (i == NULL) { goto fail; } nid = pki_key_ecdsa_nid_from_name(ssh_string_get_char(i)); ssh_string_free(i); if (nid == -1) { goto fail; } e = ssh_buffer_get_ssh_string(buffer); if (e == NULL) { goto fail; } rc = pki_pubkey_build_ecdsa(key, nid, e); ssh_string_burn(e); ssh_string_free(e); if (rc < 0) { goto fail; } /* Update key type */ key->type_c = ssh_pki_key_ecdsa_name(key); } break; #endif case SSH_KEYTYPE_ED25519: { ssh_string pubkey = ssh_buffer_get_ssh_string(buffer); if (ssh_string_len(pubkey) != ED25519_PK_LEN) { SSH_LOG(SSH_LOG_WARN, "Invalid public key length"); ssh_string_burn(pubkey); ssh_string_free(pubkey); goto fail; } key->ed25519_pubkey = malloc(ED25519_PK_LEN); if (key->ed25519_pubkey == NULL) { ssh_string_burn(pubkey); ssh_string_free(pubkey); goto fail; } memcpy(key->ed25519_pubkey, ssh_string_data(pubkey), ED25519_PK_LEN); ssh_string_burn(pubkey); ssh_string_free(pubkey); } break; case SSH_KEYTYPE_DSS_CERT01: case SSH_KEYTYPE_RSA_CERT01: case SSH_KEYTYPE_UNKNOWN: default: SSH_LOG(SSH_LOG_WARN, "Unknown public key protocol %d", type); goto fail; } *pkey = key; return SSH_OK; fail: ssh_key_free(key); return SSH_ERROR; }
int ssh_pki_import_pubkey_base64(ssh_session session, const char *b64_key, enum ssh_keytypes_e type, ssh_key *pkey) { ssh_buffer buffer; ssh_key key; int rc; key = ssh_key_new(); if (key == NULL) { return SSH_ERROR; } key->type = type; key->type_c = ssh_key_type_to_char(type); key->flags = SSH_KEY_FLAG_PUBLIC; buffer = base64_to_bin(b64_key); switch (type) { case SSH_KEYTYPE_DSS: { ssh_string p; ssh_string q; ssh_string g; ssh_string pubkey; p = buffer_get_ssh_string(buffer); if (p == NULL) { goto fail; } q = buffer_get_ssh_string(buffer); if (q == NULL) { ssh_string_burn(p); ssh_string_free(p); goto fail; } g = buffer_get_ssh_string(buffer); if (g == NULL) { ssh_string_burn(p); ssh_string_free(p); ssh_string_burn(q); ssh_string_free(q); goto fail; } pubkey = buffer_get_ssh_string(buffer); if (g == NULL) { ssh_string_burn(p); ssh_string_free(p); ssh_string_burn(q); ssh_string_free(q); ssh_string_burn(g); ssh_string_free(g); goto fail; } rc = pki_pubkey_build_dss(key, p, q, g, pubkey); #ifdef DEBUG_CRYPTO ssh_print_hexa("p", ssh_string_data(p), ssh_string_len(p)); ssh_print_hexa("q", ssh_string_data(q), ssh_string_len(q)); ssh_print_hexa("g", ssh_string_data(g), ssh_string_len(g)); #endif ssh_string_burn(p); ssh_string_free(p); ssh_string_burn(q); ssh_string_free(q); ssh_string_burn(g); ssh_string_free(g); if (rc == SSH_ERROR) { goto fail; } } break; case SSH_KEYTYPE_RSA: case SSH_KEYTYPE_RSA1: { ssh_string e; ssh_string n; e = buffer_get_ssh_string(buffer); if (e == NULL) { goto fail; } n = buffer_get_ssh_string(buffer); if (n == NULL) { ssh_string_burn(e); ssh_string_free(e); goto fail; } rc = pki_pubkey_build_rsa(key, e, n); #ifdef DEBUG_CRYPTO ssh_print_hexa("e", ssh_string_data(e), ssh_string_len(e)); ssh_print_hexa("n", ssh_string_data(n), ssh_string_len(n)); #endif ssh_string_burn(e); ssh_string_free(e); ssh_string_burn(n); ssh_string_free(n); if (rc == SSH_ERROR) { goto fail; } } break; case SSH_KEYTYPE_ECDSA: case SSH_KEYTYPE_UNKNOWN: ssh_set_error(session, SSH_FATAL, "Unknown public key protocol %d", type); goto fail; } ssh_buffer_free(buffer); *pkey = key; return SSH_OK; fail: ssh_buffer_free(buffer); ssh_key_free(key); return SSH_ERROR; }