]> git.ipfire.org Git - thirdparty/openssl.git/blame - ssl/ssl_rsa.c
Fix no-stdio build
[thirdparty/openssl.git] / ssl / ssl_rsa.c
CommitLineData
d02b48c6 1/* ssl/ssl_rsa.c */
58964a49 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
d02b48c6
RE
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.
0f113f3e 8 *
d02b48c6
RE
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).
0f113f3e 15 *
d02b48c6
RE
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.
0f113f3e 22 *
d02b48c6
RE
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 :-).
0f113f3e 37 * 4. If you include any Windows specific code (or a derivative thereof) from
d02b48c6
RE
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
0f113f3e 40 *
d02b48c6
RE
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.
0f113f3e 52 *
d02b48c6
RE
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>
7b63c0fa 60#include "ssl_locl.h"
ec577822
BM
61#include <openssl/bio.h>
62#include <openssl/objects.h>
63#include <openssl/evp.h>
64#include <openssl/x509.h>
65#include <openssl/pem.h>
d02b48c6 66
d02b48c6
RE
67static int ssl_set_cert(CERT *c, X509 *x509);
68static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
6b691a5c 69int SSL_use_certificate(SSL *ssl, X509 *x)
0f113f3e
MC
70{
71 int rv;
72 if (x == NULL) {
73 SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER);
74 return (0);
75 }
76 rv = ssl_security_cert(ssl, NULL, x, 0, 1);
77 if (rv != 1) {
78 SSLerr(SSL_F_SSL_USE_CERTIFICATE, rv);
79 return 0;
80 }
81
0f113f3e
MC
82 return (ssl_set_cert(ssl->cert, x));
83}
d02b48c6 84
bc36ee62 85#ifndef OPENSSL_NO_STDIO
303c0028 86int SSL_use_certificate_file(SSL *ssl, const char *file, int type)
0f113f3e
MC
87{
88 int j;
89 BIO *in;
90 int ret = 0;
91 X509 *x = NULL;
92
93 in = BIO_new(BIO_s_file_internal());
94 if (in == NULL) {
95 SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB);
96 goto end;
97 }
98
99 if (BIO_read_filename(in, file) <= 0) {
100 SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB);
101 goto end;
102 }
103 if (type == SSL_FILETYPE_ASN1) {
104 j = ERR_R_ASN1_LIB;
105 x = d2i_X509_bio(in, NULL);
106 } else if (type == SSL_FILETYPE_PEM) {
107 j = ERR_R_PEM_LIB;
108 x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback,
109 ssl->ctx->default_passwd_callback_userdata);
110 } else {
111 SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE);
112 goto end;
113 }
114
115 if (x == NULL) {
116 SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, j);
117 goto end;
118 }
119
120 ret = SSL_use_certificate(ssl, x);
121 end:
222561fe 122 X509_free(x);
ca3a82c3 123 BIO_free(in);
0f113f3e
MC
124 return (ret);
125}
58964a49 126#endif
d02b48c6 127
875a644a 128int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len)
0f113f3e
MC
129{
130 X509 *x;
131 int ret;
132
133 x = d2i_X509(NULL, &d, (long)len);
134 if (x == NULL) {
135 SSLerr(SSL_F_SSL_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB);
136 return (0);
137 }
138
139 ret = SSL_use_certificate(ssl, x);
140 X509_free(x);
141 return (ret);
142}
d02b48c6 143
bc36ee62 144#ifndef OPENSSL_NO_RSA
6b691a5c 145int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa)
0f113f3e
MC
146{
147 EVP_PKEY *pkey;
148 int ret;
149
150 if (rsa == NULL) {
151 SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
152 return (0);
153 }
0f113f3e
MC
154 if ((pkey = EVP_PKEY_new()) == NULL) {
155 SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB);
156 return (0);
157 }
158
159 RSA_up_ref(rsa);
160 EVP_PKEY_assign_RSA(pkey, rsa);
161
162 ret = ssl_set_pkey(ssl->cert, pkey);
163 EVP_PKEY_free(pkey);
164 return (ret);
165}
d02b48c6
RE
166#endif
167
6b691a5c 168static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey)
0f113f3e
MC
169{
170 int i;
171 /*
172 * Special case for DH: check two DH certificate types for a match. This
173 * means for DH certificates we must set the certificate first.
174 */
175 if (pkey->type == EVP_PKEY_DH) {
176 X509 *x;
177 i = -1;
178 x = c->pkeys[SSL_PKEY_DH_RSA].x509;
179 if (x && X509_check_private_key(x, pkey))
180 i = SSL_PKEY_DH_RSA;
181 x = c->pkeys[SSL_PKEY_DH_DSA].x509;
182 if (i == -1 && x && X509_check_private_key(x, pkey))
183 i = SSL_PKEY_DH_DSA;
184 ERR_clear_error();
185 } else
186 i = ssl_cert_type(NULL, pkey);
187 if (i < 0) {
188 SSLerr(SSL_F_SSL_SET_PKEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
189 return (0);
190 }
191
192 if (c->pkeys[i].x509 != NULL) {
193 EVP_PKEY *pktmp;
194 pktmp = X509_get_pubkey(c->pkeys[i].x509);
195 EVP_PKEY_copy_parameters(pktmp, pkey);
196 EVP_PKEY_free(pktmp);
197 ERR_clear_error();
dfeab068 198
bc36ee62 199#ifndef OPENSSL_NO_RSA
0f113f3e
MC
200 /*
201 * Don't check the public/private key, this is mostly for smart
202 * cards.
203 */
204 if ((pkey->type == EVP_PKEY_RSA) &&
205 (RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK)) ;
206 else
58964a49 207#endif
0f113f3e
MC
208 if (!X509_check_private_key(c->pkeys[i].x509, pkey)) {
209 X509_free(c->pkeys[i].x509);
210 c->pkeys[i].x509 = NULL;
211 return 0;
212 }
213 }
214
25aaa98a 215 EVP_PKEY_free(c->pkeys[i].privatekey);
0f113f3e
MC
216 CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
217 c->pkeys[i].privatekey = pkey;
218 c->key = &(c->pkeys[i]);
0f113f3e
MC
219 return (1);
220}
d02b48c6 221
bc36ee62 222#ifndef OPENSSL_NO_RSA
0f113f3e 223# ifndef OPENSSL_NO_STDIO
303c0028 224int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type)
0f113f3e
MC
225{
226 int j, ret = 0;
227 BIO *in;
228 RSA *rsa = NULL;
229
230 in = BIO_new(BIO_s_file_internal());
231 if (in == NULL) {
232 SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB);
233 goto end;
234 }
235
236 if (BIO_read_filename(in, file) <= 0) {
237 SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB);
238 goto end;
239 }
240 if (type == SSL_FILETYPE_ASN1) {
241 j = ERR_R_ASN1_LIB;
242 rsa = d2i_RSAPrivateKey_bio(in, NULL);
243 } else if (type == SSL_FILETYPE_PEM) {
244 j = ERR_R_PEM_LIB;
245 rsa = PEM_read_bio_RSAPrivateKey(in, NULL,
246 ssl->ctx->default_passwd_callback,
247 ssl->
248 ctx->default_passwd_callback_userdata);
249 } else {
250 SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE);
251 goto end;
252 }
253 if (rsa == NULL) {
254 SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, j);
255 goto end;
256 }
257 ret = SSL_use_RSAPrivateKey(ssl, rsa);
258 RSA_free(rsa);
259 end:
ca3a82c3 260 BIO_free(in);
0f113f3e
MC
261 return (ret);
262}
263# endif
d02b48c6 264
693b71fa 265int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, long len)
0f113f3e
MC
266{
267 int ret;
268 const unsigned char *p;
269 RSA *rsa;
270
271 p = d;
272 if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) {
273 SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB);
274 return (0);
275 }
276
277 ret = SSL_use_RSAPrivateKey(ssl, rsa);
278 RSA_free(rsa);
279 return (ret);
280}
281#endif /* !OPENSSL_NO_RSA */
d02b48c6 282
6b691a5c 283int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey)
0f113f3e
MC
284{
285 int ret;
286
287 if (pkey == NULL) {
288 SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
289 return (0);
290 }
0f113f3e
MC
291 ret = ssl_set_pkey(ssl->cert, pkey);
292 return (ret);
293}
d02b48c6 294
bc36ee62 295#ifndef OPENSSL_NO_STDIO
303c0028 296int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type)
0f113f3e
MC
297{
298 int j, ret = 0;
299 BIO *in;
300 EVP_PKEY *pkey = NULL;
301
302 in = BIO_new(BIO_s_file_internal());
303 if (in == NULL) {
304 SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB);
305 goto end;
306 }
307
308 if (BIO_read_filename(in, file) <= 0) {
309 SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB);
310 goto end;
311 }
312 if (type == SSL_FILETYPE_PEM) {
313 j = ERR_R_PEM_LIB;
314 pkey = PEM_read_bio_PrivateKey(in, NULL,
315 ssl->ctx->default_passwd_callback,
316 ssl->
317 ctx->default_passwd_callback_userdata);
318 } else if (type == SSL_FILETYPE_ASN1) {
319 j = ERR_R_ASN1_LIB;
320 pkey = d2i_PrivateKey_bio(in, NULL);
321 } else {
322 SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE);
323 goto end;
324 }
325 if (pkey == NULL) {
326 SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, j);
327 goto end;
328 }
329 ret = SSL_use_PrivateKey(ssl, pkey);
330 EVP_PKEY_free(pkey);
331 end:
ca3a82c3 332 BIO_free(in);
0f113f3e
MC
333 return (ret);
334}
58964a49 335#endif
d02b48c6 336
0f113f3e
MC
337int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d,
338 long len)
339{
340 int ret;
341 const unsigned char *p;
342 EVP_PKEY *pkey;
d02b48c6 343
0f113f3e
MC
344 p = d;
345 if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) {
346 SSLerr(SSL_F_SSL_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB);
347 return (0);
348 }
d02b48c6 349
0f113f3e
MC
350 ret = SSL_use_PrivateKey(ssl, pkey);
351 EVP_PKEY_free(pkey);
352 return (ret);
353}
d02b48c6 354
6b691a5c 355int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
0f113f3e
MC
356{
357 int rv;
358 if (x == NULL) {
359 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER);
360 return (0);
361 }
362 rv = ssl_security_cert(NULL, ctx, x, 0, 1);
363 if (rv != 1) {
364 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, rv);
365 return 0;
366 }
0f113f3e
MC
367 return (ssl_set_cert(ctx->cert, x));
368}
d02b48c6 369
6b691a5c 370static int ssl_set_cert(CERT *c, X509 *x)
0f113f3e
MC
371{
372 EVP_PKEY *pkey;
373 int i;
374
375 pkey = X509_get_pubkey(x);
376 if (pkey == NULL) {
377 SSLerr(SSL_F_SSL_SET_CERT, SSL_R_X509_LIB);
378 return (0);
379 }
380
381 i = ssl_cert_type(x, pkey);
382 if (i < 0) {
383 SSLerr(SSL_F_SSL_SET_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
384 EVP_PKEY_free(pkey);
385 return (0);
386 }
387
388 if (c->pkeys[i].privatekey != NULL) {
389 EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey);
390 ERR_clear_error();
dfeab068 391
bc36ee62 392#ifndef OPENSSL_NO_RSA
0f113f3e
MC
393 /*
394 * Don't check the public/private key, this is mostly for smart
395 * cards.
396 */
397 if ((c->pkeys[i].privatekey->type == EVP_PKEY_RSA) &&
398 (RSA_flags(c->pkeys[i].privatekey->pkey.rsa) &
399 RSA_METHOD_FLAG_NO_CHECK)) ;
400 else
401#endif /* OPENSSL_NO_RSA */
402 if (!X509_check_private_key(x, c->pkeys[i].privatekey)) {
403 /*
404 * don't fail for a cert/key mismatch, just free current private
405 * key (when switching to a different cert & key, first this
406 * function should be used, then ssl_set_pkey
407 */
408 EVP_PKEY_free(c->pkeys[i].privatekey);
409 c->pkeys[i].privatekey = NULL;
410 /* clear error queue */
411 ERR_clear_error();
412 }
413 }
414
415 EVP_PKEY_free(pkey);
416
222561fe 417 X509_free(c->pkeys[i].x509);
05f0fb9f 418 X509_up_ref(x);
0f113f3e
MC
419 c->pkeys[i].x509 = x;
420 c->key = &(c->pkeys[i]);
421
0f113f3e
MC
422 return (1);
423}
d02b48c6 424
bc36ee62 425#ifndef OPENSSL_NO_STDIO
303c0028 426int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
0f113f3e
MC
427{
428 int j;
429 BIO *in;
430 int ret = 0;
431 X509 *x = NULL;
432
433 in = BIO_new(BIO_s_file_internal());
434 if (in == NULL) {
435 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB);
436 goto end;
437 }
438
439 if (BIO_read_filename(in, file) <= 0) {
440 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB);
441 goto end;
442 }
443 if (type == SSL_FILETYPE_ASN1) {
444 j = ERR_R_ASN1_LIB;
445 x = d2i_X509_bio(in, NULL);
446 } else if (type == SSL_FILETYPE_PEM) {
447 j = ERR_R_PEM_LIB;
448 x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
449 ctx->default_passwd_callback_userdata);
450 } else {
451 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE);
452 goto end;
453 }
454
455 if (x == NULL) {
456 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, j);
457 goto end;
458 }
459
460 ret = SSL_CTX_use_certificate(ctx, x);
461 end:
222561fe 462 X509_free(x);
ca3a82c3 463 BIO_free(in);
0f113f3e
MC
464 return (ret);
465}
58964a49 466#endif
d02b48c6 467
0f113f3e
MC
468int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len,
469 const unsigned char *d)
470{
471 X509 *x;
472 int ret;
d02b48c6 473
0f113f3e
MC
474 x = d2i_X509(NULL, &d, (long)len);
475 if (x == NULL) {
476 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB);
477 return (0);
478 }
d02b48c6 479
0f113f3e
MC
480 ret = SSL_CTX_use_certificate(ctx, x);
481 X509_free(x);
482 return (ret);
483}
d02b48c6 484
bc36ee62 485#ifndef OPENSSL_NO_RSA
6b691a5c 486int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa)
0f113f3e
MC
487{
488 int ret;
489 EVP_PKEY *pkey;
490
491 if (rsa == NULL) {
492 SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
493 return (0);
494 }
0f113f3e
MC
495 if ((pkey = EVP_PKEY_new()) == NULL) {
496 SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB);
497 return (0);
498 }
499
500 RSA_up_ref(rsa);
501 EVP_PKEY_assign_RSA(pkey, rsa);
502
503 ret = ssl_set_pkey(ctx->cert, pkey);
504 EVP_PKEY_free(pkey);
505 return (ret);
506}
507
508# ifndef OPENSSL_NO_STDIO
303c0028 509int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type)
0f113f3e
MC
510{
511 int j, ret = 0;
512 BIO *in;
513 RSA *rsa = NULL;
514
515 in = BIO_new(BIO_s_file_internal());
516 if (in == NULL) {
517 SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB);
518 goto end;
519 }
520
521 if (BIO_read_filename(in, file) <= 0) {
522 SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB);
523 goto end;
524 }
525 if (type == SSL_FILETYPE_ASN1) {
526 j = ERR_R_ASN1_LIB;
527 rsa = d2i_RSAPrivateKey_bio(in, NULL);
528 } else if (type == SSL_FILETYPE_PEM) {
529 j = ERR_R_PEM_LIB;
530 rsa = PEM_read_bio_RSAPrivateKey(in, NULL,
531 ctx->default_passwd_callback,
532 ctx->default_passwd_callback_userdata);
533 } else {
534 SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE);
535 goto end;
536 }
537 if (rsa == NULL) {
538 SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, j);
539 goto end;
540 }
541 ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
542 RSA_free(rsa);
543 end:
ca3a82c3 544 BIO_free(in);
0f113f3e
MC
545 return (ret);
546}
547# endif
548
549int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d,
550 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#endif /* !OPENSSL_NO_RSA */
d02b48c6 567
6b691a5c 568int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
0f113f3e
MC
569{
570 if (pkey == NULL) {
571 SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
572 return (0);
573 }
0f113f3e
MC
574 return (ssl_set_pkey(ctx->cert, pkey));
575}
d02b48c6 576
bc36ee62 577#ifndef OPENSSL_NO_STDIO
303c0028 578int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
0f113f3e
MC
579{
580 int j, ret = 0;
581 BIO *in;
582 EVP_PKEY *pkey = NULL;
583
584 in = BIO_new(BIO_s_file_internal());
585 if (in == NULL) {
586 SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB);
587 goto end;
588 }
589
590 if (BIO_read_filename(in, file) <= 0) {
591 SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB);
592 goto end;
593 }
594 if (type == SSL_FILETYPE_PEM) {
595 j = ERR_R_PEM_LIB;
596 pkey = PEM_read_bio_PrivateKey(in, NULL,
597 ctx->default_passwd_callback,
598 ctx->default_passwd_callback_userdata);
599 } else if (type == SSL_FILETYPE_ASN1) {
600 j = ERR_R_ASN1_LIB;
601 pkey = d2i_PrivateKey_bio(in, NULL);
602 } else {
603 SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE);
604 goto end;
605 }
606 if (pkey == NULL) {
607 SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, j);
608 goto end;
609 }
610 ret = SSL_CTX_use_PrivateKey(ctx, pkey);
611 EVP_PKEY_free(pkey);
612 end:
ca3a82c3 613 BIO_free(in);
0f113f3e
MC
614 return (ret);
615}
58964a49 616#endif
d02b48c6 617
0f113f3e
MC
618int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx,
619 const unsigned char *d, long len)
620{
621 int ret;
622 const unsigned char *p;
623 EVP_PKEY *pkey;
d02b48c6 624
0f113f3e
MC
625 p = d;
626 if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) {
627 SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB);
628 return (0);
629 }
d02b48c6 630
0f113f3e
MC
631 ret = SSL_CTX_use_PrivateKey(ctx, pkey);
632 EVP_PKEY_free(pkey);
633 return (ret);
634}
d02b48c6 635
bc36ee62 636#ifndef OPENSSL_NO_STDIO
0f113f3e
MC
637/*
638 * Read a file that contains our certificate in "PEM" format, possibly
639 * followed by a sequence of CA certificates that should be sent to the peer
640 * in the Certificate message.
b3ca645f 641 */
fae4772c 642static int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file)
0f113f3e
MC
643{
644 BIO *in;
645 int ret = 0;
646 X509 *x = NULL;
647
648 ERR_clear_error(); /* clear error stack for
649 * SSL_CTX_use_certificate() */
650
651 in = BIO_new(BIO_s_file_internal());
652 if (in == NULL) {
fae4772c 653 SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB);
0f113f3e
MC
654 goto end;
655 }
656
657 if (BIO_read_filename(in, file) <= 0) {
fae4772c 658 SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_SYS_LIB);
0f113f3e
MC
659 goto end;
660 }
661
662 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback,
663 ctx->default_passwd_callback_userdata);
664 if (x == NULL) {
fae4772c 665 SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
0f113f3e
MC
666 goto end;
667 }
668
fae4772c
DSH
669 if (ctx)
670 ret = SSL_CTX_use_certificate(ctx, x);
671 else
672 ret = SSL_use_certificate(ssl, x);
0f113f3e
MC
673
674 if (ERR_peek_error() != 0)
675 ret = 0; /* Key/certificate mismatch doesn't imply
676 * ret==0 ... */
677 if (ret) {
678 /*
679 * If we could set up our certificate, now proceed to the CA
680 * certificates.
681 */
682 X509 *ca;
683 int r;
684 unsigned long err;
685
fae4772c
DSH
686 if (ctx)
687 r = SSL_CTX_clear_chain_certs(ctx);
688 else
689 r = SSL_clear_chain_certs(ssl);
690
691 if (r == 0) {
69f68237
MC
692 ret = 0;
693 goto end;
694 }
0f113f3e
MC
695
696 while ((ca = PEM_read_bio_X509(in, NULL,
697 ctx->default_passwd_callback,
698 ctx->default_passwd_callback_userdata))
699 != NULL) {
fae4772c
DSH
700 if (ctx)
701 r = SSL_CTX_add0_chain_cert(ctx, ca);
702 else
703 r = SSL_add0_chain_cert(ssl, ca);
704 /*
705 * Note that we must not free ca if it was successfully added to
706 * the chain (while we must free the main certificate, since its
707 * reference count is increased by SSL_CTX_use_certificate).
708 */
0f113f3e
MC
709 if (!r) {
710 X509_free(ca);
711 ret = 0;
712 goto end;
713 }
0f113f3e
MC
714 }
715 /* When the while loop ends, it's usually just EOF. */
716 err = ERR_peek_last_error();
717 if (ERR_GET_LIB(err) == ERR_LIB_PEM
718 && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)
719 ERR_clear_error();
720 else
721 ret = 0; /* some real error */
722 }
723
724 end:
25aaa98a 725 X509_free(x);
ca3a82c3 726 BIO_free(in);
0f113f3e
MC
727 return (ret);
728}
fae4772c
DSH
729
730int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
731{
732 return use_certificate_chain_file(ctx, NULL, file);
733}
734
735int SSL_use_certificate_chain_file(SSL *ssl, const char *file)
736{
737 return use_certificate_chain_file(NULL, ssl, file);
738}
b3ca645f 739#endif
a9e1c50b 740
a398f821 741static int serverinfo_find_extension(const unsigned char *serverinfo,
0f113f3e
MC
742 size_t serverinfo_length,
743 unsigned int extension_type,
744 const unsigned char **extension_data,
745 size_t *extension_length)
746{
747 *extension_data = NULL;
748 *extension_length = 0;
749 if (serverinfo == NULL || serverinfo_length == 0)
fae11ec7 750 return -1;
0f113f3e
MC
751 for (;;) {
752 unsigned int type = 0;
753 size_t len = 0;
754
755 /* end of serverinfo */
756 if (serverinfo_length == 0)
fae11ec7 757 return 0; /* Extension not found */
0f113f3e
MC
758
759 /* read 2-byte type field */
760 if (serverinfo_length < 2)
fae11ec7 761 return -1; /* Error */
0f113f3e
MC
762 type = (serverinfo[0] << 8) + serverinfo[1];
763 serverinfo += 2;
764 serverinfo_length -= 2;
765
766 /* read 2-byte len field */
767 if (serverinfo_length < 2)
fae11ec7 768 return -1; /* Error */
0f113f3e
MC
769 len = (serverinfo[0] << 8) + serverinfo[1];
770 serverinfo += 2;
771 serverinfo_length -= 2;
772
773 if (len > serverinfo_length)
fae11ec7 774 return -1; /* Error */
0f113f3e
MC
775
776 if (type == extension_type) {
777 *extension_data = serverinfo;
778 *extension_length = len;
779 return 1; /* Success */
780 }
781
782 serverinfo += len;
783 serverinfo_length -= len;
784 }
c6ef15c4 785 /* Unreachable */
0f113f3e 786}
a398f821 787
de2a9e38 788static int serverinfo_srv_parse_cb(SSL *s, unsigned int ext_type,
0f113f3e
MC
789 const unsigned char *in,
790 size_t inlen, int *al, void *arg)
791{
0a602875 792
0f113f3e
MC
793 if (inlen != 0) {
794 *al = SSL_AD_DECODE_ERROR;
795 return 0;
796 }
0a602875 797
0f113f3e
MC
798 return 1;
799}
9cd50f73 800
de2a9e38 801static int serverinfo_srv_add_cb(SSL *s, unsigned int ext_type,
0f113f3e
MC
802 const unsigned char **out, size_t *outlen,
803 int *al, void *arg)
804{
805 const unsigned char *serverinfo = NULL;
806 size_t serverinfo_length = 0;
807
808 /* Is there serverinfo data for the chosen server cert? */
809 if ((ssl_get_server_cert_serverinfo(s, &serverinfo,
810 &serverinfo_length)) != 0) {
811 /* Find the relevant extension from the serverinfo */
812 int retval = serverinfo_find_extension(serverinfo, serverinfo_length,
813 ext_type, out, outlen);
fae11ec7
KR
814 if (retval == -1) {
815 *al = SSL_AD_DECODE_ERROR;
816 return -1; /* Error */
817 }
0f113f3e 818 if (retval == 0)
fae11ec7 819 return 0; /* No extension found, don't send extension */
0f113f3e
MC
820 return 1; /* Send extension */
821 }
822 return -1; /* No serverinfo data found, don't send
823 * extension */
824}
825
826/*
827 * With a NULL context, this function just checks that the serverinfo data
828 * parses correctly. With a non-NULL context, it registers callbacks for
829 * the included extensions.
830 */
831static int serverinfo_process_buffer(const unsigned char *serverinfo,
832 size_t serverinfo_length, SSL_CTX *ctx)
833{
834 if (serverinfo == NULL || serverinfo_length == 0)
835 return 0;
836 for (;;) {
837 unsigned int ext_type = 0;
838 size_t len = 0;
839
840 /* end of serverinfo */
841 if (serverinfo_length == 0)
842 return 1;
843
844 /* read 2-byte type field */
845 if (serverinfo_length < 2)
846 return 0;
847 /* FIXME: check for types we understand explicitly? */
848
849 /* Register callbacks for extensions */
850 ext_type = (serverinfo[0] << 8) + serverinfo[1];
851 if (ctx && !SSL_CTX_add_server_custom_ext(ctx, ext_type,
852 serverinfo_srv_add_cb,
853 NULL, NULL,
854 serverinfo_srv_parse_cb,
855 NULL))
856 return 0;
857
858 serverinfo += 2;
859 serverinfo_length -= 2;
860
861 /* read 2-byte len field */
862 if (serverinfo_length < 2)
863 return 0;
864 len = (serverinfo[0] << 8) + serverinfo[1];
865 serverinfo += 2;
866 serverinfo_length -= 2;
867
868 if (len > serverinfo_length)
869 return 0;
870
871 serverinfo += len;
872 serverinfo_length -= len;
873 }
874}
a398f821 875
a398f821 876int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
0f113f3e
MC
877 size_t serverinfo_length)
878{
879 unsigned char *new_serverinfo;
880
881 if (ctx == NULL || serverinfo == NULL || serverinfo_length == 0) {
882 SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_PASSED_NULL_PARAMETER);
883 return 0;
884 }
885 if (!serverinfo_process_buffer(serverinfo, serverinfo_length, NULL)) {
886 SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, SSL_R_INVALID_SERVERINFO_DATA);
887 return 0;
888 }
0f113f3e
MC
889 if (ctx->cert->key == NULL) {
890 SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_INTERNAL_ERROR);
891 return 0;
892 }
893 new_serverinfo = OPENSSL_realloc(ctx->cert->key->serverinfo,
894 serverinfo_length);
895 if (new_serverinfo == NULL) {
896 SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_MALLOC_FAILURE);
897 return 0;
898 }
899 ctx->cert->key->serverinfo = new_serverinfo;
900 memcpy(ctx->cert->key->serverinfo, serverinfo, serverinfo_length);
901 ctx->cert->key->serverinfo_length = serverinfo_length;
902
903 /*
904 * Now that the serverinfo is validated and stored, go ahead and
905 * register callbacks.
906 */
907 if (!serverinfo_process_buffer(serverinfo, serverinfo_length, ctx)) {
908 SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, SSL_R_INVALID_SERVERINFO_DATA);
909 return 0;
910 }
911 return 1;
912}
913
a398f821 914int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file)
0f113f3e
MC
915{
916 unsigned char *serverinfo = NULL;
917 size_t serverinfo_length = 0;
918 unsigned char *extension = 0;
919 long extension_length = 0;
920 char *name = NULL;
921 char *header = NULL;
922 char namePrefix[] = "SERVERINFO FOR ";
923 int ret = 0;
924 BIO *bin = NULL;
925 size_t num_extensions = 0;
926
927 if (ctx == NULL || file == NULL) {
928 SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE,
929 ERR_R_PASSED_NULL_PARAMETER);
930 goto end;
931 }
932
933 bin = BIO_new(BIO_s_file_internal());
934 if (bin == NULL) {
935 SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_BUF_LIB);
936 goto end;
937 }
938 if (BIO_read_filename(bin, file) <= 0) {
939 SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_SYS_LIB);
940 goto end;
941 }
942
943 for (num_extensions = 0;; num_extensions++) {
944 if (PEM_read_bio(bin, &name, &header, &extension, &extension_length)
945 == 0) {
946 /*
947 * There must be at least one extension in this file
948 */
949 if (num_extensions == 0) {
950 SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE,
951 SSL_R_NO_PEM_EXTENSIONS);
952 goto end;
953 } else /* End of file, we're done */
954 break;
955 }
956 /* Check that PEM name starts with "BEGIN SERVERINFO FOR " */
957 if (strlen(name) < strlen(namePrefix)) {
958 SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE,
959 SSL_R_PEM_NAME_TOO_SHORT);
960 goto end;
961 }
962 if (strncmp(name, namePrefix, strlen(namePrefix)) != 0) {
963 SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE,
964 SSL_R_PEM_NAME_BAD_PREFIX);
965 goto end;
966 }
967 /*
968 * Check that the decoded PEM data is plausible (valid length field)
969 */
970 if (extension_length < 4
971 || (extension[2] << 8) + extension[3] != extension_length - 4) {
972 SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_BAD_DATA);
973 goto end;
974 }
975 /* Append the decoded extension to the serverinfo buffer */
976 serverinfo =
977 OPENSSL_realloc(serverinfo, serverinfo_length + extension_length);
978 if (serverinfo == NULL) {
979 SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_MALLOC_FAILURE);
980 goto end;
981 }
982 memcpy(serverinfo + serverinfo_length, extension, extension_length);
983 serverinfo_length += extension_length;
984
985 OPENSSL_free(name);
986 name = NULL;
987 OPENSSL_free(header);
988 header = NULL;
989 OPENSSL_free(extension);
990 extension = NULL;
991 }
992
993 ret = SSL_CTX_use_serverinfo(ctx, serverinfo, serverinfo_length);
994 end:
995 /* SSL_CTX_use_serverinfo makes a local copy of the serverinfo. */
996 OPENSSL_free(name);
997 OPENSSL_free(header);
998 OPENSSL_free(extension);
999 OPENSSL_free(serverinfo);
ca3a82c3 1000 BIO_free(bin);
0f113f3e
MC
1001 return ret;
1002}