We now build libssh2 in Xcode and it's a much better UB/10.4 citizen
[printdrop.git] / Vendor / libssh2 / Source / openssl.c
1 /* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
2 * Author: Simon Josefsson
3 * Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
4 *
5 * Redistribution and use in source and binary forms,
6 * with or without modification, are permitted provided
7 * that the following conditions are met:
8 *
9 * Redistributions of source code must retain the above
10 * copyright notice, this list of conditions and the
11 * following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials
16 * provided with the distribution.
17 *
18 * Neither the name of the copyright holder nor the names
19 * of any other contributors may be used to endorse or
20 * promote products derived from this software without
21 * specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
24 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
35 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
36 * OF SUCH DAMAGE.
37 */
38
39 #include "libssh2_priv.h"
40 #include <string.h>
41
42 #ifndef EVP_MAX_BLOCK_LENGTH
43 #define EVP_MAX_BLOCK_LENGTH 32
44 #endif
45
46 int
47 _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
48 const unsigned char *edata,
49 unsigned long elen,
50 const unsigned char *ndata,
51 unsigned long nlen,
52 const unsigned char *ddata,
53 unsigned long dlen,
54 const unsigned char *pdata,
55 unsigned long plen,
56 const unsigned char *qdata,
57 unsigned long qlen,
58 const unsigned char *e1data,
59 unsigned long e1len,
60 const unsigned char *e2data,
61 unsigned long e2len,
62 const unsigned char *coeffdata, unsigned long coefflen)
63 {
64 *rsa = RSA_new();
65
66 (*rsa)->e = BN_new();
67 BN_bin2bn(edata, elen, (*rsa)->e);
68
69 (*rsa)->n = BN_new();
70 BN_bin2bn(ndata, nlen, (*rsa)->n);
71
72 if (ddata) {
73 (*rsa)->d = BN_new();
74 BN_bin2bn(ddata, dlen, (*rsa)->d);
75
76 (*rsa)->p = BN_new();
77 BN_bin2bn(pdata, plen, (*rsa)->p);
78
79 (*rsa)->q = BN_new();
80 BN_bin2bn(qdata, qlen, (*rsa)->q);
81
82 (*rsa)->dmp1 = BN_new();
83 BN_bin2bn(e1data, e1len, (*rsa)->dmp1);
84
85 (*rsa)->dmq1 = BN_new();
86 BN_bin2bn(e2data, e2len, (*rsa)->dmq1);
87
88 (*rsa)->iqmp = BN_new();
89 BN_bin2bn(coeffdata, coefflen, (*rsa)->iqmp);
90 }
91 return 0;
92 }
93
94 int
95 _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsactx,
96 const unsigned char *sig,
97 unsigned long sig_len,
98 const unsigned char *m, unsigned long m_len)
99 {
100 unsigned char hash[SHA_DIGEST_LENGTH];
101 int ret;
102
103 SHA1(m, m_len, hash);
104 ret = RSA_verify(NID_sha1, hash, SHA_DIGEST_LENGTH,
105 (unsigned char *) sig, sig_len, rsactx);
106 return (ret == 1) ? 0 : -1;
107 }
108
109 int
110 _libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
111 const unsigned char *p,
112 unsigned long p_len,
113 const unsigned char *q,
114 unsigned long q_len,
115 const unsigned char *g,
116 unsigned long g_len,
117 const unsigned char *y,
118 unsigned long y_len,
119 const unsigned char *x, unsigned long x_len)
120 {
121 *dsactx = DSA_new();
122
123 (*dsactx)->p = BN_new();
124 BN_bin2bn(p, p_len, (*dsactx)->p);
125
126 (*dsactx)->q = BN_new();
127 BN_bin2bn(q, q_len, (*dsactx)->q);
128
129 (*dsactx)->g = BN_new();
130 BN_bin2bn(g, g_len, (*dsactx)->g);
131
132 (*dsactx)->pub_key = BN_new();
133 BN_bin2bn(y, y_len, (*dsactx)->pub_key);
134
135 if (x_len) {
136 (*dsactx)->priv_key = BN_new();
137 BN_bin2bn(x, x_len, (*dsactx)->priv_key);
138 }
139
140 return 0;
141 }
142
143 int
144 _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
145 const unsigned char *sig,
146 const unsigned char *m, unsigned long m_len)
147 {
148 unsigned char hash[SHA_DIGEST_LENGTH];
149 DSA_SIG dsasig;
150 int ret;
151
152 dsasig.r = BN_new();
153 BN_bin2bn(sig, 20, dsasig.r);
154 dsasig.s = BN_new();
155 BN_bin2bn(sig + 20, 20, dsasig.s);
156
157 libssh2_sha1(m, m_len, hash);
158 ret = DSA_do_verify(hash, SHA_DIGEST_LENGTH, &dsasig, dsactx);
159 BN_clear_free(dsasig.s);
160 BN_clear_free(dsasig.r);
161
162 return (ret == 1) ? 0 : -1;
163 }
164
165 int
166 _libssh2_cipher_init(_libssh2_cipher_ctx * h,
167 _libssh2_cipher_type(algo),
168 unsigned char *iv, unsigned char *secret, int encrypt)
169 {
170 EVP_CIPHER_CTX_init(h);
171 EVP_CipherInit(h, algo(), secret, iv, encrypt);
172 return 0;
173 }
174
175 int
176 _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
177 _libssh2_cipher_type(algo),
178 int encrypt, unsigned char *block)
179 {
180 int blocksize = ctx->cipher->block_size;
181 unsigned char buf[EVP_MAX_BLOCK_LENGTH];
182 int ret;
183 (void) algo;
184 (void) encrypt;
185
186 if (blocksize == 1) {
187 /* Hack for arcfour. */
188 blocksize = 8;
189 }
190 ret = EVP_Cipher(ctx, buf, block, blocksize);
191 if (ret == 1) {
192 memcpy(block, buf, blocksize);
193 }
194 return ret == 1 ? 0 : 1;
195 }
196
197 /* TODO: Optionally call a passphrase callback specified by the
198 * calling program
199 */
200 static int
201 passphrase_cb(char *buf, int size, int rwflag, char *passphrase)
202 {
203 int passphrase_len = strlen(passphrase);
204 (void) rwflag;
205
206 if (passphrase_len > (size - 1)) {
207 passphrase_len = size - 1;
208 }
209 memcpy(buf, passphrase, passphrase_len);
210 buf[passphrase_len] = '\0';
211
212 return passphrase_len;
213 }
214
215 int
216 _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
217 LIBSSH2_SESSION * session,
218 FILE * fp, unsigned const char *passphrase)
219 {
220 (void) session;
221 if (!EVP_get_cipherbyname("des")) {
222 /* If this cipher isn't loaded it's a pretty good indication that none are.
223 * I have *NO DOUBT* that there's a better way to deal with this ($#&%#$(%$#(
224 * Someone buy me an OpenSSL manual and I'll read up on it.
225 */
226 OpenSSL_add_all_ciphers();
227 }
228 *rsa = PEM_read_RSAPrivateKey(fp, NULL, (void *) passphrase_cb,
229 (void *) passphrase);
230 if (!*rsa) {
231 return -1;
232 }
233 return 0;
234 }
235
236 int
237 _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
238 LIBSSH2_SESSION * session,
239 FILE * fp, unsigned const char *passphrase)
240 {
241 (void) session;
242 if (!EVP_get_cipherbyname("des")) {
243 /* If this cipher isn't loaded it's a pretty good indication that none are.
244 * I have *NO DOUBT* that there's a better way to deal with this ($#&%#$(%$#(
245 * Someone buy me an OpenSSL manual and I'll read up on it.
246 */
247 OpenSSL_add_all_ciphers();
248 }
249 *dsa = PEM_read_DSAPrivateKey(fp, NULL, (void *) passphrase_cb,
250 (void *) passphrase);
251 if (!*dsa) {
252 return -1;
253 }
254 return 0;
255 }
256
257 int
258 _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
259 libssh2_rsa_ctx * rsactx,
260 const unsigned char *hash,
261 unsigned long hash_len,
262 unsigned char **signature, unsigned long *signature_len)
263 {
264 int ret;
265 unsigned char *sig;
266 unsigned int sig_len;
267
268 sig_len = RSA_size(rsactx);
269 sig = LIBSSH2_ALLOC(session, sig_len);
270
271 if (!sig) {
272 return -1;
273 }
274
275 ret = RSA_sign(NID_sha1, hash, hash_len, sig, &sig_len, rsactx);
276
277 if (!ret) {
278 LIBSSH2_FREE(session, sig);
279 return -1;
280 }
281
282 *signature = sig;
283 *signature_len = sig_len;
284
285 return 0;
286 }
287
288 int
289 _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
290 const unsigned char *hash,
291 unsigned long hash_len, unsigned char *signature)
292 {
293 DSA_SIG *sig;
294 int r_len, s_len, rs_pad;
295 (void) hash_len;
296
297 sig = DSA_do_sign(hash, SHA_DIGEST_LENGTH, dsactx);
298 if (!sig) {
299 return -1;
300 }
301
302 r_len = BN_num_bytes(sig->r);
303 s_len = BN_num_bytes(sig->s);
304 rs_pad = (2 * SHA_DIGEST_LENGTH) - (r_len + s_len);
305 if (rs_pad < 0) {
306 DSA_SIG_free(sig);
307 return -1;
308 }
309
310 BN_bn2bin(sig->r, signature + rs_pad);
311 BN_bn2bin(sig->s, signature + rs_pad + r_len);
312
313 DSA_SIG_free(sig);
314
315 return 0;
316 }