155714Skris/* ssl/ssl_rsa.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
8296465Sdelphij *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15296465Sdelphij *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
22296465Sdelphij *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
37296465Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40296465Sdelphij *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
52296465Sdelphij *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
5955714Skris#include <stdio.h>
60109998Smarkm#include "ssl_locl.h"
6155714Skris#include <openssl/bio.h>
6255714Skris#include <openssl/objects.h>
6355714Skris#include <openssl/evp.h>
6455714Skris#include <openssl/x509.h>
6555714Skris#include <openssl/pem.h>
6655714Skris
6755714Skrisstatic int ssl_set_cert(CERT *c, X509 *x509);
6855714Skrisstatic int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
6955714Skrisint SSL_use_certificate(SSL *ssl, X509 *x)
70296465Sdelphij{
71296465Sdelphij    if (x == NULL) {
72296465Sdelphij        SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER);
73296465Sdelphij        return (0);
74296465Sdelphij    }
75296465Sdelphij    if (!ssl_cert_inst(&ssl->cert)) {
76296465Sdelphij        SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_MALLOC_FAILURE);
77296465Sdelphij        return (0);
78296465Sdelphij    }
79296465Sdelphij    return (ssl_set_cert(ssl->cert, x));
80296465Sdelphij}
8155714Skris
82109998Smarkm#ifndef OPENSSL_NO_STDIO
8355714Skrisint SSL_use_certificate_file(SSL *ssl, const char *file, int type)
84296465Sdelphij{
85296465Sdelphij    int j;
86296465Sdelphij    BIO *in;
87296465Sdelphij    int ret = 0;
88296465Sdelphij    X509 *x = NULL;
8955714Skris
90296465Sdelphij    in = BIO_new(BIO_s_file_internal());
91296465Sdelphij    if (in == NULL) {
92296465Sdelphij        SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB);
93296465Sdelphij        goto end;
94296465Sdelphij    }
9555714Skris
96296465Sdelphij    if (BIO_read_filename(in, file) <= 0) {
97296465Sdelphij        SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB);
98296465Sdelphij        goto end;
99296465Sdelphij    }
100296465Sdelphij    if (type == SSL_FILETYPE_ASN1) {
101296465Sdelphij        j = ERR_R_ASN1_LIB;
102296465Sdelphij        x = d2i_X509_bio(in, NULL);
103296465Sdelphij    } else if (type == SSL_FILETYPE_PEM) {
104296465Sdelphij        j = ERR_R_PEM_LIB;
105296465Sdelphij        x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback,
106296465Sdelphij                              ssl->ctx->default_passwd_callback_userdata);
107296465Sdelphij    } else {
108296465Sdelphij        SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE);
109296465Sdelphij        goto end;
110296465Sdelphij    }
11155714Skris
112296465Sdelphij    if (x == NULL) {
113296465Sdelphij        SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, j);
114296465Sdelphij        goto end;
115296465Sdelphij    }
11655714Skris
117296465Sdelphij    ret = SSL_use_certificate(ssl, x);
118296465Sdelphij end:
119296465Sdelphij    if (x != NULL)
120296465Sdelphij        X509_free(x);
121296465Sdelphij    if (in != NULL)
122296465Sdelphij        BIO_free(in);
123296465Sdelphij    return (ret);
124296465Sdelphij}
12555714Skris#endif
12655714Skris
127160814Ssimonint SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len)
128296465Sdelphij{
129296465Sdelphij    X509 *x;
130296465Sdelphij    int ret;
13155714Skris
132296465Sdelphij    x = d2i_X509(NULL, &d, (long)len);
133296465Sdelphij    if (x == NULL) {
134296465Sdelphij        SSLerr(SSL_F_SSL_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB);
135296465Sdelphij        return (0);
136296465Sdelphij    }
13755714Skris
138296465Sdelphij    ret = SSL_use_certificate(ssl, x);
139296465Sdelphij    X509_free(x);
140296465Sdelphij    return (ret);
141296465Sdelphij}
14255714Skris
143109998Smarkm#ifndef OPENSSL_NO_RSA
14455714Skrisint SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa)
145296465Sdelphij{
146296465Sdelphij    EVP_PKEY *pkey;
147296465Sdelphij    int ret;
14855714Skris
149296465Sdelphij    if (rsa == NULL) {
150296465Sdelphij        SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
151296465Sdelphij        return (0);
152296465Sdelphij    }
153296465Sdelphij    if (!ssl_cert_inst(&ssl->cert)) {
154296465Sdelphij        SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_MALLOC_FAILURE);
155296465Sdelphij        return (0);
156296465Sdelphij    }
157296465Sdelphij    if ((pkey = EVP_PKEY_new()) == NULL) {
158296465Sdelphij        SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB);
159296465Sdelphij        return (0);
160296465Sdelphij    }
16155714Skris
162296465Sdelphij    RSA_up_ref(rsa);
163296465Sdelphij    EVP_PKEY_assign_RSA(pkey, rsa);
16455714Skris
165296465Sdelphij    ret = ssl_set_pkey(ssl->cert, pkey);
166296465Sdelphij    EVP_PKEY_free(pkey);
167296465Sdelphij    return (ret);
168296465Sdelphij}
16955714Skris#endif
17055714Skris
17155714Skrisstatic int ssl_set_pkey(CERT *c, EVP_PKEY *pkey)
172296465Sdelphij{
173296465Sdelphij    int i;
17455714Skris
175296465Sdelphij    i = ssl_cert_type(NULL, pkey);
176296465Sdelphij    if (i < 0) {
177296465Sdelphij        SSLerr(SSL_F_SSL_SET_PKEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
178296465Sdelphij        return (0);
179296465Sdelphij    }
18055714Skris
181296465Sdelphij    if (c->pkeys[i].x509 != NULL) {
182296465Sdelphij        EVP_PKEY *pktmp;
183296465Sdelphij        pktmp = X509_get_pubkey(c->pkeys[i].x509);
184296465Sdelphij        EVP_PKEY_copy_parameters(pktmp, pkey);
185296465Sdelphij        EVP_PKEY_free(pktmp);
186296465Sdelphij        ERR_clear_error();
18755714Skris
188109998Smarkm#ifndef OPENSSL_NO_RSA
189296465Sdelphij        /*
190296465Sdelphij         * Don't check the public/private key, this is mostly for smart
191296465Sdelphij         * cards.
192296465Sdelphij         */
193296465Sdelphij        if ((pkey->type == EVP_PKEY_RSA) &&
194296465Sdelphij            (RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK)) ;
195296465Sdelphij        else
19655714Skris#endif
197296465Sdelphij        if (!X509_check_private_key(c->pkeys[i].x509, pkey)) {
198296465Sdelphij            X509_free(c->pkeys[i].x509);
199296465Sdelphij            c->pkeys[i].x509 = NULL;
200296465Sdelphij            return 0;
201296465Sdelphij        }
202296465Sdelphij    }
20355714Skris
204296465Sdelphij    if (c->pkeys[i].privatekey != NULL)
205296465Sdelphij        EVP_PKEY_free(c->pkeys[i].privatekey);
206296465Sdelphij    CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
207296465Sdelphij    c->pkeys[i].privatekey = pkey;
208296465Sdelphij    c->key = &(c->pkeys[i]);
20955714Skris
210296465Sdelphij    c->valid = 0;
211296465Sdelphij    return (1);
212296465Sdelphij}
21355714Skris
214109998Smarkm#ifndef OPENSSL_NO_RSA
215296465Sdelphij# ifndef OPENSSL_NO_STDIO
21655714Skrisint SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type)
217296465Sdelphij{
218296465Sdelphij    int j, ret = 0;
219296465Sdelphij    BIO *in;
220296465Sdelphij    RSA *rsa = NULL;
22155714Skris
222296465Sdelphij    in = BIO_new(BIO_s_file_internal());
223296465Sdelphij    if (in == NULL) {
224296465Sdelphij        SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB);
225296465Sdelphij        goto end;
226296465Sdelphij    }
22755714Skris
228296465Sdelphij    if (BIO_read_filename(in, file) <= 0) {
229296465Sdelphij        SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB);
230296465Sdelphij        goto end;
231296465Sdelphij    }
232296465Sdelphij    if (type == SSL_FILETYPE_ASN1) {
233296465Sdelphij        j = ERR_R_ASN1_LIB;
234296465Sdelphij        rsa = d2i_RSAPrivateKey_bio(in, NULL);
235296465Sdelphij    } else if (type == SSL_FILETYPE_PEM) {
236296465Sdelphij        j = ERR_R_PEM_LIB;
237296465Sdelphij        rsa = PEM_read_bio_RSAPrivateKey(in, NULL,
238296465Sdelphij                                         ssl->ctx->default_passwd_callback,
239296465Sdelphij                                         ssl->
240296465Sdelphij                                         ctx->default_passwd_callback_userdata);
241296465Sdelphij    } else {
242296465Sdelphij        SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE);
243296465Sdelphij        goto end;
244296465Sdelphij    }
245296465Sdelphij    if (rsa == NULL) {
246296465Sdelphij        SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, j);
247296465Sdelphij        goto end;
248296465Sdelphij    }
249296465Sdelphij    ret = SSL_use_RSAPrivateKey(ssl, rsa);
250296465Sdelphij    RSA_free(rsa);
251296465Sdelphij end:
252296465Sdelphij    if (in != NULL)
253296465Sdelphij        BIO_free(in);
254296465Sdelphij    return (ret);
255296465Sdelphij}
256296465Sdelphij# endif
25755714Skris
25855714Skrisint SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len)
259296465Sdelphij{
260296465Sdelphij    int ret;
261296465Sdelphij    const unsigned char *p;
262296465Sdelphij    RSA *rsa;
26355714Skris
264296465Sdelphij    p = d;
265296465Sdelphij    if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) {
266296465Sdelphij        SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB);
267296465Sdelphij        return (0);
268296465Sdelphij    }
26955714Skris
270296465Sdelphij    ret = SSL_use_RSAPrivateKey(ssl, rsa);
271296465Sdelphij    RSA_free(rsa);
272296465Sdelphij    return (ret);
273296465Sdelphij}
274296465Sdelphij#endif                          /* !OPENSSL_NO_RSA */
27555714Skris
27655714Skrisint SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey)
277296465Sdelphij{
278296465Sdelphij    int ret;
27955714Skris
280296465Sdelphij    if (pkey == NULL) {
281296465Sdelphij        SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
282296465Sdelphij        return (0);
283296465Sdelphij    }
284296465Sdelphij    if (!ssl_cert_inst(&ssl->cert)) {
285296465Sdelphij        SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE);
286296465Sdelphij        return (0);
287296465Sdelphij    }
288296465Sdelphij    ret = ssl_set_pkey(ssl->cert, pkey);
289296465Sdelphij    return (ret);
290296465Sdelphij}
29155714Skris
292109998Smarkm#ifndef OPENSSL_NO_STDIO
29355714Skrisint SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type)
294296465Sdelphij{
295296465Sdelphij    int j, ret = 0;
296296465Sdelphij    BIO *in;
297296465Sdelphij    EVP_PKEY *pkey = NULL;
29855714Skris
299296465Sdelphij    in = BIO_new(BIO_s_file_internal());
300296465Sdelphij    if (in == NULL) {
301296465Sdelphij        SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB);
302296465Sdelphij        goto end;
303296465Sdelphij    }
30455714Skris
305296465Sdelphij    if (BIO_read_filename(in, file) <= 0) {
306296465Sdelphij        SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB);
307296465Sdelphij        goto end;
308296465Sdelphij    }
309296465Sdelphij    if (type == SSL_FILETYPE_PEM) {
310296465Sdelphij        j = ERR_R_PEM_LIB;
311296465Sdelphij        pkey = PEM_read_bio_PrivateKey(in, NULL,
312296465Sdelphij                                       ssl->ctx->default_passwd_callback,
313296465Sdelphij                                       ssl->
314296465Sdelphij                                       ctx->default_passwd_callback_userdata);
315296465Sdelphij    } else if (type == SSL_FILETYPE_ASN1) {
316296465Sdelphij        j = ERR_R_ASN1_LIB;
317296465Sdelphij        pkey = d2i_PrivateKey_bio(in, NULL);
318296465Sdelphij    } else {
319296465Sdelphij        SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE);
320296465Sdelphij        goto end;
321296465Sdelphij    }
322296465Sdelphij    if (pkey == NULL) {
323296465Sdelphij        SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, j);
324296465Sdelphij        goto end;
325296465Sdelphij    }
326296465Sdelphij    ret = SSL_use_PrivateKey(ssl, pkey);
327296465Sdelphij    EVP_PKEY_free(pkey);
328296465Sdelphij end:
329296465Sdelphij    if (in != NULL)
330296465Sdelphij        BIO_free(in);
331296465Sdelphij    return (ret);
332296465Sdelphij}
33355714Skris#endif
33455714Skris
335296465Sdelphijint SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d,
336296465Sdelphij                            long len)
337296465Sdelphij{
338296465Sdelphij    int ret;
339296465Sdelphij    const unsigned char *p;
340296465Sdelphij    EVP_PKEY *pkey;
34155714Skris
342296465Sdelphij    p = d;
343296465Sdelphij    if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) {
344296465Sdelphij        SSLerr(SSL_F_SSL_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB);
345296465Sdelphij        return (0);
346296465Sdelphij    }
34755714Skris
348296465Sdelphij    ret = SSL_use_PrivateKey(ssl, pkey);
349296465Sdelphij    EVP_PKEY_free(pkey);
350296465Sdelphij    return (ret);
351296465Sdelphij}
35255714Skris
35355714Skrisint SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
354296465Sdelphij{
355296465Sdelphij    if (x == NULL) {
356296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER);
357296465Sdelphij        return (0);
358296465Sdelphij    }
359296465Sdelphij    if (!ssl_cert_inst(&ctx->cert)) {
360296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_MALLOC_FAILURE);
361296465Sdelphij        return (0);
362296465Sdelphij    }
363296465Sdelphij    return (ssl_set_cert(ctx->cert, x));
364296465Sdelphij}
36555714Skris
36655714Skrisstatic int ssl_set_cert(CERT *c, X509 *x)
367296465Sdelphij{
368296465Sdelphij    EVP_PKEY *pkey;
369296465Sdelphij    int i;
37055714Skris
371296465Sdelphij    pkey = X509_get_pubkey(x);
372296465Sdelphij    if (pkey == NULL) {
373296465Sdelphij        SSLerr(SSL_F_SSL_SET_CERT, SSL_R_X509_LIB);
374296465Sdelphij        return (0);
375296465Sdelphij    }
37655714Skris
377296465Sdelphij    i = ssl_cert_type(x, pkey);
378296465Sdelphij    if (i < 0) {
379296465Sdelphij        SSLerr(SSL_F_SSL_SET_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
380296465Sdelphij        EVP_PKEY_free(pkey);
381296465Sdelphij        return (0);
382296465Sdelphij    }
38355714Skris
384296465Sdelphij    if (c->pkeys[i].privatekey != NULL) {
385296465Sdelphij        EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey);
386296465Sdelphij        ERR_clear_error();
38755714Skris
388109998Smarkm#ifndef OPENSSL_NO_RSA
389296465Sdelphij        /*
390296465Sdelphij         * Don't check the public/private key, this is mostly for smart
391296465Sdelphij         * cards.
392296465Sdelphij         */
393296465Sdelphij        if ((c->pkeys[i].privatekey->type == EVP_PKEY_RSA) &&
394296465Sdelphij            (RSA_flags(c->pkeys[i].privatekey->pkey.rsa) &
395296465Sdelphij             RSA_METHOD_FLAG_NO_CHECK)) ;
396296465Sdelphij        else
397296465Sdelphij#endif                          /* OPENSSL_NO_RSA */
398296465Sdelphij        if (!X509_check_private_key(x, c->pkeys[i].privatekey)) {
399296465Sdelphij            /*
400296465Sdelphij             * don't fail for a cert/key mismatch, just free current private
401296465Sdelphij             * key (when switching to a different cert & key, first this
402296465Sdelphij             * function should be used, then ssl_set_pkey
403296465Sdelphij             */
404296465Sdelphij            EVP_PKEY_free(c->pkeys[i].privatekey);
405296465Sdelphij            c->pkeys[i].privatekey = NULL;
406296465Sdelphij            /* clear error queue */
407296465Sdelphij            ERR_clear_error();
408296465Sdelphij        }
409296465Sdelphij    }
41055714Skris
411296465Sdelphij    EVP_PKEY_free(pkey);
41255714Skris
413296465Sdelphij    if (c->pkeys[i].x509 != NULL)
414296465Sdelphij        X509_free(c->pkeys[i].x509);
415296465Sdelphij    CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
416296465Sdelphij    c->pkeys[i].x509 = x;
417296465Sdelphij    c->key = &(c->pkeys[i]);
41855714Skris
419296465Sdelphij    c->valid = 0;
420296465Sdelphij    return (1);
421296465Sdelphij}
42255714Skris
423109998Smarkm#ifndef OPENSSL_NO_STDIO
42455714Skrisint SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
425296465Sdelphij{
426296465Sdelphij    int j;
427296465Sdelphij    BIO *in;
428296465Sdelphij    int ret = 0;
429296465Sdelphij    X509 *x = NULL;
43055714Skris
431296465Sdelphij    in = BIO_new(BIO_s_file_internal());
432296465Sdelphij    if (in == NULL) {
433296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB);
434296465Sdelphij        goto end;
435296465Sdelphij    }
43655714Skris
437296465Sdelphij    if (BIO_read_filename(in, file) <= 0) {
438296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB);
439296465Sdelphij        goto end;
440296465Sdelphij    }
441296465Sdelphij    if (type == SSL_FILETYPE_ASN1) {
442296465Sdelphij        j = ERR_R_ASN1_LIB;
443296465Sdelphij        x = d2i_X509_bio(in, NULL);
444296465Sdelphij    } else if (type == SSL_FILETYPE_PEM) {
445296465Sdelphij        j = ERR_R_PEM_LIB;
446296465Sdelphij        x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
447296465Sdelphij                              ctx->default_passwd_callback_userdata);
448296465Sdelphij    } else {
449296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE);
450296465Sdelphij        goto end;
451296465Sdelphij    }
45255714Skris
453296465Sdelphij    if (x == NULL) {
454296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, j);
455296465Sdelphij        goto end;
456296465Sdelphij    }
45755714Skris
458296465Sdelphij    ret = SSL_CTX_use_certificate(ctx, x);
459296465Sdelphij end:
460296465Sdelphij    if (x != NULL)
461296465Sdelphij        X509_free(x);
462296465Sdelphij    if (in != NULL)
463296465Sdelphij        BIO_free(in);
464296465Sdelphij    return (ret);
465296465Sdelphij}
46655714Skris#endif
46755714Skris
468296465Sdelphijint SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len,
469296465Sdelphij                                 const unsigned char *d)
470296465Sdelphij{
471296465Sdelphij    X509 *x;
472296465Sdelphij    int ret;
47355714Skris
474296465Sdelphij    x = d2i_X509(NULL, &d, (long)len);
475296465Sdelphij    if (x == NULL) {
476296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB);
477296465Sdelphij        return (0);
478296465Sdelphij    }
47955714Skris
480296465Sdelphij    ret = SSL_CTX_use_certificate(ctx, x);
481296465Sdelphij    X509_free(x);
482296465Sdelphij    return (ret);
483296465Sdelphij}
48455714Skris
485109998Smarkm#ifndef OPENSSL_NO_RSA
48655714Skrisint SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa)
487296465Sdelphij{
488296465Sdelphij    int ret;
489296465Sdelphij    EVP_PKEY *pkey;
49055714Skris
491296465Sdelphij    if (rsa == NULL) {
492296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
493296465Sdelphij        return (0);
494296465Sdelphij    }
495296465Sdelphij    if (!ssl_cert_inst(&ctx->cert)) {
496296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_MALLOC_FAILURE);
497296465Sdelphij        return (0);
498296465Sdelphij    }
499296465Sdelphij    if ((pkey = EVP_PKEY_new()) == NULL) {
500296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB);
501296465Sdelphij        return (0);
502296465Sdelphij    }
50355714Skris
504296465Sdelphij    RSA_up_ref(rsa);
505296465Sdelphij    EVP_PKEY_assign_RSA(pkey, rsa);
50655714Skris
507296465Sdelphij    ret = ssl_set_pkey(ctx->cert, pkey);
508296465Sdelphij    EVP_PKEY_free(pkey);
509296465Sdelphij    return (ret);
510296465Sdelphij}
51155714Skris
512296465Sdelphij# ifndef OPENSSL_NO_STDIO
51355714Skrisint SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type)
514296465Sdelphij{
515296465Sdelphij    int j, ret = 0;
516296465Sdelphij    BIO *in;
517296465Sdelphij    RSA *rsa = NULL;
51855714Skris
519296465Sdelphij    in = BIO_new(BIO_s_file_internal());
520296465Sdelphij    if (in == NULL) {
521296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB);
522296465Sdelphij        goto end;
523296465Sdelphij    }
52455714Skris
525296465Sdelphij    if (BIO_read_filename(in, file) <= 0) {
526296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB);
527296465Sdelphij        goto end;
528296465Sdelphij    }
529296465Sdelphij    if (type == SSL_FILETYPE_ASN1) {
530296465Sdelphij        j = ERR_R_ASN1_LIB;
531296465Sdelphij        rsa = d2i_RSAPrivateKey_bio(in, NULL);
532296465Sdelphij    } else if (type == SSL_FILETYPE_PEM) {
533296465Sdelphij        j = ERR_R_PEM_LIB;
534296465Sdelphij        rsa = PEM_read_bio_RSAPrivateKey(in, NULL,
535296465Sdelphij                                         ctx->default_passwd_callback,
536296465Sdelphij                                         ctx->default_passwd_callback_userdata);
537296465Sdelphij    } else {
538296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE);
539296465Sdelphij        goto end;
540296465Sdelphij    }
541296465Sdelphij    if (rsa == NULL) {
542296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, j);
543296465Sdelphij        goto end;
544296465Sdelphij    }
545296465Sdelphij    ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
546296465Sdelphij    RSA_free(rsa);
547296465Sdelphij end:
548296465Sdelphij    if (in != NULL)
549296465Sdelphij        BIO_free(in);
550296465Sdelphij    return (ret);
551296465Sdelphij}
552296465Sdelphij# endif
55355714Skris
554296465Sdelphijint SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d,
555296465Sdelphij                                   long len)
556296465Sdelphij{
557296465Sdelphij    int ret;
558296465Sdelphij    const unsigned char *p;
559296465Sdelphij    RSA *rsa;
56055714Skris
561296465Sdelphij    p = d;
562296465Sdelphij    if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) {
563296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB);
564296465Sdelphij        return (0);
565296465Sdelphij    }
56655714Skris
567296465Sdelphij    ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
568296465Sdelphij    RSA_free(rsa);
569296465Sdelphij    return (ret);
570296465Sdelphij}
571296465Sdelphij#endif                          /* !OPENSSL_NO_RSA */
57255714Skris
57355714Skrisint SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
574296465Sdelphij{
575296465Sdelphij    if (pkey == NULL) {
576296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
577296465Sdelphij        return (0);
578296465Sdelphij    }
579296465Sdelphij    if (!ssl_cert_inst(&ctx->cert)) {
580296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE);
581296465Sdelphij        return (0);
582296465Sdelphij    }
583296465Sdelphij    return (ssl_set_pkey(ctx->cert, pkey));
584296465Sdelphij}
58555714Skris
586109998Smarkm#ifndef OPENSSL_NO_STDIO
58755714Skrisint SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
588296465Sdelphij{
589296465Sdelphij    int j, ret = 0;
590296465Sdelphij    BIO *in;
591296465Sdelphij    EVP_PKEY *pkey = NULL;
59255714Skris
593296465Sdelphij    in = BIO_new(BIO_s_file_internal());
594296465Sdelphij    if (in == NULL) {
595296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB);
596296465Sdelphij        goto end;
597296465Sdelphij    }
59855714Skris
599296465Sdelphij    if (BIO_read_filename(in, file) <= 0) {
600296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB);
601296465Sdelphij        goto end;
602296465Sdelphij    }
603296465Sdelphij    if (type == SSL_FILETYPE_PEM) {
604296465Sdelphij        j = ERR_R_PEM_LIB;
605296465Sdelphij        pkey = PEM_read_bio_PrivateKey(in, NULL,
606296465Sdelphij                                       ctx->default_passwd_callback,
607296465Sdelphij                                       ctx->default_passwd_callback_userdata);
608296465Sdelphij    } else if (type == SSL_FILETYPE_ASN1) {
609296465Sdelphij        j = ERR_R_ASN1_LIB;
610296465Sdelphij        pkey = d2i_PrivateKey_bio(in, NULL);
611296465Sdelphij    } else {
612296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE);
613296465Sdelphij        goto end;
614296465Sdelphij    }
615296465Sdelphij    if (pkey == NULL) {
616296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, j);
617296465Sdelphij        goto end;
618296465Sdelphij    }
619296465Sdelphij    ret = SSL_CTX_use_PrivateKey(ctx, pkey);
620296465Sdelphij    EVP_PKEY_free(pkey);
621296465Sdelphij end:
622296465Sdelphij    if (in != NULL)
623296465Sdelphij        BIO_free(in);
624296465Sdelphij    return (ret);
625296465Sdelphij}
62655714Skris#endif
62755714Skris
628296465Sdelphijint SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx,
629296465Sdelphij                                const unsigned char *d, long len)
630296465Sdelphij{
631296465Sdelphij    int ret;
632296465Sdelphij    const unsigned char *p;
633296465Sdelphij    EVP_PKEY *pkey;
63455714Skris
635296465Sdelphij    p = d;
636296465Sdelphij    if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) {
637296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB);
638296465Sdelphij        return (0);
639296465Sdelphij    }
64055714Skris
641296465Sdelphij    ret = SSL_CTX_use_PrivateKey(ctx, pkey);
642296465Sdelphij    EVP_PKEY_free(pkey);
643296465Sdelphij    return (ret);
644296465Sdelphij}
64555714Skris
646109998Smarkm#ifndef OPENSSL_NO_STDIO
647296465Sdelphij/*
648296465Sdelphij * Read a file that contains our certificate in "PEM" format, possibly
649296465Sdelphij * followed by a sequence of CA certificates that should be sent to the peer
650296465Sdelphij * in the Certificate message.
65155714Skris */
65255714Skrisint SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
653296465Sdelphij{
654296465Sdelphij    BIO *in;
655296465Sdelphij    int ret = 0;
656296465Sdelphij    X509 *x = NULL;
65755714Skris
658296465Sdelphij    ERR_clear_error();          /* clear error stack for
659296465Sdelphij                                 * SSL_CTX_use_certificate() */
660194206Ssimon
661296465Sdelphij    in = BIO_new(BIO_s_file_internal());
662296465Sdelphij    if (in == NULL) {
663296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB);
664296465Sdelphij        goto end;
665296465Sdelphij    }
66655714Skris
667296465Sdelphij    if (BIO_read_filename(in, file) <= 0) {
668296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_SYS_LIB);
669296465Sdelphij        goto end;
670296465Sdelphij    }
67155714Skris
672296465Sdelphij    x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback,
673296465Sdelphij                              ctx->default_passwd_callback_userdata);
674296465Sdelphij    if (x == NULL) {
675296465Sdelphij        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
676296465Sdelphij        goto end;
677296465Sdelphij    }
67855714Skris
679296465Sdelphij    ret = SSL_CTX_use_certificate(ctx, x);
680296465Sdelphij    if (ERR_peek_error() != 0)
681296465Sdelphij        ret = 0;                /* Key/certificate mismatch doesn't imply
682296465Sdelphij                                 * ret==0 ... */
683296465Sdelphij    if (ret) {
684296465Sdelphij        /*
685296465Sdelphij         * If we could set up our certificate, now proceed to the CA
686296465Sdelphij         * certificates.
687296465Sdelphij         */
688296465Sdelphij        X509 *ca;
689296465Sdelphij        int r;
690296465Sdelphij        unsigned long err;
69155714Skris
692296465Sdelphij        if (ctx->extra_certs != NULL) {
693296465Sdelphij            sk_X509_pop_free(ctx->extra_certs, X509_free);
694296465Sdelphij            ctx->extra_certs = NULL;
695296465Sdelphij        }
69655714Skris
697296465Sdelphij        while ((ca =
698296465Sdelphij                PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
699296465Sdelphij                                  ctx->default_passwd_callback_userdata))
700296465Sdelphij               != NULL) {
701296465Sdelphij            r = SSL_CTX_add_extra_chain_cert(ctx, ca);
702296465Sdelphij            if (!r) {
703296465Sdelphij                X509_free(ca);
704296465Sdelphij                ret = 0;
705296465Sdelphij                goto end;
706296465Sdelphij            }
707296465Sdelphij            /*
708296465Sdelphij             * Note that we must not free r if it was successfully added to
709296465Sdelphij             * the chain (while we must free the main certificate, since its
710296465Sdelphij             * reference count is increased by SSL_CTX_use_certificate).
711296465Sdelphij             */
712296465Sdelphij        }
713296465Sdelphij        /* When the while loop ends, it's usually just EOF. */
714296465Sdelphij        err = ERR_peek_last_error();
715296465Sdelphij        if (ERR_GET_LIB(err) == ERR_LIB_PEM
716296465Sdelphij            && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)
717296465Sdelphij            ERR_clear_error();
718296465Sdelphij        else
719296465Sdelphij            ret = 0;            /* some real error */
720296465Sdelphij    }
721296465Sdelphij
722296465Sdelphij end:
723296465Sdelphij    if (x != NULL)
724296465Sdelphij        X509_free(x);
725296465Sdelphij    if (in != NULL)
726296465Sdelphij        BIO_free(in);
727296465Sdelphij    return (ret);
728296465Sdelphij}
72955714Skris#endif
730