diff options
Diffstat (limited to 'src/lib/libssl/ssl_rsa.c')
-rw-r--r-- | src/lib/libssl/ssl_rsa.c | 755 |
1 files changed, 0 insertions, 755 deletions
diff --git a/src/lib/libssl/ssl_rsa.c b/src/lib/libssl/ssl_rsa.c deleted file mode 100644 index 039bee7952..0000000000 --- a/src/lib/libssl/ssl_rsa.c +++ /dev/null | |||
@@ -1,755 +0,0 @@ | |||
1 | /* $OpenBSD: ssl_rsa.c,v 1.20 2015/02/06 01:37:11 reyk Exp $ */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | |||
61 | #include "ssl_locl.h" | ||
62 | |||
63 | #include <openssl/bio.h> | ||
64 | #include <openssl/evp.h> | ||
65 | #include <openssl/objects.h> | ||
66 | #include <openssl/pem.h> | ||
67 | #include <openssl/x509.h> | ||
68 | |||
69 | static int ssl_set_cert(CERT *c, X509 *x509); | ||
70 | static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey); | ||
71 | static int ssl_ctx_use_certificate_chain_bio(SSL_CTX *, BIO *); | ||
72 | |||
73 | int | ||
74 | SSL_use_certificate(SSL *ssl, X509 *x) | ||
75 | { | ||
76 | if (x == NULL) { | ||
77 | SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); | ||
78 | return (0); | ||
79 | } | ||
80 | if (!ssl_cert_inst(&ssl->cert)) { | ||
81 | SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_MALLOC_FAILURE); | ||
82 | return (0); | ||
83 | } | ||
84 | return (ssl_set_cert(ssl->cert, x)); | ||
85 | } | ||
86 | |||
87 | int | ||
88 | SSL_use_certificate_file(SSL *ssl, const char *file, int type) | ||
89 | { | ||
90 | int j; | ||
91 | BIO *in; | ||
92 | int ret = 0; | ||
93 | X509 *x = NULL; | ||
94 | |||
95 | in = BIO_new(BIO_s_file_internal()); | ||
96 | if (in == NULL) { | ||
97 | SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB); | ||
98 | goto end; | ||
99 | } | ||
100 | |||
101 | if (BIO_read_filename(in, file) <= 0) { | ||
102 | SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); | ||
103 | goto end; | ||
104 | } | ||
105 | if (type == SSL_FILETYPE_ASN1) { | ||
106 | j = ERR_R_ASN1_LIB; | ||
107 | x = d2i_X509_bio(in, NULL); | ||
108 | } else if (type == SSL_FILETYPE_PEM) { | ||
109 | j = ERR_R_PEM_LIB; | ||
110 | x = PEM_read_bio_X509(in, NULL, | ||
111 | ssl->ctx->default_passwd_callback, | ||
112 | ssl->ctx->default_passwd_callback_userdata); | ||
113 | } else { | ||
114 | SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); | ||
115 | goto end; | ||
116 | } | ||
117 | |||
118 | if (x == NULL) { | ||
119 | SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, j); | ||
120 | goto end; | ||
121 | } | ||
122 | |||
123 | ret = SSL_use_certificate(ssl, x); | ||
124 | end: | ||
125 | if (x != NULL) | ||
126 | X509_free(x); | ||
127 | BIO_free(in); | ||
128 | return (ret); | ||
129 | } | ||
130 | |||
131 | int | ||
132 | SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len) | ||
133 | { | ||
134 | X509 *x; | ||
135 | int ret; | ||
136 | |||
137 | x = d2i_X509(NULL, &d,(long)len); | ||
138 | if (x == NULL) { | ||
139 | SSLerr(SSL_F_SSL_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); | ||
140 | return (0); | ||
141 | } | ||
142 | |||
143 | ret = SSL_use_certificate(ssl, x); | ||
144 | X509_free(x); | ||
145 | return (ret); | ||
146 | } | ||
147 | |||
148 | int | ||
149 | SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) | ||
150 | { | ||
151 | EVP_PKEY *pkey; | ||
152 | int ret; | ||
153 | |||
154 | if (rsa == NULL) { | ||
155 | SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); | ||
156 | return (0); | ||
157 | } | ||
158 | if (!ssl_cert_inst(&ssl->cert)) { | ||
159 | SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_MALLOC_FAILURE); | ||
160 | return (0); | ||
161 | } | ||
162 | if ((pkey = EVP_PKEY_new()) == NULL) { | ||
163 | SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB); | ||
164 | return (0); | ||
165 | } | ||
166 | |||
167 | RSA_up_ref(rsa); | ||
168 | EVP_PKEY_assign_RSA(pkey, rsa); | ||
169 | |||
170 | ret = ssl_set_pkey(ssl->cert, pkey); | ||
171 | EVP_PKEY_free(pkey); | ||
172 | return (ret); | ||
173 | } | ||
174 | |||
175 | static int | ||
176 | ssl_set_pkey(CERT *c, EVP_PKEY *pkey) | ||
177 | { | ||
178 | int i; | ||
179 | |||
180 | i = ssl_cert_type(NULL, pkey); | ||
181 | if (i < 0) { | ||
182 | SSLerr(SSL_F_SSL_SET_PKEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE); | ||
183 | return (0); | ||
184 | } | ||
185 | |||
186 | if (c->pkeys[i].x509 != NULL) { | ||
187 | EVP_PKEY *pktmp; | ||
188 | pktmp = X509_get_pubkey(c->pkeys[i].x509); | ||
189 | EVP_PKEY_copy_parameters(pktmp, pkey); | ||
190 | EVP_PKEY_free(pktmp); | ||
191 | ERR_clear_error(); | ||
192 | |||
193 | /* | ||
194 | * Don't check the public/private key, this is mostly | ||
195 | * for smart cards. | ||
196 | */ | ||
197 | if ((pkey->type == EVP_PKEY_RSA) && | ||
198 | (RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK)) | ||
199 | ; | ||
200 | else | ||
201 | if (!X509_check_private_key(c->pkeys[i].x509, pkey)) { | ||
202 | X509_free(c->pkeys[i].x509); | ||
203 | c->pkeys[i].x509 = NULL; | ||
204 | return 0; | ||
205 | } | ||
206 | } | ||
207 | |||
208 | EVP_PKEY_free(c->pkeys[i].privatekey); | ||
209 | CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); | ||
210 | c->pkeys[i].privatekey = pkey; | ||
211 | c->key = &(c->pkeys[i]); | ||
212 | |||
213 | c->valid = 0; | ||
214 | return (1); | ||
215 | } | ||
216 | |||
217 | int | ||
218 | SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) | ||
219 | { | ||
220 | int j, ret = 0; | ||
221 | BIO *in; | ||
222 | RSA *rsa = NULL; | ||
223 | |||
224 | in = BIO_new(BIO_s_file_internal()); | ||
225 | if (in == NULL) { | ||
226 | SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB); | ||
227 | goto end; | ||
228 | } | ||
229 | |||
230 | if (BIO_read_filename(in, file) <= 0) { | ||
231 | SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB); | ||
232 | goto end; | ||
233 | } | ||
234 | if (type == SSL_FILETYPE_ASN1) { | ||
235 | j = ERR_R_ASN1_LIB; | ||
236 | rsa = d2i_RSAPrivateKey_bio(in, NULL); | ||
237 | } else if (type == SSL_FILETYPE_PEM) { | ||
238 | j = ERR_R_PEM_LIB; | ||
239 | rsa = PEM_read_bio_RSAPrivateKey(in, NULL, | ||
240 | ssl->ctx->default_passwd_callback, | ||
241 | ssl->ctx->default_passwd_callback_userdata); | ||
242 | } else { | ||
243 | SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); | ||
244 | goto end; | ||
245 | } | ||
246 | if (rsa == NULL) { | ||
247 | SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, j); | ||
248 | goto end; | ||
249 | } | ||
250 | ret = SSL_use_RSAPrivateKey(ssl, rsa); | ||
251 | RSA_free(rsa); | ||
252 | end: | ||
253 | BIO_free(in); | ||
254 | return (ret); | ||
255 | } | ||
256 | |||
257 | int | ||
258 | SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len) | ||
259 | { | ||
260 | int ret; | ||
261 | const unsigned char *p; | ||
262 | RSA *rsa; | ||
263 | |||
264 | p = d; | ||
265 | if ((rsa = d2i_RSAPrivateKey(NULL, &p,(long)len)) == NULL) { | ||
266 | SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB); | ||
267 | return (0); | ||
268 | } | ||
269 | |||
270 | ret = SSL_use_RSAPrivateKey(ssl, rsa); | ||
271 | RSA_free(rsa); | ||
272 | return (ret); | ||
273 | } | ||
274 | |||
275 | int | ||
276 | SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) | ||
277 | { | ||
278 | int ret; | ||
279 | |||
280 | if (pkey == NULL) { | ||
281 | SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); | ||
282 | return (0); | ||
283 | } | ||
284 | if (!ssl_cert_inst(&ssl->cert)) { | ||
285 | SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE); | ||
286 | return (0); | ||
287 | } | ||
288 | ret = ssl_set_pkey(ssl->cert, pkey); | ||
289 | return (ret); | ||
290 | } | ||
291 | |||
292 | int | ||
293 | SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) | ||
294 | { | ||
295 | int j, ret = 0; | ||
296 | BIO *in; | ||
297 | EVP_PKEY *pkey = NULL; | ||
298 | |||
299 | in = BIO_new(BIO_s_file_internal()); | ||
300 | if (in == NULL) { | ||
301 | SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB); | ||
302 | goto end; | ||
303 | } | ||
304 | |||
305 | if (BIO_read_filename(in, file) <= 0) { | ||
306 | SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB); | ||
307 | goto end; | ||
308 | } | ||
309 | if (type == SSL_FILETYPE_PEM) { | ||
310 | j = ERR_R_PEM_LIB; | ||
311 | pkey = PEM_read_bio_PrivateKey(in, NULL, | ||
312 | ssl->ctx->default_passwd_callback, | ||
313 | ssl->ctx->default_passwd_callback_userdata); | ||
314 | } else if (type == SSL_FILETYPE_ASN1) { | ||
315 | j = ERR_R_ASN1_LIB; | ||
316 | pkey = d2i_PrivateKey_bio(in, NULL); | ||
317 | } else { | ||
318 | SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); | ||
319 | goto end; | ||
320 | } | ||
321 | if (pkey == NULL) { | ||
322 | SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, j); | ||
323 | goto end; | ||
324 | } | ||
325 | ret = SSL_use_PrivateKey(ssl, pkey); | ||
326 | EVP_PKEY_free(pkey); | ||
327 | end: | ||
328 | BIO_free(in); | ||
329 | return (ret); | ||
330 | } | ||
331 | |||
332 | int | ||
333 | SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len) | ||
334 | { | ||
335 | int ret; | ||
336 | const unsigned char *p; | ||
337 | EVP_PKEY *pkey; | ||
338 | |||
339 | p = d; | ||
340 | if ((pkey = d2i_PrivateKey(type, NULL, &p,(long)len)) == NULL) { | ||
341 | SSLerr(SSL_F_SSL_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); | ||
342 | return (0); | ||
343 | } | ||
344 | |||
345 | ret = SSL_use_PrivateKey(ssl, pkey); | ||
346 | EVP_PKEY_free(pkey); | ||
347 | return (ret); | ||
348 | } | ||
349 | |||
350 | int | ||
351 | SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) | ||
352 | { | ||
353 | if (x == NULL) { | ||
354 | SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); | ||
355 | return (0); | ||
356 | } | ||
357 | if (!ssl_cert_inst(&ctx->cert)) { | ||
358 | SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_MALLOC_FAILURE); | ||
359 | return (0); | ||
360 | } | ||
361 | return (ssl_set_cert(ctx->cert, x)); | ||
362 | } | ||
363 | |||
364 | static int | ||
365 | ssl_set_cert(CERT *c, X509 *x) | ||
366 | { | ||
367 | EVP_PKEY *pkey; | ||
368 | int i; | ||
369 | |||
370 | pkey = X509_get_pubkey(x); | ||
371 | if (pkey == NULL) { | ||
372 | SSLerr(SSL_F_SSL_SET_CERT, SSL_R_X509_LIB); | ||
373 | return (0); | ||
374 | } | ||
375 | |||
376 | i = ssl_cert_type(x, pkey); | ||
377 | if (i < 0) { | ||
378 | SSLerr(SSL_F_SSL_SET_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE); | ||
379 | EVP_PKEY_free(pkey); | ||
380 | return (0); | ||
381 | } | ||
382 | |||
383 | if (c->pkeys[i].privatekey != NULL) { | ||
384 | EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey); | ||
385 | ERR_clear_error(); | ||
386 | |||
387 | /* | ||
388 | * Don't check the public/private key, this is mostly | ||
389 | * for smart cards. | ||
390 | */ | ||
391 | if ((c->pkeys[i].privatekey->type == EVP_PKEY_RSA) && | ||
392 | (RSA_flags(c->pkeys[i].privatekey->pkey.rsa) & | ||
393 | RSA_METHOD_FLAG_NO_CHECK)) | ||
394 | ; | ||
395 | else | ||
396 | if (!X509_check_private_key(x, c->pkeys[i].privatekey)) { | ||
397 | /* | ||
398 | * don't fail for a cert/key mismatch, just free | ||
399 | * current private key (when switching to a different | ||
400 | * cert & key, first this function should be used, | ||
401 | * then ssl_set_pkey | ||
402 | */ | ||
403 | EVP_PKEY_free(c->pkeys[i].privatekey); | ||
404 | c->pkeys[i].privatekey = NULL; | ||
405 | /* clear error queue */ | ||
406 | ERR_clear_error(); | ||
407 | } | ||
408 | } | ||
409 | |||
410 | EVP_PKEY_free(pkey); | ||
411 | |||
412 | if (c->pkeys[i].x509 != NULL) | ||
413 | X509_free(c->pkeys[i].x509); | ||
414 | CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); | ||
415 | c->pkeys[i].x509 = x; | ||
416 | c->key = &(c->pkeys[i]); | ||
417 | |||
418 | c->valid = 0; | ||
419 | return (1); | ||
420 | } | ||
421 | |||
422 | int | ||
423 | SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) | ||
424 | { | ||
425 | int j; | ||
426 | BIO *in; | ||
427 | int ret = 0; | ||
428 | X509 *x = NULL; | ||
429 | |||
430 | in = BIO_new(BIO_s_file_internal()); | ||
431 | if (in == NULL) { | ||
432 | SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB); | ||
433 | goto end; | ||
434 | } | ||
435 | |||
436 | if (BIO_read_filename(in, file) <= 0) { | ||
437 | SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); | ||
438 | goto end; | ||
439 | } | ||
440 | if (type == SSL_FILETYPE_ASN1) { | ||
441 | j = ERR_R_ASN1_LIB; | ||
442 | x = d2i_X509_bio(in, NULL); | ||
443 | } else if (type == SSL_FILETYPE_PEM) { | ||
444 | j = ERR_R_PEM_LIB; | ||
445 | x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, | ||
446 | ctx->default_passwd_callback_userdata); | ||
447 | } else { | ||
448 | SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); | ||
449 | goto end; | ||
450 | } | ||
451 | |||
452 | if (x == NULL) { | ||
453 | SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, j); | ||
454 | goto end; | ||
455 | } | ||
456 | |||
457 | ret = SSL_CTX_use_certificate(ctx, x); | ||
458 | end: | ||
459 | if (x != NULL) | ||
460 | X509_free(x); | ||
461 | BIO_free(in); | ||
462 | return (ret); | ||
463 | } | ||
464 | |||
465 | int | ||
466 | SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d) | ||
467 | { | ||
468 | X509 *x; | ||
469 | int ret; | ||
470 | |||
471 | x = d2i_X509(NULL, &d,(long)len); | ||
472 | if (x == NULL) { | ||
473 | SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); | ||
474 | return (0); | ||
475 | } | ||
476 | |||
477 | ret = SSL_CTX_use_certificate(ctx, x); | ||
478 | X509_free(x); | ||
479 | return (ret); | ||
480 | } | ||
481 | |||
482 | int | ||
483 | SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) | ||
484 | { | ||
485 | int ret; | ||
486 | EVP_PKEY *pkey; | ||
487 | |||
488 | if (rsa == NULL) { | ||
489 | SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); | ||
490 | return (0); | ||
491 | } | ||
492 | if (!ssl_cert_inst(&ctx->cert)) { | ||
493 | SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_MALLOC_FAILURE); | ||
494 | return (0); | ||
495 | } | ||
496 | if ((pkey = EVP_PKEY_new()) == NULL) { | ||
497 | SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB); | ||
498 | return (0); | ||
499 | } | ||
500 | |||
501 | RSA_up_ref(rsa); | ||
502 | EVP_PKEY_assign_RSA(pkey, rsa); | ||
503 | |||
504 | ret = ssl_set_pkey(ctx->cert, pkey); | ||
505 | EVP_PKEY_free(pkey); | ||
506 | return (ret); | ||
507 | } | ||
508 | |||
509 | int | ||
510 | SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) | ||
511 | { | ||
512 | int j, ret = 0; | ||
513 | BIO *in; | ||
514 | RSA *rsa = NULL; | ||
515 | |||
516 | in = BIO_new(BIO_s_file_internal()); | ||
517 | if (in == NULL) { | ||
518 | SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB); | ||
519 | goto end; | ||
520 | } | ||
521 | |||
522 | if (BIO_read_filename(in, file) <= 0) { | ||
523 | SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB); | ||
524 | goto end; | ||
525 | } | ||
526 | if (type == SSL_FILETYPE_ASN1) { | ||
527 | j = ERR_R_ASN1_LIB; | ||
528 | rsa = d2i_RSAPrivateKey_bio(in, NULL); | ||
529 | } else if (type == SSL_FILETYPE_PEM) { | ||
530 | j = ERR_R_PEM_LIB; | ||
531 | rsa = PEM_read_bio_RSAPrivateKey(in, NULL, | ||
532 | ctx->default_passwd_callback, | ||
533 | ctx->default_passwd_callback_userdata); | ||
534 | } else { | ||
535 | SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); | ||
536 | goto end; | ||
537 | } | ||
538 | if (rsa == NULL) { | ||
539 | SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, j); | ||
540 | goto end; | ||
541 | } | ||
542 | ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); | ||
543 | RSA_free(rsa); | ||
544 | end: | ||
545 | BIO_free(in); | ||
546 | return (ret); | ||
547 | } | ||
548 | |||
549 | int | ||
550 | SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len) | ||
551 | { | ||
552 | int ret; | ||
553 | const unsigned char *p; | ||
554 | RSA *rsa; | ||
555 | |||
556 | p = d; | ||
557 | if ((rsa = d2i_RSAPrivateKey(NULL, &p,(long)len)) == NULL) { | ||
558 | SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB); | ||
559 | return (0); | ||
560 | } | ||
561 | |||
562 | ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); | ||
563 | RSA_free(rsa); | ||
564 | return (ret); | ||
565 | } | ||
566 | |||
567 | int | ||
568 | SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) | ||
569 | { | ||
570 | if (pkey == NULL) { | ||
571 | SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, | ||
572 | ERR_R_PASSED_NULL_PARAMETER); | ||
573 | return (0); | ||
574 | } | ||
575 | if (!ssl_cert_inst(&ctx->cert)) { | ||
576 | SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE); | ||
577 | return (0); | ||
578 | } | ||
579 | return (ssl_set_pkey(ctx->cert, pkey)); | ||
580 | } | ||
581 | |||
582 | int | ||
583 | SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) | ||
584 | { | ||
585 | int j, ret = 0; | ||
586 | BIO *in; | ||
587 | EVP_PKEY *pkey = NULL; | ||
588 | |||
589 | in = BIO_new(BIO_s_file_internal()); | ||
590 | if (in == NULL) { | ||
591 | SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB); | ||
592 | goto end; | ||
593 | } | ||
594 | |||
595 | if (BIO_read_filename(in, file) <= 0) { | ||
596 | SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB); | ||
597 | goto end; | ||
598 | } | ||
599 | if (type == SSL_FILETYPE_PEM) { | ||
600 | j = ERR_R_PEM_LIB; | ||
601 | pkey = PEM_read_bio_PrivateKey(in, NULL, | ||
602 | ctx->default_passwd_callback, | ||
603 | ctx->default_passwd_callback_userdata); | ||
604 | } else if (type == SSL_FILETYPE_ASN1) { | ||
605 | j = ERR_R_ASN1_LIB; | ||
606 | pkey = d2i_PrivateKey_bio(in, NULL); | ||
607 | } else { | ||
608 | SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, | ||
609 | SSL_R_BAD_SSL_FILETYPE); | ||
610 | goto end; | ||
611 | } | ||
612 | if (pkey == NULL) { | ||
613 | SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, j); | ||
614 | goto end; | ||
615 | } | ||
616 | ret = SSL_CTX_use_PrivateKey(ctx, pkey); | ||
617 | EVP_PKEY_free(pkey); | ||
618 | end: | ||
619 | BIO_free(in); | ||
620 | return (ret); | ||
621 | } | ||
622 | |||
623 | int | ||
624 | SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d, | ||
625 | long len) | ||
626 | { | ||
627 | int ret; | ||
628 | const unsigned char *p; | ||
629 | EVP_PKEY *pkey; | ||
630 | |||
631 | p = d; | ||
632 | if ((pkey = d2i_PrivateKey(type, NULL, &p,(long)len)) == NULL) { | ||
633 | SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); | ||
634 | return (0); | ||
635 | } | ||
636 | |||
637 | ret = SSL_CTX_use_PrivateKey(ctx, pkey); | ||
638 | EVP_PKEY_free(pkey); | ||
639 | return (ret); | ||
640 | } | ||
641 | |||
642 | |||
643 | /* | ||
644 | * Read a bio that contains our certificate in "PEM" format, | ||
645 | * possibly followed by a sequence of CA certificates that should be | ||
646 | * sent to the peer in the Certificate message. | ||
647 | */ | ||
648 | static int | ||
649 | ssl_ctx_use_certificate_chain_bio(SSL_CTX *ctx, BIO *in) | ||
650 | { | ||
651 | int ret = 0; | ||
652 | X509 *x = NULL; | ||
653 | |||
654 | ERR_clear_error(); /* clear error stack for SSL_CTX_use_certificate() */ | ||
655 | |||
656 | x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, | ||
657 | ctx->default_passwd_callback_userdata); | ||
658 | if (x == NULL) { | ||
659 | SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB); | ||
660 | goto end; | ||
661 | } | ||
662 | |||
663 | ret = SSL_CTX_use_certificate(ctx, x); | ||
664 | |||
665 | if (ERR_peek_error() != 0) | ||
666 | ret = 0; | ||
667 | /* Key/certificate mismatch doesn't imply ret==0 ... */ | ||
668 | if (ret) { | ||
669 | /* | ||
670 | * If we could set up our certificate, now proceed to | ||
671 | * the CA certificates. | ||
672 | */ | ||
673 | X509 *ca; | ||
674 | int r; | ||
675 | unsigned long err; | ||
676 | |||
677 | if (ctx->extra_certs != NULL) { | ||
678 | sk_X509_pop_free(ctx->extra_certs, X509_free); | ||
679 | ctx->extra_certs = NULL; | ||
680 | } | ||
681 | |||
682 | while ((ca = PEM_read_bio_X509(in, NULL, | ||
683 | ctx->default_passwd_callback, | ||
684 | ctx->default_passwd_callback_userdata)) != NULL) { | ||
685 | r = SSL_CTX_add_extra_chain_cert(ctx, ca); | ||
686 | if (!r) { | ||
687 | X509_free(ca); | ||
688 | ret = 0; | ||
689 | goto end; | ||
690 | } | ||
691 | /* | ||
692 | * Note that we must not free r if it was successfully | ||
693 | * added to the chain (while we must free the main | ||
694 | * certificate, since its reference count is increased | ||
695 | * by SSL_CTX_use_certificate). | ||
696 | */ | ||
697 | } | ||
698 | |||
699 | /* When the while loop ends, it's usually just EOF. */ | ||
700 | err = ERR_peek_last_error(); | ||
701 | if (ERR_GET_LIB(err) == ERR_LIB_PEM && | ||
702 | ERR_GET_REASON(err) == PEM_R_NO_START_LINE) | ||
703 | ERR_clear_error(); | ||
704 | else | ||
705 | ret = 0; /* some real error */ | ||
706 | } | ||
707 | |||
708 | end: | ||
709 | if (x != NULL) | ||
710 | X509_free(x); | ||
711 | return (ret); | ||
712 | } | ||
713 | |||
714 | int | ||
715 | SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) | ||
716 | { | ||
717 | BIO *in; | ||
718 | int ret = 0; | ||
719 | |||
720 | in = BIO_new(BIO_s_file_internal()); | ||
721 | if (in == NULL) { | ||
722 | SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB); | ||
723 | goto end; | ||
724 | } | ||
725 | |||
726 | if (BIO_read_filename(in, file) <= 0) { | ||
727 | SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_SYS_LIB); | ||
728 | goto end; | ||
729 | } | ||
730 | |||
731 | ret = ssl_ctx_use_certificate_chain_bio(ctx, in); | ||
732 | |||
733 | end: | ||
734 | BIO_free(in); | ||
735 | return (ret); | ||
736 | } | ||
737 | |||
738 | int | ||
739 | SSL_CTX_use_certificate_chain_mem(SSL_CTX *ctx, void *buf, int len) | ||
740 | { | ||
741 | BIO *in; | ||
742 | int ret = 0; | ||
743 | |||
744 | in = BIO_new_mem_buf(buf, len); | ||
745 | if (in == NULL) { | ||
746 | SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB); | ||
747 | goto end; | ||
748 | } | ||
749 | |||
750 | ret = ssl_ctx_use_certificate_chain_bio(ctx, in); | ||
751 | |||
752 | end: | ||
753 | BIO_free(in); | ||
754 | return (ret); | ||
755 | } | ||