1d059297112922cabb0c674840589be8db821fd9aAdam Langley/* $OpenBSD: key.c,v 1.127 2015/01/28 22:36:00 djm Exp $ */
2bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/*
3d059297112922cabb0c674840589be8db821fd9aAdam Langley * placed in the public domain
4bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */
5bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
6bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "includes.h"
7bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
8bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <sys/types.h>
9d059297112922cabb0c674840589be8db821fd9aAdam Langley#include <errno.h>
10bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <stdarg.h>
11bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <stdio.h>
12d059297112922cabb0c674840589be8db821fd9aAdam Langley#include <limits.h>
13bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
14d059297112922cabb0c674840589be8db821fd9aAdam Langley#define SSH_KEY_NO_DEFINE
15bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "key.h"
16bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
17d059297112922cabb0c674840589be8db821fd9aAdam Langley#include "compat.h"
18d059297112922cabb0c674840589be8db821fd9aAdam Langley#include "sshkey.h"
19d059297112922cabb0c674840589be8db821fd9aAdam Langley#include "ssherr.h"
20d059297112922cabb0c674840589be8db821fd9aAdam Langley#include "log.h"
21d059297112922cabb0c674840589be8db821fd9aAdam Langley#include "authfile.h"
22bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
23bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid
24bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmankey_add_private(Key *k)
25bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
26d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
27d059297112922cabb0c674840589be8db821fd9aAdam Langley
28d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_add_private(k)) != 0)
29d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal("%s: %s", __func__, ssh_err(r));
30bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
31bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
32bd77cf78387b72b7b3ea870459077672bf75c3b5Greg HartmanKey *
33bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmankey_new_private(int type)
34bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
35d059297112922cabb0c674840589be8db821fd9aAdam Langley	Key *ret = NULL;
36bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
37d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((ret = sshkey_new_private(type)) == NULL)
38d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal("%s: failed", __func__);
39d059297112922cabb0c674840589be8db821fd9aAdam Langley	return ret;
40bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
41bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
42bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint
43bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmankey_read(Key *ret, char **cpp)
44bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
45d059297112922cabb0c674840589be8db821fd9aAdam Langley	return sshkey_read(ret, cpp) == 0 ? 1 : -1;
46bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
47bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
48bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint
49bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmankey_write(const Key *key, FILE *f)
50bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
51d059297112922cabb0c674840589be8db821fd9aAdam Langley	return sshkey_write(key, f) == 0 ? 1 : 0;
52bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
53bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
54bd77cf78387b72b7b3ea870459077672bf75c3b5Greg HartmanKey *
55bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmankey_generate(int type, u_int bits)
56bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
57d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
58d059297112922cabb0c674840589be8db821fd9aAdam Langley	Key *ret = NULL;
59d059297112922cabb0c674840589be8db821fd9aAdam Langley
60d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_generate(type, bits, &ret)) != 0)
61d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal("%s: %s", __func__, ssh_err(r));
62d059297112922cabb0c674840589be8db821fd9aAdam Langley	return ret;
63bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
64bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
65bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid
66d059297112922cabb0c674840589be8db821fd9aAdam Langleykey_cert_copy(const Key *from_key, Key *to_key)
67bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
68d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
69bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
70d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_cert_copy(from_key, to_key)) != 0)
71d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal("%s: %s", __func__, ssh_err(r));
72bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
73bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
74bd77cf78387b72b7b3ea870459077672bf75c3b5Greg HartmanKey *
75bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmankey_from_private(const Key *k)
76bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
77d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
78d059297112922cabb0c674840589be8db821fd9aAdam Langley	Key *ret = NULL;
79bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
80d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_from_private(k, &ret)) != 0)
81d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal("%s: %s", __func__, ssh_err(r));
82d059297112922cabb0c674840589be8db821fd9aAdam Langley	return ret;
83bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
84bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
85d059297112922cabb0c674840589be8db821fd9aAdam Langleystatic void
86d059297112922cabb0c674840589be8db821fd9aAdam Langleyfatal_on_fatal_errors(int r, const char *func, int extra_fatal)
87bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
88d059297112922cabb0c674840589be8db821fd9aAdam Langley	if (r == SSH_ERR_INTERNAL_ERROR ||
89d059297112922cabb0c674840589be8db821fd9aAdam Langley	    r == SSH_ERR_ALLOC_FAIL ||
90d059297112922cabb0c674840589be8db821fd9aAdam Langley	    (extra_fatal != 0 && r == extra_fatal))
91d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal("%s: %s", func, ssh_err(r));
92bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
93bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
94bd77cf78387b72b7b3ea870459077672bf75c3b5Greg HartmanKey *
95bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmankey_from_blob(const u_char *blob, u_int blen)
96bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
97d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
98d059297112922cabb0c674840589be8db821fd9aAdam Langley	Key *ret = NULL;
99bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
100d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_from_blob(blob, blen, &ret)) != 0) {
101d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal_on_fatal_errors(r, __func__, 0);
102d059297112922cabb0c674840589be8db821fd9aAdam Langley		error("%s: %s", __func__, ssh_err(r));
103d059297112922cabb0c674840589be8db821fd9aAdam Langley		return NULL;
104bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman	}
105d059297112922cabb0c674840589be8db821fd9aAdam Langley	return ret;
106bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
107bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
108bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint
109bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmankey_to_blob(const Key *key, u_char **blobp, u_int *lenp)
110bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
111d059297112922cabb0c674840589be8db821fd9aAdam Langley	u_char *blob;
112d059297112922cabb0c674840589be8db821fd9aAdam Langley	size_t blen;
113d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
114bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
115d059297112922cabb0c674840589be8db821fd9aAdam Langley	if (blobp != NULL)
116d059297112922cabb0c674840589be8db821fd9aAdam Langley		*blobp = NULL;
117d059297112922cabb0c674840589be8db821fd9aAdam Langley	if (lenp != NULL)
118d059297112922cabb0c674840589be8db821fd9aAdam Langley		*lenp = 0;
119d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) {
120d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal_on_fatal_errors(r, __func__, 0);
121d059297112922cabb0c674840589be8db821fd9aAdam Langley		error("%s: %s", __func__, ssh_err(r));
122bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman		return 0;
123bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman	}
124d059297112922cabb0c674840589be8db821fd9aAdam Langley	if (blen > INT_MAX)
125d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal("%s: giant len %zu", __func__, blen);
126d059297112922cabb0c674840589be8db821fd9aAdam Langley	if (blobp != NULL)
127d059297112922cabb0c674840589be8db821fd9aAdam Langley		*blobp = blob;
128bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman	if (lenp != NULL)
129d059297112922cabb0c674840589be8db821fd9aAdam Langley		*lenp = blen;
130d059297112922cabb0c674840589be8db821fd9aAdam Langley	return blen;
131bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
132bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
133bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint
134d059297112922cabb0c674840589be8db821fd9aAdam Langleykey_sign(const Key *key, u_char **sigp, u_int *lenp,
135bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman    const u_char *data, u_int datalen)
136bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
137d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
138d059297112922cabb0c674840589be8db821fd9aAdam Langley	u_char *sig;
139d059297112922cabb0c674840589be8db821fd9aAdam Langley	size_t siglen;
140d059297112922cabb0c674840589be8db821fd9aAdam Langley
141d059297112922cabb0c674840589be8db821fd9aAdam Langley	if (sigp != NULL)
142d059297112922cabb0c674840589be8db821fd9aAdam Langley		*sigp = NULL;
143d059297112922cabb0c674840589be8db821fd9aAdam Langley	if (lenp != NULL)
144d059297112922cabb0c674840589be8db821fd9aAdam Langley		*lenp = 0;
145d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_sign(key, &sig, &siglen,
146d059297112922cabb0c674840589be8db821fd9aAdam Langley	    data, datalen, datafellows)) != 0) {
147d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal_on_fatal_errors(r, __func__, 0);
148d059297112922cabb0c674840589be8db821fd9aAdam Langley		error("%s: %s", __func__, ssh_err(r));
149bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman		return -1;
150bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman	}
151d059297112922cabb0c674840589be8db821fd9aAdam Langley	if (siglen > INT_MAX)
152d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal("%s: giant len %zu", __func__, siglen);
153d059297112922cabb0c674840589be8db821fd9aAdam Langley	if (sigp != NULL)
154d059297112922cabb0c674840589be8db821fd9aAdam Langley		*sigp = sig;
155d059297112922cabb0c674840589be8db821fd9aAdam Langley	if (lenp != NULL)
156d059297112922cabb0c674840589be8db821fd9aAdam Langley		*lenp = siglen;
157d059297112922cabb0c674840589be8db821fd9aAdam Langley	return 0;
158bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
159bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
160bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint
161d059297112922cabb0c674840589be8db821fd9aAdam Langleykey_verify(const Key *key, const u_char *signature, u_int signaturelen,
162bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman    const u_char *data, u_int datalen)
163bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
164d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
165bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
166d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_verify(key, signature, signaturelen,
167d059297112922cabb0c674840589be8db821fd9aAdam Langley	    data, datalen, datafellows)) != 0) {
168d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal_on_fatal_errors(r, __func__, 0);
169d059297112922cabb0c674840589be8db821fd9aAdam Langley		error("%s: %s", __func__, ssh_err(r));
170d059297112922cabb0c674840589be8db821fd9aAdam Langley		return r == SSH_ERR_SIGNATURE_INVALID ? 0 : -1;
171bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman	}
172d059297112922cabb0c674840589be8db821fd9aAdam Langley	return 1;
173bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
174bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
175bd77cf78387b72b7b3ea870459077672bf75c3b5Greg HartmanKey *
176bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmankey_demote(const Key *k)
177bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
178d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
179d059297112922cabb0c674840589be8db821fd9aAdam Langley	Key *ret = NULL;
180bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
181d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_demote(k, &ret)) != 0)
182d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal("%s: %s", __func__, ssh_err(r));
183d059297112922cabb0c674840589be8db821fd9aAdam Langley	return ret;
184bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
185bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
186bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint
187bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmankey_to_certified(Key *k, int legacy)
188bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
189d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
190d059297112922cabb0c674840589be8db821fd9aAdam Langley
191d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_to_certified(k, legacy)) != 0) {
192d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal_on_fatal_errors(r, __func__, 0);
193d059297112922cabb0c674840589be8db821fd9aAdam Langley		error("%s: %s", __func__, ssh_err(r));
194bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman		return -1;
195bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman	}
196d059297112922cabb0c674840589be8db821fd9aAdam Langley	return 0;
197bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
198bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
199bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint
200bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmankey_drop_cert(Key *k)
201bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
202d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
203d059297112922cabb0c674840589be8db821fd9aAdam Langley
204d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_drop_cert(k)) != 0) {
205d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal_on_fatal_errors(r, __func__, 0);
206d059297112922cabb0c674840589be8db821fd9aAdam Langley		error("%s: %s", __func__, ssh_err(r));
207bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman		return -1;
208bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman	}
209d059297112922cabb0c674840589be8db821fd9aAdam Langley	return 0;
210bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
211bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
212bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint
213bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmankey_certify(Key *k, Key *ca)
214bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
215d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
216bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
217d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_certify(k, ca)) != 0) {
218d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal_on_fatal_errors(r, __func__, 0);
219d059297112922cabb0c674840589be8db821fd9aAdam Langley		error("%s: %s", __func__, ssh_err(r));
220bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman		return -1;
221bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman	}
222bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman	return 0;
223bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
224bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
225bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint
226bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmankey_cert_check_authority(const Key *k, int want_host, int require_principal,
227bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman    const char *name, const char **reason)
228bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
229d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
230bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
231d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_cert_check_authority(k, want_host, require_principal,
232d059297112922cabb0c674840589be8db821fd9aAdam Langley	    name, reason)) != 0) {
233d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal_on_fatal_errors(r, __func__, 0);
234d059297112922cabb0c674840589be8db821fd9aAdam Langley		error("%s: %s", __func__, ssh_err(r));
235bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman		return -1;
236bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman	}
237bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman	return 0;
238bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
239bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
240d059297112922cabb0c674840589be8db821fd9aAdam Langley#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
241bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint
242d059297112922cabb0c674840589be8db821fd9aAdam Langleykey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
243bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
244d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
245d059297112922cabb0c674840589be8db821fd9aAdam Langley
246d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_ec_validate_public(group, public)) != 0) {
247d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
248d059297112922cabb0c674840589be8db821fd9aAdam Langley		error("%s: %s", __func__, ssh_err(r));
249d059297112922cabb0c674840589be8db821fd9aAdam Langley		return -1;
250bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman	}
251d059297112922cabb0c674840589be8db821fd9aAdam Langley	return 0;
252bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
253bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
254bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint
255d059297112922cabb0c674840589be8db821fd9aAdam Langleykey_ec_validate_private(const EC_KEY *key)
256bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
257d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
258bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
259d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_ec_validate_private(key)) != 0) {
260d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
261d059297112922cabb0c674840589be8db821fd9aAdam Langley		error("%s: %s", __func__, ssh_err(r));
262d059297112922cabb0c674840589be8db821fd9aAdam Langley		return -1;
263bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman	}
264d059297112922cabb0c674840589be8db821fd9aAdam Langley	return 0;
265bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
266d059297112922cabb0c674840589be8db821fd9aAdam Langley#endif /* WITH_OPENSSL */
267bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
268d059297112922cabb0c674840589be8db821fd9aAdam Langleyvoid
269d059297112922cabb0c674840589be8db821fd9aAdam Langleykey_private_serialize(const Key *key, struct sshbuf *b)
270bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
271d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
272d059297112922cabb0c674840589be8db821fd9aAdam Langley
273d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_private_serialize(key, b)) != 0)
274d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal("%s: %s", __func__, ssh_err(r));
275bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
276bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
277d059297112922cabb0c674840589be8db821fd9aAdam LangleyKey *
278d059297112922cabb0c674840589be8db821fd9aAdam Langleykey_private_deserialize(struct sshbuf *blob)
279bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
280d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
281d059297112922cabb0c674840589be8db821fd9aAdam Langley	Key *ret = NULL;
282bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
283d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_private_deserialize(blob, &ret)) != 0) {
284d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
285d059297112922cabb0c674840589be8db821fd9aAdam Langley		error("%s: %s", __func__, ssh_err(r));
286d059297112922cabb0c674840589be8db821fd9aAdam Langley		return NULL;
287d059297112922cabb0c674840589be8db821fd9aAdam Langley	}
288d059297112922cabb0c674840589be8db821fd9aAdam Langley	return ret;
289bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
290bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
291d059297112922cabb0c674840589be8db821fd9aAdam Langley/* authfile.c */
292d059297112922cabb0c674840589be8db821fd9aAdam Langley
293bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint
294d059297112922cabb0c674840589be8db821fd9aAdam Langleykey_save_private(Key *key, const char *filename, const char *passphrase,
295d059297112922cabb0c674840589be8db821fd9aAdam Langley    const char *comment, int force_new_format, const char *new_format_cipher,
296d059297112922cabb0c674840589be8db821fd9aAdam Langley    int new_format_rounds)
297bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
298d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
299bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
300d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_save_private(key, filename, passphrase, comment,
301d059297112922cabb0c674840589be8db821fd9aAdam Langley	    force_new_format, new_format_cipher, new_format_rounds)) != 0) {
302d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
303d059297112922cabb0c674840589be8db821fd9aAdam Langley		error("%s: %s", __func__, ssh_err(r));
304d059297112922cabb0c674840589be8db821fd9aAdam Langley		return 0;
305bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman	}
306d059297112922cabb0c674840589be8db821fd9aAdam Langley	return 1;
307d059297112922cabb0c674840589be8db821fd9aAdam Langley}
308bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
309d059297112922cabb0c674840589be8db821fd9aAdam Langleyint
310d059297112922cabb0c674840589be8db821fd9aAdam Langleykey_load_file(int fd, const char *filename, struct sshbuf *blob)
311d059297112922cabb0c674840589be8db821fd9aAdam Langley{
312d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
313bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
314d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_load_file(fd, blob)) != 0) {
315d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
316d059297112922cabb0c674840589be8db821fd9aAdam Langley		error("%s: %s", __func__, ssh_err(r));
317d059297112922cabb0c674840589be8db821fd9aAdam Langley		return 0;
318bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman	}
319d059297112922cabb0c674840589be8db821fd9aAdam Langley	return 1;
320d059297112922cabb0c674840589be8db821fd9aAdam Langley}
321bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
322d059297112922cabb0c674840589be8db821fd9aAdam LangleyKey *
323d059297112922cabb0c674840589be8db821fd9aAdam Langleykey_load_cert(const char *filename)
324d059297112922cabb0c674840589be8db821fd9aAdam Langley{
325d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
326d059297112922cabb0c674840589be8db821fd9aAdam Langley	Key *ret = NULL;
327bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
328d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_load_cert(filename, &ret)) != 0) {
329d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
330d059297112922cabb0c674840589be8db821fd9aAdam Langley		/* Old authfile.c ignored all file errors. */
331d059297112922cabb0c674840589be8db821fd9aAdam Langley		if (r == SSH_ERR_SYSTEM_ERROR)
332d059297112922cabb0c674840589be8db821fd9aAdam Langley			debug("%s: %s", __func__, ssh_err(r));
333d059297112922cabb0c674840589be8db821fd9aAdam Langley		else
334d059297112922cabb0c674840589be8db821fd9aAdam Langley			error("%s: %s", __func__, ssh_err(r));
335d059297112922cabb0c674840589be8db821fd9aAdam Langley		return NULL;
336bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman	}
337bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman	return ret;
338d059297112922cabb0c674840589be8db821fd9aAdam Langley
339bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
340bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
341d059297112922cabb0c674840589be8db821fd9aAdam LangleyKey *
342d059297112922cabb0c674840589be8db821fd9aAdam Langleykey_load_public(const char *filename, char **commentp)
343bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
344d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
345d059297112922cabb0c674840589be8db821fd9aAdam Langley	Key *ret = NULL;
346bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
347d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_load_public(filename, &ret, commentp)) != 0) {
348d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
349d059297112922cabb0c674840589be8db821fd9aAdam Langley		/* Old authfile.c ignored all file errors. */
350d059297112922cabb0c674840589be8db821fd9aAdam Langley		if (r == SSH_ERR_SYSTEM_ERROR)
351d059297112922cabb0c674840589be8db821fd9aAdam Langley			debug("%s: %s", __func__, ssh_err(r));
352d059297112922cabb0c674840589be8db821fd9aAdam Langley		else
353d059297112922cabb0c674840589be8db821fd9aAdam Langley			error("%s: %s", __func__, ssh_err(r));
354d059297112922cabb0c674840589be8db821fd9aAdam Langley		return NULL;
355bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman	}
356d059297112922cabb0c674840589be8db821fd9aAdam Langley	return ret;
357d059297112922cabb0c674840589be8db821fd9aAdam Langley}
358bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
359d059297112922cabb0c674840589be8db821fd9aAdam LangleyKey *
360d059297112922cabb0c674840589be8db821fd9aAdam Langleykey_load_private(const char *path, const char *passphrase,
361d059297112922cabb0c674840589be8db821fd9aAdam Langley    char **commentp)
362d059297112922cabb0c674840589be8db821fd9aAdam Langley{
363d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
364d059297112922cabb0c674840589be8db821fd9aAdam Langley	Key *ret = NULL;
365d059297112922cabb0c674840589be8db821fd9aAdam Langley
366d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_load_private(path, passphrase, &ret, commentp)) != 0) {
367d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
368d059297112922cabb0c674840589be8db821fd9aAdam Langley		/* Old authfile.c ignored all file errors. */
369d059297112922cabb0c674840589be8db821fd9aAdam Langley		if (r == SSH_ERR_SYSTEM_ERROR ||
370d059297112922cabb0c674840589be8db821fd9aAdam Langley		    r == SSH_ERR_KEY_WRONG_PASSPHRASE)
371d059297112922cabb0c674840589be8db821fd9aAdam Langley			debug("%s: %s", __func__, ssh_err(r));
372d059297112922cabb0c674840589be8db821fd9aAdam Langley		else
373d059297112922cabb0c674840589be8db821fd9aAdam Langley			error("%s: %s", __func__, ssh_err(r));
374d059297112922cabb0c674840589be8db821fd9aAdam Langley		return NULL;
375bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman	}
376bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman	return ret;
377bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
378bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
379d059297112922cabb0c674840589be8db821fd9aAdam LangleyKey *
380d059297112922cabb0c674840589be8db821fd9aAdam Langleykey_load_private_cert(int type, const char *filename, const char *passphrase,
381d059297112922cabb0c674840589be8db821fd9aAdam Langley    int *perm_ok)
382d059297112922cabb0c674840589be8db821fd9aAdam Langley{
383d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
384d059297112922cabb0c674840589be8db821fd9aAdam Langley	Key *ret = NULL;
385d059297112922cabb0c674840589be8db821fd9aAdam Langley
386d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_load_private_cert(type, filename, passphrase,
387d059297112922cabb0c674840589be8db821fd9aAdam Langley	    &ret, perm_ok)) != 0) {
388d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
389d059297112922cabb0c674840589be8db821fd9aAdam Langley		/* Old authfile.c ignored all file errors. */
390d059297112922cabb0c674840589be8db821fd9aAdam Langley		if (r == SSH_ERR_SYSTEM_ERROR ||
391d059297112922cabb0c674840589be8db821fd9aAdam Langley		    r == SSH_ERR_KEY_WRONG_PASSPHRASE)
392d059297112922cabb0c674840589be8db821fd9aAdam Langley			debug("%s: %s", __func__, ssh_err(r));
393d059297112922cabb0c674840589be8db821fd9aAdam Langley		else
394d059297112922cabb0c674840589be8db821fd9aAdam Langley			error("%s: %s", __func__, ssh_err(r));
395d059297112922cabb0c674840589be8db821fd9aAdam Langley		return NULL;
396d059297112922cabb0c674840589be8db821fd9aAdam Langley	}
397d059297112922cabb0c674840589be8db821fd9aAdam Langley	return ret;
398d059297112922cabb0c674840589be8db821fd9aAdam Langley}
399bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
400d059297112922cabb0c674840589be8db821fd9aAdam LangleyKey *
401d059297112922cabb0c674840589be8db821fd9aAdam Langleykey_load_private_type(int type, const char *filename, const char *passphrase,
402d059297112922cabb0c674840589be8db821fd9aAdam Langley    char **commentp, int *perm_ok)
403d059297112922cabb0c674840589be8db821fd9aAdam Langley{
404d059297112922cabb0c674840589be8db821fd9aAdam Langley	int r;
405d059297112922cabb0c674840589be8db821fd9aAdam Langley	Key *ret = NULL;
406d059297112922cabb0c674840589be8db821fd9aAdam Langley
407d059297112922cabb0c674840589be8db821fd9aAdam Langley	if ((r = sshkey_load_private_type(type, filename, passphrase,
408d059297112922cabb0c674840589be8db821fd9aAdam Langley	    &ret, commentp, perm_ok)) != 0) {
409d059297112922cabb0c674840589be8db821fd9aAdam Langley		fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
410d059297112922cabb0c674840589be8db821fd9aAdam Langley		/* Old authfile.c ignored all file errors. */
411d059297112922cabb0c674840589be8db821fd9aAdam Langley		if (r == SSH_ERR_SYSTEM_ERROR ||
412d059297112922cabb0c674840589be8db821fd9aAdam Langley		    (r == SSH_ERR_KEY_WRONG_PASSPHRASE))
413d059297112922cabb0c674840589be8db821fd9aAdam Langley			debug("%s: %s", __func__, ssh_err(r));
414d059297112922cabb0c674840589be8db821fd9aAdam Langley		else
415d059297112922cabb0c674840589be8db821fd9aAdam Langley			error("%s: %s", __func__, ssh_err(r));
416d059297112922cabb0c674840589be8db821fd9aAdam Langley		return NULL;
417bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman	}
418d059297112922cabb0c674840589be8db821fd9aAdam Langley	return ret;
419bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
420bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman
421d059297112922cabb0c674840589be8db821fd9aAdam Langleyint
422d059297112922cabb0c674840589be8db821fd9aAdam Langleykey_perm_ok(int fd, const char *filename)
423bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{
424d059297112922cabb0c674840589be8db821fd9aAdam Langley	return sshkey_perm_ok(fd, filename) == 0 ? 1 : 0;
425bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}
426d059297112922cabb0c674840589be8db821fd9aAdam Langley
427