]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - crypto/openssh/key.c
Upgrade to OpenSSH 7.7p1.
[FreeBSD/FreeBSD.git] / crypto / openssh / key.c
1 /* $OpenBSD: key.c,v 1.132 2017/12/18 02:25:15 djm Exp $ */
2 /*
3  * placed in the public domain
4  */
5
6 #include "includes.h"
7
8 #include <sys/types.h>
9 #include <errno.h>
10 #include <stdarg.h>
11 #include <stdio.h>
12 #include <limits.h>
13
14 #define SSH_KEY_NO_DEFINE
15 #include "key.h"
16
17 #include "compat.h"
18 #include "sshkey.h"
19 #include "ssherr.h"
20 #include "log.h"
21 #include "authfile.h"
22
23 static void
24 fatal_on_fatal_errors(int r, const char *func, int extra_fatal)
25 {
26         if (r == SSH_ERR_INTERNAL_ERROR ||
27             r == SSH_ERR_ALLOC_FAIL ||
28             (extra_fatal != 0 && r == extra_fatal))
29                 fatal("%s: %s", func, ssh_err(r));
30 }
31
32 Key *
33 key_from_blob(const u_char *blob, u_int blen)
34 {
35         int r;
36         Key *ret = NULL;
37
38         if ((r = sshkey_from_blob(blob, blen, &ret)) != 0) {
39                 fatal_on_fatal_errors(r, __func__, 0);
40                 error("%s: %s", __func__, ssh_err(r));
41                 return NULL;
42         }
43         return ret;
44 }
45
46 int
47 key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
48 {
49         u_char *blob;
50         size_t blen;
51         int r;
52
53         if (blobp != NULL)
54                 *blobp = NULL;
55         if (lenp != NULL)
56                 *lenp = 0;
57         if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) {
58                 fatal_on_fatal_errors(r, __func__, 0);
59                 error("%s: %s", __func__, ssh_err(r));
60                 return 0;
61         }
62         if (blen > INT_MAX)
63                 fatal("%s: giant len %zu", __func__, blen);
64         if (blobp != NULL)
65                 *blobp = blob;
66         if (lenp != NULL)
67                 *lenp = blen;
68         return blen;
69 }
70
71 int
72 key_sign(const Key *key, u_char **sigp, u_int *lenp,
73     const u_char *data, u_int datalen, const char *alg)
74 {
75         int r;
76         u_char *sig;
77         size_t siglen;
78
79         if (sigp != NULL)
80                 *sigp = NULL;
81         if (lenp != NULL)
82                 *lenp = 0;
83         if ((r = sshkey_sign(key, &sig, &siglen,
84             data, datalen, alg, datafellows)) != 0) {
85                 fatal_on_fatal_errors(r, __func__, 0);
86                 error("%s: %s", __func__, ssh_err(r));
87                 return -1;
88         }
89         if (siglen > INT_MAX)
90                 fatal("%s: giant len %zu", __func__, siglen);
91         if (sigp != NULL)
92                 *sigp = sig;
93         if (lenp != NULL)
94                 *lenp = siglen;
95         return 0;
96 }
97
98 Key *
99 key_demote(const Key *k)
100 {
101         int r;
102         Key *ret = NULL;
103
104         if ((r = sshkey_demote(k, &ret)) != 0)
105                 fatal("%s: %s", __func__, ssh_err(r));
106         return ret;
107 }
108
109 int
110 key_drop_cert(Key *k)
111 {
112         int r;
113
114         if ((r = sshkey_drop_cert(k)) != 0) {
115                 fatal_on_fatal_errors(r, __func__, 0);
116                 error("%s: %s", __func__, ssh_err(r));
117                 return -1;
118         }
119         return 0;
120 }
121
122 int
123 key_cert_check_authority(const Key *k, int want_host, int require_principal,
124     const char *name, const char **reason)
125 {
126         int r;
127
128         if ((r = sshkey_cert_check_authority(k, want_host, require_principal,
129             name, reason)) != 0) {
130                 fatal_on_fatal_errors(r, __func__, 0);
131                 error("%s: %s", __func__, ssh_err(r));
132                 return -1;
133         }
134         return 0;
135 }
136
137 /* authfile.c */
138
139 Key *
140 key_load_cert(const char *filename)
141 {
142         int r;
143         Key *ret = NULL;
144
145         if ((r = sshkey_load_cert(filename, &ret)) != 0) {
146                 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
147                 /* Old authfile.c ignored all file errors. */
148                 if (r == SSH_ERR_SYSTEM_ERROR)
149                         debug("%s: %s", __func__, ssh_err(r));
150                 else
151                         error("%s: %s", __func__, ssh_err(r));
152                 return NULL;
153         }
154         return ret;
155
156 }
157
158 Key *
159 key_load_public(const char *filename, char **commentp)
160 {
161         int r;
162         Key *ret = NULL;
163
164         if ((r = sshkey_load_public(filename, &ret, commentp)) != 0) {
165                 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
166                 /* Old authfile.c ignored all file errors. */
167                 if (r == SSH_ERR_SYSTEM_ERROR)
168                         debug("%s: %s", __func__, ssh_err(r));
169                 else
170                         error("%s: %s", __func__, ssh_err(r));
171                 return NULL;
172         }
173         return ret;
174 }
175
176 Key *
177 key_load_private(const char *path, const char *passphrase,
178     char **commentp)
179 {
180         int r;
181         Key *ret = NULL;
182
183         if ((r = sshkey_load_private(path, passphrase, &ret, commentp)) != 0) {
184                 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
185                 /* Old authfile.c ignored all file errors. */
186                 if (r == SSH_ERR_SYSTEM_ERROR ||
187                     r == SSH_ERR_KEY_WRONG_PASSPHRASE)
188                         debug("%s: %s", __func__, ssh_err(r));
189                 else
190                         error("%s: %s", __func__, ssh_err(r));
191                 return NULL;
192         }
193         return ret;
194 }
195
196 Key *
197 key_load_private_cert(int type, const char *filename, const char *passphrase,
198     int *perm_ok)
199 {
200         int r;
201         Key *ret = NULL;
202
203         if ((r = sshkey_load_private_cert(type, filename, passphrase,
204             &ret, perm_ok)) != 0) {
205                 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
206                 /* Old authfile.c ignored all file errors. */
207                 if (r == SSH_ERR_SYSTEM_ERROR ||
208                     r == SSH_ERR_KEY_WRONG_PASSPHRASE)
209                         debug("%s: %s", __func__, ssh_err(r));
210                 else
211                         error("%s: %s", __func__, ssh_err(r));
212                 return NULL;
213         }
214         return ret;
215 }
216
217 Key *
218 key_load_private_type(int type, const char *filename, const char *passphrase,
219     char **commentp, int *perm_ok)
220 {
221         int r;
222         Key *ret = NULL;
223
224         if ((r = sshkey_load_private_type(type, filename, passphrase,
225             &ret, commentp, perm_ok)) != 0) {
226                 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
227                 /* Old authfile.c ignored all file errors. */
228                 if (r == SSH_ERR_SYSTEM_ERROR ||
229                     (r == SSH_ERR_KEY_WRONG_PASSPHRASE))
230                         debug("%s: %s", __func__, ssh_err(r));
231                 else
232                         error("%s: %s", __func__, ssh_err(r));
233                 return NULL;
234         }
235         return ret;
236 }