GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/ssh/lib/../key.c Lines: 20 115 17.4 %
Date: 2017-11-07 Branches: 8 60 13.3 %

Line Branch Exec Source
1
/* $OpenBSD: key.c,v 1.131 2017/05/30 14:16:41 markus Exp $ */
2
/*
3
 * placed in the public domain
4
 */
5
6
#include <sys/types.h>
7
#include <errno.h>
8
#include <stdarg.h>
9
#include <stdio.h>
10
#include <limits.h>
11
12
#define SSH_KEY_NO_DEFINE
13
#include "key.h"
14
15
#include "compat.h"
16
#include "sshkey.h"
17
#include "ssherr.h"
18
#include "log.h"
19
#include "authfile.h"
20
21
static void
22
fatal_on_fatal_errors(int r, const char *func, int extra_fatal)
23
{
24

144
	if (r == SSH_ERR_INTERNAL_ERROR ||
25
36
	    r == SSH_ERR_ALLOC_FAIL ||
26
72
	    (extra_fatal != 0 && r == extra_fatal))
27
		fatal("%s: %s", func, ssh_err(r));
28
36
}
29
30
Key *
31
key_from_blob(const u_char *blob, u_int blen)
32
{
33
	int r;
34
	Key *ret = NULL;
35
36
	if ((r = sshkey_from_blob(blob, blen, &ret)) != 0) {
37
		fatal_on_fatal_errors(r, __func__, 0);
38
		error("%s: %s", __func__, ssh_err(r));
39
		return NULL;
40
	}
41
	return ret;
42
}
43
44
int
45
key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
46
{
47
	u_char *blob;
48
	size_t blen;
49
	int r;
50
51
	if (blobp != NULL)
52
		*blobp = NULL;
53
	if (lenp != NULL)
54
		*lenp = 0;
55
	if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) {
56
		fatal_on_fatal_errors(r, __func__, 0);
57
		error("%s: %s", __func__, ssh_err(r));
58
		return 0;
59
	}
60
	if (blen > INT_MAX)
61
		fatal("%s: giant len %zu", __func__, blen);
62
	if (blobp != NULL)
63
		*blobp = blob;
64
	if (lenp != NULL)
65
		*lenp = blen;
66
	return blen;
67
}
68
69
int
70
key_sign(const Key *key, u_char **sigp, u_int *lenp,
71
    const u_char *data, u_int datalen, const char *alg)
72
{
73
	int r;
74
	u_char *sig;
75
	size_t siglen;
76
77
	if (sigp != NULL)
78
		*sigp = NULL;
79
	if (lenp != NULL)
80
		*lenp = 0;
81
	if ((r = sshkey_sign(key, &sig, &siglen,
82
	    data, datalen, alg, datafellows)) != 0) {
83
		fatal_on_fatal_errors(r, __func__, 0);
84
		error("%s: %s", __func__, ssh_err(r));
85
		return -1;
86
	}
87
	if (siglen > INT_MAX)
88
		fatal("%s: giant len %zu", __func__, siglen);
89
	if (sigp != NULL)
90
		*sigp = sig;
91
	if (lenp != NULL)
92
		*lenp = siglen;
93
	return 0;
94
}
95
96
int
97
key_verify(const Key *key, const u_char *signature, u_int signaturelen,
98
    const u_char *data, u_int datalen)
99
{
100
	int r;
101
102
	if ((r = sshkey_verify(key, signature, signaturelen,
103
	    data, datalen, datafellows)) != 0) {
104
		fatal_on_fatal_errors(r, __func__, 0);
105
		error("%s: %s", __func__, ssh_err(r));
106
		return r == SSH_ERR_SIGNATURE_INVALID ? 0 : -1;
107
	}
108
	return 1;
109
}
110
111
Key *
112
key_demote(const Key *k)
113
{
114
	int r;
115
56
	Key *ret = NULL;
116
117
28
	if ((r = sshkey_demote(k, &ret)) != 0)
118
		fatal("%s: %s", __func__, ssh_err(r));
119
56
	return ret;
120
28
}
121
122
int
123
key_drop_cert(Key *k)
124
{
125
	int r;
126
127
	if ((r = sshkey_drop_cert(k)) != 0) {
128
		fatal_on_fatal_errors(r, __func__, 0);
129
		error("%s: %s", __func__, ssh_err(r));
130
		return -1;
131
	}
132
	return 0;
133
}
134
135
int
136
key_cert_check_authority(const Key *k, int want_host, int require_principal,
137
    const char *name, const char **reason)
138
{
139
	int r;
140
141
	if ((r = sshkey_cert_check_authority(k, want_host, require_principal,
142
	    name, reason)) != 0) {
143
		fatal_on_fatal_errors(r, __func__, 0);
144
		error("%s: %s", __func__, ssh_err(r));
145
		return -1;
146
	}
147
	return 0;
148
}
149
150
/* authfile.c */
151
152
Key *
153
key_load_cert(const char *filename)
154
{
155
	int r;
156
	Key *ret = NULL;
157
158
	if ((r = sshkey_load_cert(filename, &ret)) != 0) {
159
		fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
160
		/* Old authfile.c ignored all file errors. */
161
		if (r == SSH_ERR_SYSTEM_ERROR)
162
			debug("%s: %s", __func__, ssh_err(r));
163
		else
164
			error("%s: %s", __func__, ssh_err(r));
165
		return NULL;
166
	}
167
	return ret;
168
169
}
170
171
Key *
172
key_load_public(const char *filename, char **commentp)
173
{
174
	int r;
175
100
	Key *ret = NULL;
176
177
50
	if ((r = sshkey_load_public(filename, &ret, commentp)) != 0) {
178
36
		fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
179
		/* Old authfile.c ignored all file errors. */
180
72
		if (r == SSH_ERR_SYSTEM_ERROR)
181
72
			debug("%s: %s", __func__, ssh_err(r));
182
		else
183
			error("%s: %s", __func__, ssh_err(r));
184
36
		return NULL;
185
	}
186
14
	return ret;
187
50
}
188
189
Key *
190
key_load_private(const char *path, const char *passphrase,
191
    char **commentp)
192
{
193
	int r;
194
84
	Key *ret = NULL;
195
196
42
	if ((r = sshkey_load_private(path, passphrase, &ret, commentp)) != 0) {
197
		fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
198
		/* Old authfile.c ignored all file errors. */
199
		if (r == SSH_ERR_SYSTEM_ERROR ||
200
		    r == SSH_ERR_KEY_WRONG_PASSPHRASE)
201
			debug("%s: %s", __func__, ssh_err(r));
202
		else
203
			error("%s: %s", __func__, ssh_err(r));
204
		return NULL;
205
	}
206
42
	return ret;
207
42
}
208
209
Key *
210
key_load_private_cert(int type, const char *filename, const char *passphrase,
211
    int *perm_ok)
212
{
213
	int r;
214
	Key *ret = NULL;
215
216
	if ((r = sshkey_load_private_cert(type, filename, passphrase,
217
	    &ret, perm_ok)) != 0) {
218
		fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
219
		/* Old authfile.c ignored all file errors. */
220
		if (r == SSH_ERR_SYSTEM_ERROR ||
221
		    r == SSH_ERR_KEY_WRONG_PASSPHRASE)
222
			debug("%s: %s", __func__, ssh_err(r));
223
		else
224
			error("%s: %s", __func__, ssh_err(r));
225
		return NULL;
226
	}
227
	return ret;
228
}
229
230
Key *
231
key_load_private_type(int type, const char *filename, const char *passphrase,
232
    char **commentp, int *perm_ok)
233
{
234
	int r;
235
	Key *ret = NULL;
236
237
	if ((r = sshkey_load_private_type(type, filename, passphrase,
238
	    &ret, commentp, perm_ok)) != 0) {
239
		fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
240
		/* Old authfile.c ignored all file errors. */
241
		if (r == SSH_ERR_SYSTEM_ERROR ||
242
		    (r == SSH_ERR_KEY_WRONG_PASSPHRASE))
243
			debug("%s: %s", __func__, ssh_err(r));
244
		else
245
			error("%s: %s", __func__, ssh_err(r));
246
		return NULL;
247
	}
248
	return ret;
249
}