ssl_rsa.c 27.2 KB
Newer Older
R
Rich Salz 已提交
1 2
/*
 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3
 *
R
Rich Salz 已提交
4 5 6 7
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
8 9 10
 */

#include <stdio.h>
11
#include "ssl_locl.h"
12 13 14 15 16
#include <openssl/bio.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
17 18 19

static int ssl_set_cert(CERT *c, X509 *x509);
static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
U
Ulf Möller 已提交
20
int SSL_use_certificate(SSL *ssl, X509 *x)
21 22 23 24 25 26 27 28 29 30 31 32 33 34
{
    int rv;
    if (x == NULL) {
        SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER);
        return (0);
    }
    rv = ssl_security_cert(ssl, NULL, x, 0, 1);
    if (rv != 1) {
        SSLerr(SSL_F_SSL_USE_CERTIFICATE, rv);
        return 0;
    }

    return (ssl_set_cert(ssl->cert, x));
}
35

36
int SSL_use_certificate_file(SSL *ssl, const char *file, int type)
37 38 39 40 41 42
{
    int j;
    BIO *in;
    int ret = 0;
    X509 *x = NULL;

R
Rich Salz 已提交
43
    in = BIO_new(BIO_s_file());
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
    if (in == NULL) {
        SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB);
        goto end;
    }

    if (BIO_read_filename(in, file) <= 0) {
        SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB);
        goto end;
    }
    if (type == SSL_FILETYPE_ASN1) {
        j = ERR_R_ASN1_LIB;
        x = d2i_X509_bio(in, NULL);
    } else if (type == SSL_FILETYPE_PEM) {
        j = ERR_R_PEM_LIB;
        x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback,
                              ssl->ctx->default_passwd_callback_userdata);
    } else {
        SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE);
        goto end;
    }

    if (x == NULL) {
        SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, j);
        goto end;
    }

    ret = SSL_use_certificate(ssl, x);
 end:
R
Rich Salz 已提交
72
    X509_free(x);
R
Rich Salz 已提交
73
    BIO_free(in);
74 75
    return (ret);
}
76

77
int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len)
78 79 80 81 82 83 84 85 86 87 88 89 90 91
{
    X509 *x;
    int ret;

    x = d2i_X509(NULL, &d, (long)len);
    if (x == NULL) {
        SSLerr(SSL_F_SSL_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB);
        return (0);
    }

    ret = SSL_use_certificate(ssl, x);
    X509_free(x);
    return (ret);
}
92

93
#ifndef OPENSSL_NO_RSA
U
Ulf Möller 已提交
94
int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa)
95 96 97 98 99 100 101 102 103 104 105 106 107 108
{
    EVP_PKEY *pkey;
    int ret;

    if (rsa == NULL) {
        SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
        return (0);
    }
    if ((pkey = EVP_PKEY_new()) == NULL) {
        SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB);
        return (0);
    }

    RSA_up_ref(rsa);
109 110
    if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) {
        RSA_free(rsa);
M
Miroslav Franc 已提交
111
        EVP_PKEY_free(pkey);
112 113
        return 0;
    }
114 115 116 117 118

    ret = ssl_set_pkey(ssl->cert, pkey);
    EVP_PKEY_free(pkey);
    return (ret);
}
119 120
#endif

U
Ulf Möller 已提交
121
static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey)
122 123
{
    int i;
D
Dr. Stephen Henson 已提交
124
    i = ssl_cert_type(NULL, pkey);
125 126 127 128 129 130 131
    if (i < 0) {
        SSLerr(SSL_F_SSL_SET_PKEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
        return (0);
    }

    if (c->pkeys[i].x509 != NULL) {
        EVP_PKEY *pktmp;
132
        pktmp = X509_get0_pubkey(c->pkeys[i].x509);
133 134 135 136 137 138 139 140
        if (pktmp == NULL) {
            SSLerr(SSL_F_SSL_SET_PKEY, ERR_R_MALLOC_FAILURE);
            return 0;
        }
        /*
         * The return code from EVP_PKEY_copy_parameters is deliberately
         * ignored. Some EVP_PKEY types cannot do this.
         */
141 142
        EVP_PKEY_copy_parameters(pktmp, pkey);
        ERR_clear_error();
143

144
#ifndef OPENSSL_NO_RSA
145 146 147 148
        /*
         * Don't check the public/private key, this is mostly for smart
         * cards.
         */
D
Dr. Stephen Henson 已提交
149
        if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA
E
Emilia Kasper 已提交
150
            && RSA_flags(EVP_PKEY_get0_RSA(pkey)) & RSA_METHOD_FLAG_NO_CHECK) ;
151
        else
152
#endif
153 154 155 156 157 158 159
        if (!X509_check_private_key(c->pkeys[i].x509, pkey)) {
            X509_free(c->pkeys[i].x509);
            c->pkeys[i].x509 = NULL;
            return 0;
        }
    }

R
Rich Salz 已提交
160
    EVP_PKEY_free(c->pkeys[i].privatekey);
D
Dr. Stephen Henson 已提交
161
    EVP_PKEY_up_ref(pkey);
162 163 164 165
    c->pkeys[i].privatekey = pkey;
    c->key = &(c->pkeys[i]);
    return (1);
}
166

167
#ifndef OPENSSL_NO_RSA
168
int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type)
169 170 171 172 173
{
    int j, ret = 0;
    BIO *in;
    RSA *rsa = NULL;

R
Rich Salz 已提交
174
    in = BIO_new(BIO_s_file());
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
    if (in == NULL) {
        SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB);
        goto end;
    }

    if (BIO_read_filename(in, file) <= 0) {
        SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB);
        goto end;
    }
    if (type == SSL_FILETYPE_ASN1) {
        j = ERR_R_ASN1_LIB;
        rsa = d2i_RSAPrivateKey_bio(in, NULL);
    } else if (type == SSL_FILETYPE_PEM) {
        j = ERR_R_PEM_LIB;
        rsa = PEM_read_bio_RSAPrivateKey(in, NULL,
                                         ssl->ctx->default_passwd_callback,
                                         ssl->
                                         ctx->default_passwd_callback_userdata);
    } else {
        SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE);
        goto end;
    }
    if (rsa == NULL) {
        SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, j);
        goto end;
    }
    ret = SSL_use_RSAPrivateKey(ssl, rsa);
    RSA_free(rsa);
 end:
R
Rich Salz 已提交
204
    BIO_free(in);
205 206
    return (ret);
}
207

208
int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, long len)
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
{
    int ret;
    const unsigned char *p;
    RSA *rsa;

    p = d;
    if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) {
        SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB);
        return (0);
    }

    ret = SSL_use_RSAPrivateKey(ssl, rsa);
    RSA_free(rsa);
    return (ret);
}
#endif                          /* !OPENSSL_NO_RSA */
225

U
Ulf Möller 已提交
226
int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey)
227 228 229 230 231 232 233 234 235 236
{
    int ret;

    if (pkey == NULL) {
        SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
        return (0);
    }
    ret = ssl_set_pkey(ssl->cert, pkey);
    return (ret);
}
237

238
int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type)
239 240 241 242 243
{
    int j, ret = 0;
    BIO *in;
    EVP_PKEY *pkey = NULL;

R
Rich Salz 已提交
244
    in = BIO_new(BIO_s_file());
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
    if (in == NULL) {
        SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB);
        goto end;
    }

    if (BIO_read_filename(in, file) <= 0) {
        SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB);
        goto end;
    }
    if (type == SSL_FILETYPE_PEM) {
        j = ERR_R_PEM_LIB;
        pkey = PEM_read_bio_PrivateKey(in, NULL,
                                       ssl->ctx->default_passwd_callback,
                                       ssl->
                                       ctx->default_passwd_callback_userdata);
    } else if (type == SSL_FILETYPE_ASN1) {
        j = ERR_R_ASN1_LIB;
        pkey = d2i_PrivateKey_bio(in, NULL);
    } else {
        SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE);
        goto end;
    }
    if (pkey == NULL) {
        SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, j);
        goto end;
    }
    ret = SSL_use_PrivateKey(ssl, pkey);
    EVP_PKEY_free(pkey);
 end:
R
Rich Salz 已提交
274
    BIO_free(in);
275 276
    return (ret);
}
277

278 279 280 281 282 283
int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d,
                            long len)
{
    int ret;
    const unsigned char *p;
    EVP_PKEY *pkey;
284

285 286 287 288 289
    p = d;
    if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) {
        SSLerr(SSL_F_SSL_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB);
        return (0);
    }
290

291 292 293 294
    ret = SSL_use_PrivateKey(ssl, pkey);
    EVP_PKEY_free(pkey);
    return (ret);
}
295

U
Ulf Möller 已提交
296
int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
297 298 299 300 301 302 303 304 305 306 307 308 309
{
    int rv;
    if (x == NULL) {
        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER);
        return (0);
    }
    rv = ssl_security_cert(NULL, ctx, x, 0, 1);
    if (rv != 1) {
        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, rv);
        return 0;
    }
    return (ssl_set_cert(ctx->cert, x));
}
310

U
Ulf Möller 已提交
311
static int ssl_set_cert(CERT *c, X509 *x)
312 313 314 315
{
    EVP_PKEY *pkey;
    int i;

316
    pkey = X509_get0_pubkey(x);
317 318 319 320 321 322 323 324
    if (pkey == NULL) {
        SSLerr(SSL_F_SSL_SET_CERT, SSL_R_X509_LIB);
        return (0);
    }

    i = ssl_cert_type(x, pkey);
    if (i < 0) {
        SSLerr(SSL_F_SSL_SET_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
325
        return 0;
326
    }
D
Dr. Stephen Henson 已提交
327
#ifndef OPENSSL_NO_EC
D
Dr. Stephen Henson 已提交
328 329 330 331
    if (i == SSL_PKEY_ECC && !EC_KEY_can_sign(EVP_PKEY_get0_EC_KEY(pkey))) {
        SSLerr(SSL_F_SSL_SET_CERT, SSL_R_ECC_CERT_NOT_FOR_SIGNING);
        return 0;
    }
D
Dr. Stephen Henson 已提交
332
#endif
333
    if (c->pkeys[i].privatekey != NULL) {
334 335 336 337
        /*
         * The return code from EVP_PKEY_copy_parameters is deliberately
         * ignored. Some EVP_PKEY types cannot do this.
         */
338 339
        EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey);
        ERR_clear_error();
340

341
#ifndef OPENSSL_NO_RSA
342 343 344 345
        /*
         * Don't check the public/private key, this is mostly for smart
         * cards.
         */
D
Dr. Stephen Henson 已提交
346 347
        if (EVP_PKEY_id(c->pkeys[i].privatekey) == EVP_PKEY_RSA
            && RSA_flags(EVP_PKEY_get0_RSA(c->pkeys[i].privatekey)) &
E
Emilia Kasper 已提交
348
            RSA_METHOD_FLAG_NO_CHECK) ;
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363
        else
#endif                          /* OPENSSL_NO_RSA */
        if (!X509_check_private_key(x, c->pkeys[i].privatekey)) {
            /*
             * don't fail for a cert/key mismatch, just free current private
             * key (when switching to a different cert & key, first this
             * function should be used, then ssl_set_pkey
             */
            EVP_PKEY_free(c->pkeys[i].privatekey);
            c->pkeys[i].privatekey = NULL;
            /* clear error queue */
            ERR_clear_error();
        }
    }

R
Rich Salz 已提交
364
    X509_free(c->pkeys[i].x509);
D
Dr. Stephen Henson 已提交
365
    X509_up_ref(x);
366 367 368
    c->pkeys[i].x509 = x;
    c->key = &(c->pkeys[i]);

369
    return 1;
370
}
371

372
int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
373 374 375 376 377 378
{
    int j;
    BIO *in;
    int ret = 0;
    X509 *x = NULL;

R
Rich Salz 已提交
379
    in = BIO_new(BIO_s_file());
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407
    if (in == NULL) {
        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB);
        goto end;
    }

    if (BIO_read_filename(in, file) <= 0) {
        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB);
        goto end;
    }
    if (type == SSL_FILETYPE_ASN1) {
        j = ERR_R_ASN1_LIB;
        x = d2i_X509_bio(in, NULL);
    } else if (type == SSL_FILETYPE_PEM) {
        j = ERR_R_PEM_LIB;
        x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
                              ctx->default_passwd_callback_userdata);
    } else {
        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE);
        goto end;
    }

    if (x == NULL) {
        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, j);
        goto end;
    }

    ret = SSL_CTX_use_certificate(ctx, x);
 end:
R
Rich Salz 已提交
408
    X509_free(x);
R
Rich Salz 已提交
409
    BIO_free(in);
410 411
    return (ret);
}
412

E
Emilia Kasper 已提交
413
int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d)
414 415 416
{
    X509 *x;
    int ret;
417

418 419 420 421 422
    x = d2i_X509(NULL, &d, (long)len);
    if (x == NULL) {
        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB);
        return (0);
    }
423

424 425 426 427
    ret = SSL_CTX_use_certificate(ctx, x);
    X509_free(x);
    return (ret);
}
428

429
#ifndef OPENSSL_NO_RSA
U
Ulf Möller 已提交
430
int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa)
431 432 433 434 435 436 437 438 439 440 441 442 443 444
{
    int ret;
    EVP_PKEY *pkey;

    if (rsa == NULL) {
        SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
        return (0);
    }
    if ((pkey = EVP_PKEY_new()) == NULL) {
        SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB);
        return (0);
    }

    RSA_up_ref(rsa);
445 446
    if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) {
        RSA_free(rsa);
M
Miroslav Franc 已提交
447
        EVP_PKEY_free(pkey);
448 449
        return 0;
    }
450 451 452 453 454 455

    ret = ssl_set_pkey(ctx->cert, pkey);
    EVP_PKEY_free(pkey);
    return (ret);
}

456
int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type)
457 458 459 460 461
{
    int j, ret = 0;
    BIO *in;
    RSA *rsa = NULL;

R
Rich Salz 已提交
462
    in = BIO_new(BIO_s_file());
463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490
    if (in == NULL) {
        SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB);
        goto end;
    }

    if (BIO_read_filename(in, file) <= 0) {
        SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB);
        goto end;
    }
    if (type == SSL_FILETYPE_ASN1) {
        j = ERR_R_ASN1_LIB;
        rsa = d2i_RSAPrivateKey_bio(in, NULL);
    } else if (type == SSL_FILETYPE_PEM) {
        j = ERR_R_PEM_LIB;
        rsa = PEM_read_bio_RSAPrivateKey(in, NULL,
                                         ctx->default_passwd_callback,
                                         ctx->default_passwd_callback_userdata);
    } else {
        SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE);
        goto end;
    }
    if (rsa == NULL) {
        SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, j);
        goto end;
    }
    ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
    RSA_free(rsa);
 end:
R
Rich Salz 已提交
491
    BIO_free(in);
492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512
    return (ret);
}

int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d,
                                   long len)
{
    int ret;
    const unsigned char *p;
    RSA *rsa;

    p = d;
    if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) {
        SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB);
        return (0);
    }

    ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
    RSA_free(rsa);
    return (ret);
}
#endif                          /* !OPENSSL_NO_RSA */
513

U
Ulf Möller 已提交
514
int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
515 516 517 518 519 520 521
{
    if (pkey == NULL) {
        SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
        return (0);
    }
    return (ssl_set_pkey(ctx->cert, pkey));
}
522

523
int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
524 525 526 527 528
{
    int j, ret = 0;
    BIO *in;
    EVP_PKEY *pkey = NULL;

R
Rich Salz 已提交
529
    in = BIO_new(BIO_s_file());
530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557
    if (in == NULL) {
        SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB);
        goto end;
    }

    if (BIO_read_filename(in, file) <= 0) {
        SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB);
        goto end;
    }
    if (type == SSL_FILETYPE_PEM) {
        j = ERR_R_PEM_LIB;
        pkey = PEM_read_bio_PrivateKey(in, NULL,
                                       ctx->default_passwd_callback,
                                       ctx->default_passwd_callback_userdata);
    } else if (type == SSL_FILETYPE_ASN1) {
        j = ERR_R_ASN1_LIB;
        pkey = d2i_PrivateKey_bio(in, NULL);
    } else {
        SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE);
        goto end;
    }
    if (pkey == NULL) {
        SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, j);
        goto end;
    }
    ret = SSL_CTX_use_PrivateKey(ctx, pkey);
    EVP_PKEY_free(pkey);
 end:
R
Rich Salz 已提交
558
    BIO_free(in);
559 560
    return (ret);
}
561

562 563 564 565 566 567
int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx,
                                const unsigned char *d, long len)
{
    int ret;
    const unsigned char *p;
    EVP_PKEY *pkey;
568

569 570 571 572 573
    p = d;
    if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) {
        SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB);
        return (0);
    }
574

575 576 577 578
    ret = SSL_CTX_use_PrivateKey(ctx, pkey);
    EVP_PKEY_free(pkey);
    return (ret);
}
579

580 581 582 583
/*
 * Read a file that contains our certificate in "PEM" format, possibly
 * followed by a sequence of CA certificates that should be sent to the peer
 * in the Certificate message.
584
 */
585
static int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file)
586 587 588 589
{
    BIO *in;
    int ret = 0;
    X509 *x = NULL;
M
Matt Caswell 已提交
590 591
    pem_password_cb *passwd_callback;
    void *passwd_callback_userdata;
592 593 594 595

    ERR_clear_error();          /* clear error stack for
                                 * SSL_CTX_use_certificate() */

M
Matt Caswell 已提交
596 597 598 599 600 601 602 603
    if (ctx != NULL) {
        passwd_callback = ctx->default_passwd_callback;
        passwd_callback_userdata = ctx->default_passwd_callback_userdata;
    } else {
        passwd_callback = ssl->default_passwd_callback;
        passwd_callback_userdata = ssl->default_passwd_callback_userdata;
    }

R
Rich Salz 已提交
604
    in = BIO_new(BIO_s_file());
605
    if (in == NULL) {
606
        SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB);
607 608 609 610
        goto end;
    }

    if (BIO_read_filename(in, file) <= 0) {
611
        SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_SYS_LIB);
612 613 614
        goto end;
    }

M
Matt Caswell 已提交
615 616
    x = PEM_read_bio_X509_AUX(in, NULL, passwd_callback,
                              passwd_callback_userdata);
617
    if (x == NULL) {
618
        SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
619 620 621
        goto end;
    }

622 623 624 625
    if (ctx)
        ret = SSL_CTX_use_certificate(ctx, x);
    else
        ret = SSL_use_certificate(ssl, x);
626 627 628 629 630 631 632 633 634 635 636 637 638

    if (ERR_peek_error() != 0)
        ret = 0;                /* Key/certificate mismatch doesn't imply
                                 * ret==0 ... */
    if (ret) {
        /*
         * If we could set up our certificate, now proceed to the CA
         * certificates.
         */
        X509 *ca;
        int r;
        unsigned long err;

639 640 641 642 643 644
        if (ctx)
            r = SSL_CTX_clear_chain_certs(ctx);
        else
            r = SSL_clear_chain_certs(ssl);

        if (r == 0) {
M
Matt Caswell 已提交
645 646 647
            ret = 0;
            goto end;
        }
648

M
Matt Caswell 已提交
649 650
        while ((ca = PEM_read_bio_X509(in, NULL, passwd_callback,
                                       passwd_callback_userdata))
E
Emilia Kasper 已提交
651
               != NULL) {
652 653 654 655 656 657 658 659 660
            if (ctx)
                r = SSL_CTX_add0_chain_cert(ctx, ca);
            else
                r = SSL_add0_chain_cert(ssl, ca);
            /*
             * Note that we must not free ca if it was successfully added to
             * the chain (while we must free the main certificate, since its
             * reference count is increased by SSL_CTX_use_certificate).
             */
661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676
            if (!r) {
                X509_free(ca);
                ret = 0;
                goto end;
            }
        }
        /* When the while loop ends, it's usually just EOF. */
        err = ERR_peek_last_error();
        if (ERR_GET_LIB(err) == ERR_LIB_PEM
            && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)
            ERR_clear_error();
        else
            ret = 0;            /* some real error */
    }

 end:
R
Rich Salz 已提交
677
    X509_free(x);
R
Rich Salz 已提交
678
    BIO_free(in);
679 680
    return (ret);
}
681 682 683 684 685 686 687 688 689 690

int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
{
    return use_certificate_chain_file(ctx, NULL, file);
}

int SSL_use_certificate_chain_file(SSL *ssl, const char *file)
{
    return use_certificate_chain_file(NULL, ssl, file);
}
B
Ben Laurie 已提交
691

692
static int serverinfo_find_extension(const unsigned char *serverinfo,
693 694 695 696 697 698 699 700
                                     size_t serverinfo_length,
                                     unsigned int extension_type,
                                     const unsigned char **extension_data,
                                     size_t *extension_length)
{
    *extension_data = NULL;
    *extension_length = 0;
    if (serverinfo == NULL || serverinfo_length == 0)
701
        return -1;
702 703 704 705 706 707
    for (;;) {
        unsigned int type = 0;
        size_t len = 0;

        /* end of serverinfo */
        if (serverinfo_length == 0)
708
            return 0;           /* Extension not found */
709 710 711

        /* read 2-byte type field */
        if (serverinfo_length < 2)
712
            return -1;          /* Error */
713 714 715 716 717 718
        type = (serverinfo[0] << 8) + serverinfo[1];
        serverinfo += 2;
        serverinfo_length -= 2;

        /* read 2-byte len field */
        if (serverinfo_length < 2)
719
            return -1;          /* Error */
720 721 722 723 724
        len = (serverinfo[0] << 8) + serverinfo[1];
        serverinfo += 2;
        serverinfo_length -= 2;

        if (len > serverinfo_length)
725
            return -1;          /* Error */
726 727 728 729 730 731 732 733 734 735

        if (type == extension_type) {
            *extension_data = serverinfo;
            *extension_length = len;
            return 1;           /* Success */
        }

        serverinfo += len;
        serverinfo_length -= len;
    }
736
    /* Unreachable */
737
}
738

D
Dr. Stephen Henson 已提交
739
static int serverinfo_srv_parse_cb(SSL *s, unsigned int ext_type,
740 741 742
                                   const unsigned char *in,
                                   size_t inlen, int *al, void *arg)
{
B
Ben Laurie 已提交
743

744 745 746 747
    if (inlen != 0) {
        *al = SSL_AD_DECODE_ERROR;
        return 0;
    }
B
Ben Laurie 已提交
748

749 750
    return 1;
}
T
Trevor 已提交
751

D
Dr. Stephen Henson 已提交
752
static int serverinfo_srv_add_cb(SSL *s, unsigned int ext_type,
753 754 755 756 757 758 759 760 761 762 763 764
                                 const unsigned char **out, size_t *outlen,
                                 int *al, void *arg)
{
    const unsigned char *serverinfo = NULL;
    size_t serverinfo_length = 0;

    /* Is there serverinfo data for the chosen server cert? */
    if ((ssl_get_server_cert_serverinfo(s, &serverinfo,
                                        &serverinfo_length)) != 0) {
        /* Find the relevant extension from the serverinfo */
        int retval = serverinfo_find_extension(serverinfo, serverinfo_length,
                                               ext_type, out, outlen);
765 766 767 768
        if (retval == -1) {
            *al = SSL_AD_DECODE_ERROR;
            return -1;          /* Error */
        }
769
        if (retval == 0)
770
            return 0;           /* No extension found, don't send extension */
771 772
        return 1;               /* Send extension */
    }
T
TJ Saunders 已提交
773
    return 0;                   /* No serverinfo data found, don't send
774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801
                                 * extension */
}

/*
 * With a NULL context, this function just checks that the serverinfo data
 * parses correctly.  With a non-NULL context, it registers callbacks for
 * the included extensions.
 */
static int serverinfo_process_buffer(const unsigned char *serverinfo,
                                     size_t serverinfo_length, SSL_CTX *ctx)
{
    if (serverinfo == NULL || serverinfo_length == 0)
        return 0;
    for (;;) {
        unsigned int ext_type = 0;
        size_t len = 0;

        /* end of serverinfo */
        if (serverinfo_length == 0)
            return 1;

        /* read 2-byte type field */
        if (serverinfo_length < 2)
            return 0;
        /* FIXME: check for types we understand explicitly? */

        /* Register callbacks for extensions */
        ext_type = (serverinfo[0] << 8) + serverinfo[1];
T
TJ Saunders 已提交
802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821
        if (ctx) {
            int have_ext_cbs = 0;
            size_t i;
            custom_ext_methods *exts = &ctx->cert->srv_ext;
            custom_ext_method *meth = exts->meths;

            for (i = 0; i < exts->meths_count; i++, meth++) {
                if (ext_type == meth->ext_type) {
                    have_ext_cbs = 1;
                    break;
                }
            }

            if (!have_ext_cbs && !SSL_CTX_add_server_custom_ext(ctx, ext_type,
                                                                serverinfo_srv_add_cb,
                                                                NULL, NULL,
                                                                serverinfo_srv_parse_cb,
                                                                NULL))
                return 0;
        }
822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839

        serverinfo += 2;
        serverinfo_length -= 2;

        /* read 2-byte len field */
        if (serverinfo_length < 2)
            return 0;
        len = (serverinfo[0] << 8) + serverinfo[1];
        serverinfo += 2;
        serverinfo_length -= 2;

        if (len > serverinfo_length)
            return 0;

        serverinfo += len;
        serverinfo_length -= len;
    }
}
840 841

int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878
                           size_t serverinfo_length)
{
    unsigned char *new_serverinfo;

    if (ctx == NULL || serverinfo == NULL || serverinfo_length == 0) {
        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }
    if (!serverinfo_process_buffer(serverinfo, serverinfo_length, NULL)) {
        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, SSL_R_INVALID_SERVERINFO_DATA);
        return 0;
    }
    if (ctx->cert->key == NULL) {
        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_INTERNAL_ERROR);
        return 0;
    }
    new_serverinfo = OPENSSL_realloc(ctx->cert->key->serverinfo,
                                     serverinfo_length);
    if (new_serverinfo == NULL) {
        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_MALLOC_FAILURE);
        return 0;
    }
    ctx->cert->key->serverinfo = new_serverinfo;
    memcpy(ctx->cert->key->serverinfo, serverinfo, serverinfo_length);
    ctx->cert->key->serverinfo_length = serverinfo_length;

    /*
     * Now that the serverinfo is validated and stored, go ahead and
     * register callbacks.
     */
    if (!serverinfo_process_buffer(serverinfo, serverinfo_length, ctx)) {
        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, SSL_R_INVALID_SERVERINFO_DATA);
        return 0;
    }
    return 1;
}

879
int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file)
880 881
{
    unsigned char *serverinfo = NULL;
882
    unsigned char *tmp;
883 884 885 886 887 888 889 890 891 892 893
    size_t serverinfo_length = 0;
    unsigned char *extension = 0;
    long extension_length = 0;
    char *name = NULL;
    char *header = NULL;
    char namePrefix[] = "SERVERINFO FOR ";
    int ret = 0;
    BIO *bin = NULL;
    size_t num_extensions = 0;

    if (ctx == NULL || file == NULL) {
E
Emilia Kasper 已提交
894
        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_PASSED_NULL_PARAMETER);
895 896 897
        goto end;
    }

R
Rich Salz 已提交
898
    bin = BIO_new(BIO_s_file());
899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922
    if (bin == NULL) {
        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_BUF_LIB);
        goto end;
    }
    if (BIO_read_filename(bin, file) <= 0) {
        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_SYS_LIB);
        goto end;
    }

    for (num_extensions = 0;; num_extensions++) {
        if (PEM_read_bio(bin, &name, &header, &extension, &extension_length)
            == 0) {
            /*
             * There must be at least one extension in this file
             */
            if (num_extensions == 0) {
                SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE,
                       SSL_R_NO_PEM_EXTENSIONS);
                goto end;
            } else              /* End of file, we're done */
                break;
        }
        /* Check that PEM name starts with "BEGIN SERVERINFO FOR " */
        if (strlen(name) < strlen(namePrefix)) {
E
Emilia Kasper 已提交
923
            SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_PEM_NAME_TOO_SHORT);
924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939
            goto end;
        }
        if (strncmp(name, namePrefix, strlen(namePrefix)) != 0) {
            SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE,
                   SSL_R_PEM_NAME_BAD_PREFIX);
            goto end;
        }
        /*
         * Check that the decoded PEM data is plausible (valid length field)
         */
        if (extension_length < 4
            || (extension[2] << 8) + extension[3] != extension_length - 4) {
            SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_BAD_DATA);
            goto end;
        }
        /* Append the decoded extension to the serverinfo buffer */
E
Emilia Kasper 已提交
940
        tmp = OPENSSL_realloc(serverinfo, serverinfo_length + extension_length);
941
        if (tmp == NULL) {
942 943 944
            SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_MALLOC_FAILURE);
            goto end;
        }
945
        serverinfo = tmp;
946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963
        memcpy(serverinfo + serverinfo_length, extension, extension_length);
        serverinfo_length += extension_length;

        OPENSSL_free(name);
        name = NULL;
        OPENSSL_free(header);
        header = NULL;
        OPENSSL_free(extension);
        extension = NULL;
    }

    ret = SSL_CTX_use_serverinfo(ctx, serverinfo, serverinfo_length);
 end:
    /* SSL_CTX_use_serverinfo makes a local copy of the serverinfo. */
    OPENSSL_free(name);
    OPENSSL_free(header);
    OPENSSL_free(extension);
    OPENSSL_free(serverinfo);
R
Rich Salz 已提交
964
    BIO_free(bin);
965 966
    return ret;
}