/** * @brief returns the ECDSA key name ("ecdsa-sha2-nistp256" for example) * * @param[in] key the ssh_key whose ECDSA name to get * * @returns the ECDSA key name ("ecdsa-sha2-nistp256" for example) * * @returns "unknown" if the ECDSA key name is not known */ const char *ssh_pki_key_ecdsa_name(const ssh_key key) { #ifdef HAVE_ECC /* FIXME Better ECC check needed */ return pki_key_ecdsa_nid_to_name(key->ecdsa_nid); #else (void) key; /* unused */ return NULL; #endif }
int pki_pubkey_build_ecdsa(ssh_key key, int nid, ssh_string e) { EC_POINT *p; const EC_GROUP *g; int ok; key->ecdsa_nid = nid; key->type_c = pki_key_ecdsa_nid_to_name(nid); key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid); if (key->ecdsa == NULL) { return -1; } g = EC_KEY_get0_group(key->ecdsa); p = EC_POINT_new(g); if (p == NULL) { return -1; } ok = EC_POINT_oct2point(g, p, ssh_string_data(e), ssh_string_len(e), NULL); if (!ok) { EC_POINT_free(p); return -1; } /* EC_KEY_set_public_key duplicates p */ ok = EC_KEY_set_public_key(key->ecdsa, p); EC_POINT_free(p); if (!ok) { return -1; } return 0; }
ssh_key pki_private_key_from_base64(const char *b64_key, const char *passphrase, ssh_auth_callback auth_fn, void *auth_data) { ssh_key key = NULL; mbedtls_pk_context *rsa = NULL; mbedtls_pk_context *ecdsa = NULL; ed25519_privkey *ed25519 = NULL; enum ssh_keytypes_e type; int valid; /* mbedtls pk_parse_key expects strlen to count the 0 byte */ size_t b64len = strlen(b64_key) + 1; unsigned char tmp[MAX_PASSPHRASE_SIZE] = {0}; type = pki_privatekey_type_from_string(b64_key); if (type == SSH_KEYTYPE_UNKNOWN) { SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key."); return NULL; } switch (type) { case SSH_KEYTYPE_RSA: rsa = malloc(sizeof(mbedtls_pk_context)); if (rsa == NULL) { return NULL; } mbedtls_pk_init(rsa); if (passphrase == NULL) { if (auth_fn) { valid = auth_fn("Passphrase for private key:", (char *) tmp, MAX_PASSPHRASE_SIZE, 0, 0, auth_data); if (valid < 0) { return NULL; } /* TODO fix signedness and strlen */ valid = mbedtls_pk_parse_key(rsa, (const unsigned char *) b64_key, b64len, tmp, strnlen((const char *) tmp, MAX_PASSPHRASE_SIZE)); } else { valid = mbedtls_pk_parse_key(rsa, (const unsigned char *) b64_key, b64len, NULL, 0); } } else { valid = mbedtls_pk_parse_key(rsa, (const unsigned char *) b64_key, b64len, (const unsigned char *) passphrase, strnlen(passphrase, MAX_PASSPHRASE_SIZE)); } if (valid != 0) { char error_buf[100]; mbedtls_strerror(valid, error_buf, 100); SSH_LOG(SSH_LOG_WARN,"Parsing private key %s", error_buf); goto fail; } break; case SSH_KEYTYPE_ECDSA: ecdsa = malloc(sizeof(mbedtls_pk_context)); if (ecdsa == NULL) { return NULL; } mbedtls_pk_init(ecdsa); if (passphrase == NULL) { if (auth_fn) { valid = auth_fn("Passphrase for private key:", (char *) tmp, MAX_PASSPHRASE_SIZE, 0, 0, auth_data); if (valid < 0) { return NULL; } valid = mbedtls_pk_parse_key(ecdsa, (const unsigned char *) b64_key, b64len, tmp, strnlen((const char *) tmp, MAX_PASSPHRASE_SIZE)); } else { valid = mbedtls_pk_parse_key(ecdsa, (const unsigned char *) b64_key, b64len, NULL, 0); } } else { valid = mbedtls_pk_parse_key(ecdsa, (const unsigned char *) b64_key, b64len, (const unsigned char *) passphrase, strnlen(passphrase, MAX_PASSPHRASE_SIZE)); } if (valid != 0) { char error_buf[100]; mbedtls_strerror(valid, error_buf, 100); SSH_LOG(SSH_LOG_WARN,"Parsing private key %s", error_buf); goto fail; } break; case SSH_KEYTYPE_ED25519: /* Cannot open ed25519 keys with libmbedcrypto */ default: SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key type %d", type); return NULL; } key = ssh_key_new(); if (key == NULL) { goto fail; } key->type = type; key->type_c = ssh_key_type_to_char(type); key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC; key->rsa = rsa; if (ecdsa != NULL) { mbedtls_ecp_keypair *keypair = mbedtls_pk_ec(*ecdsa); key->ecdsa = malloc(sizeof(mbedtls_ecdsa_context)); if (key->ecdsa == NULL) { goto fail; } mbedtls_ecdsa_init(key->ecdsa); mbedtls_ecdsa_from_keypair(key->ecdsa, keypair); mbedtls_pk_free(ecdsa); SAFE_FREE(ecdsa); } else { key->ecdsa = NULL; } key->ed25519_privkey = ed25519; rsa = NULL; ecdsa = NULL; if (key->type == SSH_KEYTYPE_ECDSA) { key->ecdsa_nid = pki_key_ecdsa_to_nid(key->ecdsa); key->type_c = pki_key_ecdsa_nid_to_name(key->ecdsa_nid); } return key; fail: ssh_key_free(key); if (rsa != NULL) { mbedtls_pk_free(rsa); SAFE_FREE(rsa); } if (ecdsa != NULL) { mbedtls_pk_free(ecdsa); SAFE_FREE(ecdsa); } return NULL; }