1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-30 12:04:07 +00:00
freebsd/crypto/openssh/key.c

427 lines
8.4 KiB
C
Raw Normal View History

2016-03-10 20:10:25 +00:00
/* $OpenBSD: key.c,v 1.129 2015/12/04 16:41:28 markus Exp $ */
/*
2015-01-05 16:09:55 +00:00
* placed in the public domain
*/
2006-09-30 13:29:51 +00:00
#include "includes.h"
2006-09-30 13:29:51 +00:00
#include <sys/types.h>
2015-01-05 16:09:55 +00:00
#include <errno.h>
2006-09-30 13:29:51 +00:00
#include <stdarg.h>
#include <stdio.h>
2015-07-02 13:15:34 +00:00
#include <limits.h>
2006-09-30 13:29:51 +00:00
2015-01-05 16:09:55 +00:00
#define SSH_KEY_NO_DEFINE
#include "key.h"
2010-03-08 11:19:52 +00:00
2015-01-05 16:09:55 +00:00
#include "compat.h"
#include "sshkey.h"
#include "ssherr.h"
#include "log.h"
#include "authfile.h"
2002-06-29 11:34:13 +00:00
2010-03-08 11:19:52 +00:00
void
key_add_private(Key *k)
{
2015-01-05 16:09:55 +00:00
int r;
if ((r = sshkey_add_private(k)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
2010-03-08 11:19:52 +00:00
}
Key *
key_new_private(int type)
{
2015-01-05 16:09:55 +00:00
Key *ret = NULL;
2011-02-17 11:47:40 +00:00
2015-01-05 16:09:55 +00:00
if ((ret = sshkey_new_private(type)) == NULL)
fatal("%s: failed", __func__);
return ret;
2010-03-08 11:19:52 +00:00
}
int
2000-05-15 04:37:24 +00:00
key_read(Key *ret, char **cpp)
{
2015-01-05 16:09:55 +00:00
return sshkey_read(ret, cpp) == 0 ? 1 : -1;
}
2002-06-29 11:34:13 +00:00
int
2004-02-26 10:38:49 +00:00
key_write(const Key *key, FILE *f)
{
2015-01-05 16:09:55 +00:00
return sshkey_write(key, f) == 0 ? 1 : 0;
}
Key *
key_generate(int type, u_int bits)
{
2015-01-05 16:09:55 +00:00
int r;
Key *ret = NULL;
if ((r = sshkey_generate(type, bits, &ret)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
return ret;
}
2010-03-08 11:19:52 +00:00
void
2015-01-05 16:09:55 +00:00
key_cert_copy(const Key *from_key, Key *to_key)
2010-03-08 11:19:52 +00:00
{
2015-01-05 16:09:55 +00:00
int r;
2010-03-08 11:19:52 +00:00
2015-01-05 16:09:55 +00:00
if ((r = sshkey_cert_copy(from_key, to_key)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
2010-03-08 11:19:52 +00:00
}
Key *
2004-02-26 10:38:49 +00:00
key_from_private(const Key *k)
{
2015-01-05 16:09:55 +00:00
int r;
Key *ret = NULL;
2010-03-08 11:19:52 +00:00
2015-01-05 16:09:55 +00:00
if ((r = sshkey_from_private(k, &ret)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
2010-03-08 11:19:52 +00:00
return ret;
}
2015-01-05 16:09:55 +00:00
static void
fatal_on_fatal_errors(int r, const char *func, int extra_fatal)
{
2015-01-05 16:09:55 +00:00
if (r == SSH_ERR_INTERNAL_ERROR ||
r == SSH_ERR_ALLOC_FAIL ||
(extra_fatal != 0 && r == extra_fatal))
fatal("%s: %s", func, ssh_err(r));
}
2014-01-30 10:56:49 +00:00
Key *
key_from_blob(const u_char *blob, u_int blen)
{
2015-01-05 16:09:55 +00:00
int r;
Key *ret = NULL;
if ((r = sshkey_from_blob(blob, blen, &ret)) != 0) {
fatal_on_fatal_errors(r, __func__, 0);
error("%s: %s", __func__, ssh_err(r));
return NULL;
}
return ret;
2014-01-30 10:56:49 +00:00
}
2015-01-05 16:09:55 +00:00
int
key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
{
2015-01-05 16:09:55 +00:00
u_char *blob;
size_t blen;
int r;
2014-01-30 10:56:49 +00:00
if (blobp != NULL)
*blobp = NULL;
if (lenp != NULL)
*lenp = 0;
2015-01-05 16:09:55 +00:00
if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) {
fatal_on_fatal_errors(r, __func__, 0);
error("%s: %s", __func__, ssh_err(r));
2002-03-18 09:55:03 +00:00
return 0;
}
2015-01-05 16:09:55 +00:00
if (blen > INT_MAX)
fatal("%s: giant len %zu", __func__, blen);
if (blobp != NULL)
*blobp = blob;
if (lenp != NULL)
2015-01-05 16:09:55 +00:00
*lenp = blen;
return blen;
2013-03-22 11:19:48 +00:00
}
int
2015-01-05 16:09:55 +00:00
key_sign(const Key *key, u_char **sigp, u_int *lenp,
2016-03-10 20:10:25 +00:00
const u_char *data, u_int datalen, const char *alg)
{
2015-01-05 16:09:55 +00:00
int r;
u_char *sig;
size_t siglen;
if (sigp != NULL)
*sigp = NULL;
if (lenp != NULL)
*lenp = 0;
if ((r = sshkey_sign(key, &sig, &siglen,
2016-03-10 20:10:25 +00:00
data, datalen, alg, datafellows)) != 0) {
2015-01-05 16:09:55 +00:00
fatal_on_fatal_errors(r, __func__, 0);
error("%s: %s", __func__, ssh_err(r));
return -1;
}
2015-01-05 16:09:55 +00:00
if (siglen > INT_MAX)
fatal("%s: giant len %zu", __func__, siglen);
if (sigp != NULL)
*sigp = sig;
if (lenp != NULL)
*lenp = siglen;
return 0;
}
int
2015-01-05 16:09:55 +00:00
key_verify(const Key *key, const u_char *signature, u_int signaturelen,
2004-02-26 10:38:49 +00:00
const u_char *data, u_int datalen)
{
2015-01-05 16:09:55 +00:00
int r;
2002-03-18 09:55:03 +00:00
2015-01-05 16:09:55 +00:00
if ((r = sshkey_verify(key, signature, signaturelen,
data, datalen, datafellows)) != 0) {
fatal_on_fatal_errors(r, __func__, 0);
error("%s: %s", __func__, ssh_err(r));
return r == SSH_ERR_SIGNATURE_INVALID ? 0 : -1;
}
2015-01-05 16:09:55 +00:00
return 1;
}
2002-06-23 14:01:54 +00:00
Key *
2004-02-26 10:38:49 +00:00
key_demote(const Key *k)
2002-06-23 14:01:54 +00:00
{
2015-01-05 16:09:55 +00:00
int r;
Key *ret = NULL;
2010-03-08 11:19:52 +00:00
2015-01-05 16:09:55 +00:00
if ((r = sshkey_demote(k, &ret)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
return ret;
2010-03-08 11:19:52 +00:00
}
int
2015-08-26 09:25:17 +00:00
key_to_certified(Key *k)
2010-03-08 11:19:52 +00:00
{
2015-01-05 16:09:55 +00:00
int r;
2015-08-26 09:25:17 +00:00
if ((r = sshkey_to_certified(k)) != 0) {
2015-01-05 16:09:55 +00:00
fatal_on_fatal_errors(r, __func__, 0);
error("%s: %s", __func__, ssh_err(r));
2010-03-08 11:19:52 +00:00
return -1;
}
2015-01-05 16:09:55 +00:00
return 0;
2010-03-08 11:19:52 +00:00
}
int
key_drop_cert(Key *k)
{
2015-01-05 16:09:55 +00:00
int r;
if ((r = sshkey_drop_cert(k)) != 0) {
fatal_on_fatal_errors(r, __func__, 0);
error("%s: %s", __func__, ssh_err(r));
2010-03-08 11:19:52 +00:00
return -1;
}
2014-01-30 10:56:49 +00:00
return 0;
2010-03-08 11:19:52 +00:00
}
int
key_certify(Key *k, Key *ca)
{
2015-01-05 16:09:55 +00:00
int r;
2010-03-08 11:19:52 +00:00
2015-01-05 16:09:55 +00:00
if ((r = sshkey_certify(k, ca)) != 0) {
fatal_on_fatal_errors(r, __func__, 0);
error("%s: %s", __func__, ssh_err(r));
2010-03-08 11:19:52 +00:00
return -1;
}
return 0;
}
int
key_cert_check_authority(const Key *k, int want_host, int require_principal,
const char *name, const char **reason)
{
2015-01-05 16:09:55 +00:00
int r;
if ((r = sshkey_cert_check_authority(k, want_host, require_principal,
name, reason)) != 0) {
fatal_on_fatal_errors(r, __func__, 0);
error("%s: %s", __func__, ssh_err(r));
2010-03-08 11:19:52 +00:00
return -1;
}
return 0;
}
2010-11-08 10:45:44 +00:00
2015-01-05 16:09:55 +00:00
#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
2010-11-08 10:45:44 +00:00
int
2015-01-05 16:09:55 +00:00
key_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
2010-11-08 10:45:44 +00:00
{
2015-01-05 16:09:55 +00:00
int r;
if ((r = sshkey_ec_validate_public(group, public)) != 0) {
fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
error("%s: %s", __func__, ssh_err(r));
return -1;
2010-11-08 10:45:44 +00:00
}
2015-01-05 16:09:55 +00:00
return 0;
2010-11-08 10:45:44 +00:00
}
2011-02-17 11:47:40 +00:00
int
2015-01-05 16:09:55 +00:00
key_ec_validate_private(const EC_KEY *key)
2011-02-17 11:47:40 +00:00
{
2015-01-05 16:09:55 +00:00
int r;
if ((r = sshkey_ec_validate_private(key)) != 0) {
fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
error("%s: %s", __func__, ssh_err(r));
return -1;
}
return 0;
2011-02-17 11:47:40 +00:00
}
2015-01-05 16:09:55 +00:00
#endif /* WITH_OPENSSL */
2011-02-17 11:47:40 +00:00
2015-01-05 16:09:55 +00:00
void
key_private_serialize(const Key *key, struct sshbuf *b)
2011-02-17 11:47:40 +00:00
{
2015-01-05 16:09:55 +00:00
int r;
if ((r = sshkey_private_serialize(key, b)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
2011-02-17 11:47:40 +00:00
}
2015-01-05 16:09:55 +00:00
Key *
key_private_deserialize(struct sshbuf *blob)
2011-02-17 11:47:40 +00:00
{
2015-01-05 16:09:55 +00:00
int r;
Key *ret = NULL;
if ((r = sshkey_private_deserialize(blob, &ret)) != 0) {
fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
error("%s: %s", __func__, ssh_err(r));
return NULL;
}
return ret;
2011-02-17 11:47:40 +00:00
}
2015-01-05 16:09:55 +00:00
/* authfile.c */
2014-01-30 10:56:49 +00:00
int
2015-01-05 16:09:55 +00:00
key_save_private(Key *key, const char *filename, const char *passphrase,
const char *comment, int force_new_format, const char *new_format_cipher,
int new_format_rounds)
2011-02-17 11:47:40 +00:00
{
2015-01-05 16:09:55 +00:00
int r;
if ((r = sshkey_save_private(key, filename, passphrase, comment,
force_new_format, new_format_cipher, new_format_rounds)) != 0) {
fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
error("%s: %s", __func__, ssh_err(r));
return 0;
}
return 1;
2011-02-17 11:47:40 +00:00
}
int
2015-01-05 16:09:55 +00:00
key_load_file(int fd, const char *filename, struct sshbuf *blob)
2011-02-17 11:47:40 +00:00
{
2015-01-05 16:09:55 +00:00
int r;
2011-02-17 11:47:40 +00:00
2015-07-02 13:15:34 +00:00
if ((r = sshkey_load_file(fd, blob)) != 0) {
2015-01-05 16:09:55 +00:00
fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
error("%s: %s", __func__, ssh_err(r));
return 0;
2011-02-17 11:47:40 +00:00
}
2015-01-05 16:09:55 +00:00
return 1;
}
2011-02-17 11:47:40 +00:00
2015-01-05 16:09:55 +00:00
Key *
key_load_cert(const char *filename)
{
int r;
Key *ret = NULL;
if ((r = sshkey_load_cert(filename, &ret)) != 0) {
fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
/* Old authfile.c ignored all file errors. */
if (r == SSH_ERR_SYSTEM_ERROR)
debug("%s: %s", __func__, ssh_err(r));
else
error("%s: %s", __func__, ssh_err(r));
return NULL;
2011-02-17 11:47:40 +00:00
}
2015-01-05 16:09:55 +00:00
return ret;
2011-02-17 11:47:40 +00:00
2015-01-05 16:09:55 +00:00
}
2011-02-17 11:47:40 +00:00
2015-01-05 16:09:55 +00:00
Key *
key_load_public(const char *filename, char **commentp)
{
int r;
Key *ret = NULL;
if ((r = sshkey_load_public(filename, &ret, commentp)) != 0) {
fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
/* Old authfile.c ignored all file errors. */
if (r == SSH_ERR_SYSTEM_ERROR)
debug("%s: %s", __func__, ssh_err(r));
else
error("%s: %s", __func__, ssh_err(r));
return NULL;
2011-02-17 11:47:40 +00:00
}
return ret;
}
2015-01-05 16:09:55 +00:00
Key *
key_load_private(const char *path, const char *passphrase,
char **commentp)
{
int r;
Key *ret = NULL;
if ((r = sshkey_load_private(path, passphrase, &ret, commentp)) != 0) {
fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
/* Old authfile.c ignored all file errors. */
if (r == SSH_ERR_SYSTEM_ERROR ||
r == SSH_ERR_KEY_WRONG_PASSPHRASE)
debug("%s: %s", __func__, ssh_err(r));
else
error("%s: %s", __func__, ssh_err(r));
return NULL;
2011-02-17 11:47:40 +00:00
}
2015-01-05 16:09:55 +00:00
return ret;
}
2011-02-17 11:47:40 +00:00
2015-01-05 16:09:55 +00:00
Key *
key_load_private_cert(int type, const char *filename, const char *passphrase,
int *perm_ok)
{
int r;
Key *ret = NULL;
if ((r = sshkey_load_private_cert(type, filename, passphrase,
&ret, perm_ok)) != 0) {
fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
/* Old authfile.c ignored all file errors. */
if (r == SSH_ERR_SYSTEM_ERROR ||
r == SSH_ERR_KEY_WRONG_PASSPHRASE)
debug("%s: %s", __func__, ssh_err(r));
else
error("%s: %s", __func__, ssh_err(r));
return NULL;
2011-02-17 11:47:40 +00:00
}
return ret;
}
2015-01-05 16:09:55 +00:00
Key *
key_load_private_type(int type, const char *filename, const char *passphrase,
char **commentp, int *perm_ok)
{
int r;
Key *ret = NULL;
if ((r = sshkey_load_private_type(type, filename, passphrase,
&ret, commentp, perm_ok)) != 0) {
fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
/* Old authfile.c ignored all file errors. */
if (r == SSH_ERR_SYSTEM_ERROR ||
(r == SSH_ERR_KEY_WRONG_PASSPHRASE))
debug("%s: %s", __func__, ssh_err(r));
else
error("%s: %s", __func__, ssh_err(r));
return NULL;
2011-02-17 11:47:40 +00:00
}
2015-01-05 16:09:55 +00:00
return ret;
2011-02-17 11:47:40 +00:00
}
2015-01-05 16:09:55 +00:00
int
key_perm_ok(int fd, const char *filename)
2014-01-30 10:56:49 +00:00
{
2015-01-05 16:09:55 +00:00
return sshkey_perm_ok(fd, filename) == 0 ? 1 : 0;
2014-01-30 10:56:49 +00:00
}