Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 1 | /* ssl/ssl_rsa.c */ |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 3 | * All rights reserved. |
| 4 | * |
| 5 | * This package is an SSL implementation written |
| 6 | * by Eric Young (eay@cryptsoft.com). |
| 7 | * The implementation was written so as to conform with Netscapes SSL. |
| 8 | * |
| 9 | * This library is free for commercial and non-commercial use as long as |
| 10 | * the following conditions are aheared to. The following conditions |
| 11 | * apply to all code found in this distribution, be it the RC4, RSA, |
| 12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation |
| 13 | * included with this distribution is covered by the same copyright terms |
| 14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). |
| 15 | * |
| 16 | * Copyright remains Eric Young's, and as such any Copyright notices in |
| 17 | * the code are not to be removed. |
| 18 | * If this package is used in a product, Eric Young should be given attribution |
| 19 | * as the author of the parts of the library used. |
| 20 | * This can be in the form of a textual message at program startup or |
| 21 | * in documentation (online or textual) provided with the package. |
| 22 | * |
| 23 | * Redistribution and use in source and binary forms, with or without |
| 24 | * modification, are permitted provided that the following conditions |
| 25 | * are met: |
| 26 | * 1. Redistributions of source code must retain the copyright |
| 27 | * notice, this list of conditions and the following disclaimer. |
| 28 | * 2. Redistributions in binary form must reproduce the above copyright |
| 29 | * notice, this list of conditions and the following disclaimer in the |
| 30 | * documentation and/or other materials provided with the distribution. |
| 31 | * 3. All advertising materials mentioning features or use of this software |
| 32 | * must display the following acknowledgement: |
| 33 | * "This product includes cryptographic software written by |
| 34 | * Eric Young (eay@cryptsoft.com)" |
| 35 | * The word 'cryptographic' can be left out if the rouines from the library |
| 36 | * being used are not cryptographic related :-). |
| 37 | * 4. If you include any Windows specific code (or a derivative thereof) from |
| 38 | * the apps directory (application code) you must include an acknowledgement: |
| 39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" |
| 40 | * |
| 41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND |
| 42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
| 45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 51 | * SUCH DAMAGE. |
| 52 | * |
| 53 | * The licence and distribution terms for any publically available version or |
| 54 | * derivative of this code cannot be changed. i.e. this code cannot simply be |
| 55 | * copied and put under another distribution licence |
| 56 | * [including the GNU Public Licence.] |
| 57 | */ |
| 58 | |
| 59 | #include <stdio.h> |
Lutz Jänicke | 7b63c0f | 2002-07-10 07:01:54 +0000 | [diff] [blame] | 60 | #include "ssl_locl.h" |
Bodo Möller | ec57782 | 1999-04-23 22:13:45 +0000 | [diff] [blame] | 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> |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 66 | |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 67 | static int ssl_set_cert(CERT *c, X509 *x509); |
| 68 | static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey); |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 69 | int SSL_use_certificate(SSL *ssl, X509 *x) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 70 | { |
Dr. Stephen Henson | b362cca | 2013-12-15 13:32:24 +0000 | [diff] [blame] | 71 | int rv; |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 72 | if (x == NULL) |
| 73 | { |
| 74 | SSLerr(SSL_F_SSL_USE_CERTIFICATE,ERR_R_PASSED_NULL_PARAMETER); |
| 75 | return(0); |
| 76 | } |
Dr. Stephen Henson | b362cca | 2013-12-15 13:32:24 +0000 | [diff] [blame] | 77 | rv = ssl_security_cert(ssl, NULL, x, 0, 1); |
| 78 | if (rv != 1) |
| 79 | { |
| 80 | SSLerr(SSL_F_SSL_USE_CERTIFICATE, rv); |
| 81 | return 0; |
| 82 | } |
| 83 | |
Bodo Möller | ca8e5b9 | 1999-05-09 20:12:44 +0000 | [diff] [blame] | 84 | if (!ssl_cert_inst(&ssl->cert)) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 85 | { |
Ralf S. Engelschall | 15d21c2 | 1999-02-25 14:40:29 +0000 | [diff] [blame] | 86 | SSLerr(SSL_F_SSL_USE_CERTIFICATE,ERR_R_MALLOC_FAILURE); |
| 87 | return(0); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 88 | } |
Ralf S. Engelschall | 15d21c2 | 1999-02-25 14:40:29 +0000 | [diff] [blame] | 89 | return(ssl_set_cert(ssl->cert,x)); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 90 | } |
| 91 | |
Richard Levitte | bc36ee6 | 2001-02-20 08:13:47 +0000 | [diff] [blame] | 92 | #ifndef OPENSSL_NO_STDIO |
Bodo Möller | 303c002 | 1999-05-09 10:12:10 +0000 | [diff] [blame] | 93 | int SSL_use_certificate_file(SSL *ssl, const char *file, int type) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 94 | { |
| 95 | int j; |
| 96 | BIO *in; |
| 97 | int ret=0; |
| 98 | X509 *x=NULL; |
| 99 | |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 100 | in=BIO_new(BIO_s_file_internal()); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 101 | if (in == NULL) |
| 102 | { |
| 103 | SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE,ERR_R_BUF_LIB); |
| 104 | goto end; |
| 105 | } |
| 106 | |
| 107 | if (BIO_read_filename(in,file) <= 0) |
| 108 | { |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 109 | SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE,ERR_R_SYS_LIB); |
| 110 | goto end; |
| 111 | } |
| 112 | if (type == SSL_FILETYPE_ASN1) |
| 113 | { |
| 114 | j=ERR_R_ASN1_LIB; |
| 115 | x=d2i_X509_bio(in,NULL); |
| 116 | } |
| 117 | else if (type == SSL_FILETYPE_PEM) |
| 118 | { |
| 119 | j=ERR_R_PEM_LIB; |
Bodo Möller | 74678cc | 1999-07-21 20:57:16 +0000 | [diff] [blame] | 120 | x=PEM_read_bio_X509(in,NULL,ssl->ctx->default_passwd_callback,ssl->ctx->default_passwd_callback_userdata); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 121 | } |
| 122 | else |
| 123 | { |
| 124 | SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE,SSL_R_BAD_SSL_FILETYPE); |
| 125 | goto end; |
| 126 | } |
| 127 | |
| 128 | if (x == NULL) |
| 129 | { |
| 130 | SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE,j); |
| 131 | goto end; |
| 132 | } |
| 133 | |
| 134 | ret=SSL_use_certificate(ssl,x); |
| 135 | end: |
| 136 | if (x != NULL) X509_free(x); |
| 137 | if (in != NULL) BIO_free(in); |
| 138 | return(ret); |
| 139 | } |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 140 | #endif |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 141 | |
Richard Levitte | 875a644 | 2004-03-15 23:15:26 +0000 | [diff] [blame] | 142 | int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 143 | { |
| 144 | X509 *x; |
| 145 | int ret; |
| 146 | |
| 147 | x=d2i_X509(NULL,&d,(long)len); |
| 148 | if (x == NULL) |
| 149 | { |
| 150 | SSLerr(SSL_F_SSL_USE_CERTIFICATE_ASN1,ERR_R_ASN1_LIB); |
| 151 | return(0); |
| 152 | } |
| 153 | |
| 154 | ret=SSL_use_certificate(ssl,x); |
| 155 | X509_free(x); |
| 156 | return(ret); |
| 157 | } |
| 158 | |
Richard Levitte | bc36ee6 | 2001-02-20 08:13:47 +0000 | [diff] [blame] | 159 | #ifndef OPENSSL_NO_RSA |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 160 | int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 161 | { |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 162 | EVP_PKEY *pkey; |
| 163 | int ret; |
| 164 | |
| 165 | if (rsa == NULL) |
| 166 | { |
| 167 | SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER); |
| 168 | return(0); |
| 169 | } |
Bodo Möller | ca8e5b9 | 1999-05-09 20:12:44 +0000 | [diff] [blame] | 170 | if (!ssl_cert_inst(&ssl->cert)) |
Ralf S. Engelschall | 15d21c2 | 1999-02-25 14:40:29 +0000 | [diff] [blame] | 171 | { |
| 172 | SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY,ERR_R_MALLOC_FAILURE); |
| 173 | return(0); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 174 | } |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 175 | if ((pkey=EVP_PKEY_new()) == NULL) |
| 176 | { |
| 177 | SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY,ERR_R_EVP_LIB); |
| 178 | return(0); |
| 179 | } |
| 180 | |
Bodo Möller | 6ac4e8b | 2001-09-03 13:40:07 +0000 | [diff] [blame] | 181 | RSA_up_ref(rsa); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 182 | EVP_PKEY_assign_RSA(pkey,rsa); |
| 183 | |
Ralf S. Engelschall | 15d21c2 | 1999-02-25 14:40:29 +0000 | [diff] [blame] | 184 | ret=ssl_set_pkey(ssl->cert,pkey); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 185 | EVP_PKEY_free(pkey); |
| 186 | return(ret); |
| 187 | } |
| 188 | #endif |
| 189 | |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 190 | static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 191 | { |
Nils Larsch | 6049399 | 2005-04-07 23:19:17 +0000 | [diff] [blame] | 192 | int i; |
Dr. Stephen Henson | 8e1dc4d | 2012-01-16 18:19:14 +0000 | [diff] [blame] | 193 | /* Special case for DH: check two DH certificate types for a match. |
| 194 | * This means for DH certificates we must set the certificate first. |
| 195 | */ |
| 196 | if (pkey->type == EVP_PKEY_DH) |
| 197 | { |
| 198 | X509 *x; |
| 199 | i = -1; |
| 200 | x = c->pkeys[SSL_PKEY_DH_RSA].x509; |
| 201 | if (x && X509_check_private_key(x, pkey)) |
| 202 | i = SSL_PKEY_DH_RSA; |
| 203 | x = c->pkeys[SSL_PKEY_DH_DSA].x509; |
| 204 | if (i == -1 && x && X509_check_private_key(x, pkey)) |
| 205 | i = SSL_PKEY_DH_DSA; |
| 206 | ERR_clear_error(); |
| 207 | } |
| 208 | else |
| 209 | i=ssl_cert_type(NULL,pkey); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 210 | if (i < 0) |
| 211 | { |
| 212 | SSLerr(SSL_F_SSL_SET_PKEY,SSL_R_UNKNOWN_CERTIFICATE_TYPE); |
| 213 | return(0); |
| 214 | } |
| 215 | |
| 216 | if (c->pkeys[i].x509 != NULL) |
| 217 | { |
Dr. Stephen Henson | a8236c8 | 1999-02-15 21:05:21 +0000 | [diff] [blame] | 218 | EVP_PKEY *pktmp; |
| 219 | pktmp = X509_get_pubkey(c->pkeys[i].x509); |
| 220 | EVP_PKEY_copy_parameters(pktmp,pkey); |
| 221 | EVP_PKEY_free(pktmp); |
Ralf S. Engelschall | dfeab06 | 1998-12-21 11:00:56 +0000 | [diff] [blame] | 222 | ERR_clear_error(); |
| 223 | |
Richard Levitte | bc36ee6 | 2001-02-20 08:13:47 +0000 | [diff] [blame] | 224 | #ifndef OPENSSL_NO_RSA |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 225 | /* Don't check the public/private key, this is mostly |
| 226 | * for smart cards. */ |
| 227 | if ((pkey->type == EVP_PKEY_RSA) && |
Nils Larsch | 6049399 | 2005-04-07 23:19:17 +0000 | [diff] [blame] | 228 | (RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK)) |
| 229 | ; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 230 | else |
| 231 | #endif |
Nils Larsch | 6049399 | 2005-04-07 23:19:17 +0000 | [diff] [blame] | 232 | if (!X509_check_private_key(c->pkeys[i].x509,pkey)) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 233 | { |
Nils Larsch | 6049399 | 2005-04-07 23:19:17 +0000 | [diff] [blame] | 234 | X509_free(c->pkeys[i].x509); |
| 235 | c->pkeys[i].x509 = NULL; |
| 236 | return 0; |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 237 | } |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 238 | } |
| 239 | |
| 240 | if (c->pkeys[i].privatekey != NULL) |
| 241 | EVP_PKEY_free(c->pkeys[i].privatekey); |
| 242 | CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY); |
| 243 | c->pkeys[i].privatekey=pkey; |
| 244 | c->key= &(c->pkeys[i]); |
| 245 | |
| 246 | c->valid=0; |
| 247 | return(1); |
| 248 | } |
| 249 | |
Richard Levitte | bc36ee6 | 2001-02-20 08:13:47 +0000 | [diff] [blame] | 250 | #ifndef OPENSSL_NO_RSA |
| 251 | #ifndef OPENSSL_NO_STDIO |
Bodo Möller | 303c002 | 1999-05-09 10:12:10 +0000 | [diff] [blame] | 252 | int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 253 | { |
| 254 | int j,ret=0; |
| 255 | BIO *in; |
| 256 | RSA *rsa=NULL; |
| 257 | |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 258 | in=BIO_new(BIO_s_file_internal()); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 259 | if (in == NULL) |
| 260 | { |
| 261 | SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE,ERR_R_BUF_LIB); |
| 262 | goto end; |
| 263 | } |
| 264 | |
| 265 | if (BIO_read_filename(in,file) <= 0) |
| 266 | { |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 267 | SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE,ERR_R_SYS_LIB); |
| 268 | goto end; |
| 269 | } |
| 270 | if (type == SSL_FILETYPE_ASN1) |
| 271 | { |
| 272 | j=ERR_R_ASN1_LIB; |
| 273 | rsa=d2i_RSAPrivateKey_bio(in,NULL); |
| 274 | } |
| 275 | else if (type == SSL_FILETYPE_PEM) |
| 276 | { |
| 277 | j=ERR_R_PEM_LIB; |
| 278 | rsa=PEM_read_bio_RSAPrivateKey(in,NULL, |
Bodo Möller | 74678cc | 1999-07-21 20:57:16 +0000 | [diff] [blame] | 279 | ssl->ctx->default_passwd_callback,ssl->ctx->default_passwd_callback_userdata); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 280 | } |
| 281 | else |
| 282 | { |
| 283 | SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE,SSL_R_BAD_SSL_FILETYPE); |
| 284 | goto end; |
| 285 | } |
| 286 | if (rsa == NULL) |
| 287 | { |
| 288 | SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE,j); |
| 289 | goto end; |
| 290 | } |
| 291 | ret=SSL_use_RSAPrivateKey(ssl,rsa); |
| 292 | RSA_free(rsa); |
| 293 | end: |
| 294 | if (in != NULL) BIO_free(in); |
| 295 | return(ret); |
| 296 | } |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 297 | #endif |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 298 | |
Viktor Szakats | 693b71f | 2014-08-08 23:15:59 -0400 | [diff] [blame] | 299 | int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, long len) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 300 | { |
| 301 | int ret; |
Richard Levitte | 5e4ca42 | 2000-11-06 23:16:04 +0000 | [diff] [blame] | 302 | const unsigned char *p; |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 303 | RSA *rsa; |
| 304 | |
| 305 | p=d; |
| 306 | if ((rsa=d2i_RSAPrivateKey(NULL,&p,(long)len)) == NULL) |
| 307 | { |
| 308 | SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1,ERR_R_ASN1_LIB); |
| 309 | return(0); |
| 310 | } |
| 311 | |
| 312 | ret=SSL_use_RSAPrivateKey(ssl,rsa); |
| 313 | RSA_free(rsa); |
| 314 | return(ret); |
| 315 | } |
Richard Levitte | bc36ee6 | 2001-02-20 08:13:47 +0000 | [diff] [blame] | 316 | #endif /* !OPENSSL_NO_RSA */ |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 317 | |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 318 | int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 319 | { |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 320 | int ret; |
| 321 | |
| 322 | if (pkey == NULL) |
| 323 | { |
| 324 | SSLerr(SSL_F_SSL_USE_PRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER); |
| 325 | return(0); |
| 326 | } |
Bodo Möller | ca8e5b9 | 1999-05-09 20:12:44 +0000 | [diff] [blame] | 327 | if (!ssl_cert_inst(&ssl->cert)) |
Ralf S. Engelschall | 15d21c2 | 1999-02-25 14:40:29 +0000 | [diff] [blame] | 328 | { |
| 329 | SSLerr(SSL_F_SSL_USE_PRIVATEKEY,ERR_R_MALLOC_FAILURE); |
| 330 | return(0); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 331 | } |
Ralf S. Engelschall | 15d21c2 | 1999-02-25 14:40:29 +0000 | [diff] [blame] | 332 | ret=ssl_set_pkey(ssl->cert,pkey); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 333 | return(ret); |
| 334 | } |
| 335 | |
Richard Levitte | bc36ee6 | 2001-02-20 08:13:47 +0000 | [diff] [blame] | 336 | #ifndef OPENSSL_NO_STDIO |
Bodo Möller | 303c002 | 1999-05-09 10:12:10 +0000 | [diff] [blame] | 337 | int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 338 | { |
| 339 | int j,ret=0; |
| 340 | BIO *in; |
| 341 | EVP_PKEY *pkey=NULL; |
| 342 | |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 343 | in=BIO_new(BIO_s_file_internal()); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 344 | if (in == NULL) |
| 345 | { |
| 346 | SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,ERR_R_BUF_LIB); |
| 347 | goto end; |
| 348 | } |
| 349 | |
| 350 | if (BIO_read_filename(in,file) <= 0) |
| 351 | { |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 352 | SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,ERR_R_SYS_LIB); |
| 353 | goto end; |
| 354 | } |
| 355 | if (type == SSL_FILETYPE_PEM) |
| 356 | { |
| 357 | j=ERR_R_PEM_LIB; |
| 358 | pkey=PEM_read_bio_PrivateKey(in,NULL, |
Bodo Möller | 74678cc | 1999-07-21 20:57:16 +0000 | [diff] [blame] | 359 | ssl->ctx->default_passwd_callback,ssl->ctx->default_passwd_callback_userdata); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 360 | } |
Nils Larsch | dc0ed30 | 2005-04-08 22:52:42 +0000 | [diff] [blame] | 361 | else if (type == SSL_FILETYPE_ASN1) |
| 362 | { |
| 363 | j = ERR_R_ASN1_LIB; |
| 364 | pkey = d2i_PrivateKey_bio(in,NULL); |
| 365 | } |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 366 | else |
| 367 | { |
| 368 | SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,SSL_R_BAD_SSL_FILETYPE); |
| 369 | goto end; |
| 370 | } |
| 371 | if (pkey == NULL) |
| 372 | { |
| 373 | SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,j); |
| 374 | goto end; |
| 375 | } |
| 376 | ret=SSL_use_PrivateKey(ssl,pkey); |
| 377 | EVP_PKEY_free(pkey); |
| 378 | end: |
| 379 | if (in != NULL) BIO_free(in); |
| 380 | return(ret); |
| 381 | } |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 382 | #endif |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 383 | |
Richard Levitte | 875a644 | 2004-03-15 23:15:26 +0000 | [diff] [blame] | 384 | int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 385 | { |
| 386 | int ret; |
Richard Levitte | 875a644 | 2004-03-15 23:15:26 +0000 | [diff] [blame] | 387 | const unsigned char *p; |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 388 | EVP_PKEY *pkey; |
| 389 | |
| 390 | p=d; |
| 391 | if ((pkey=d2i_PrivateKey(type,NULL,&p,(long)len)) == NULL) |
| 392 | { |
| 393 | SSLerr(SSL_F_SSL_USE_PRIVATEKEY_ASN1,ERR_R_ASN1_LIB); |
| 394 | return(0); |
| 395 | } |
| 396 | |
| 397 | ret=SSL_use_PrivateKey(ssl,pkey); |
| 398 | EVP_PKEY_free(pkey); |
| 399 | return(ret); |
| 400 | } |
| 401 | |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 402 | int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 403 | { |
Dr. Stephen Henson | b362cca | 2013-12-15 13:32:24 +0000 | [diff] [blame] | 404 | int rv; |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 405 | if (x == NULL) |
| 406 | { |
| 407 | SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE,ERR_R_PASSED_NULL_PARAMETER); |
| 408 | return(0); |
| 409 | } |
Dr. Stephen Henson | b362cca | 2013-12-15 13:32:24 +0000 | [diff] [blame] | 410 | rv = ssl_security_cert(NULL, ctx, x, 0, 1); |
| 411 | if (rv != 1) |
| 412 | { |
| 413 | SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, rv); |
| 414 | return 0; |
| 415 | } |
Bodo Möller | ca8e5b9 | 1999-05-09 20:12:44 +0000 | [diff] [blame] | 416 | if (!ssl_cert_inst(&ctx->cert)) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 417 | { |
Ralf S. Engelschall | 15d21c2 | 1999-02-25 14:40:29 +0000 | [diff] [blame] | 418 | SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE,ERR_R_MALLOC_FAILURE); |
| 419 | return(0); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 420 | } |
Bodo Möller | ca8e5b9 | 1999-05-09 20:12:44 +0000 | [diff] [blame] | 421 | return(ssl_set_cert(ctx->cert, x)); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 422 | } |
| 423 | |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 424 | static int ssl_set_cert(CERT *c, X509 *x) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 425 | { |
| 426 | EVP_PKEY *pkey; |
Nils Larsch | 6049399 | 2005-04-07 23:19:17 +0000 | [diff] [blame] | 427 | int i; |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 428 | |
| 429 | pkey=X509_get_pubkey(x); |
| 430 | if (pkey == NULL) |
| 431 | { |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 432 | SSLerr(SSL_F_SSL_SET_CERT,SSL_R_X509_LIB); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 433 | return(0); |
| 434 | } |
| 435 | |
| 436 | i=ssl_cert_type(x,pkey); |
| 437 | if (i < 0) |
| 438 | { |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 439 | SSLerr(SSL_F_SSL_SET_CERT,SSL_R_UNKNOWN_CERTIFICATE_TYPE); |
Dr. Stephen Henson | a8236c8 | 1999-02-15 21:05:21 +0000 | [diff] [blame] | 440 | EVP_PKEY_free(pkey); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 441 | return(0); |
| 442 | } |
| 443 | |
| 444 | if (c->pkeys[i].privatekey != NULL) |
| 445 | { |
Ralf S. Engelschall | dfeab06 | 1998-12-21 11:00:56 +0000 | [diff] [blame] | 446 | EVP_PKEY_copy_parameters(pkey,c->pkeys[i].privatekey); |
| 447 | ERR_clear_error(); |
| 448 | |
Richard Levitte | bc36ee6 | 2001-02-20 08:13:47 +0000 | [diff] [blame] | 449 | #ifndef OPENSSL_NO_RSA |
Ralf S. Engelschall | dfeab06 | 1998-12-21 11:00:56 +0000 | [diff] [blame] | 450 | /* Don't check the public/private key, this is mostly |
| 451 | * for smart cards. */ |
| 452 | if ((c->pkeys[i].privatekey->type == EVP_PKEY_RSA) && |
| 453 | (RSA_flags(c->pkeys[i].privatekey->pkey.rsa) & |
| 454 | RSA_METHOD_FLAG_NO_CHECK)) |
Nils Larsch | 6049399 | 2005-04-07 23:19:17 +0000 | [diff] [blame] | 455 | ; |
Ralf S. Engelschall | dfeab06 | 1998-12-21 11:00:56 +0000 | [diff] [blame] | 456 | else |
Nils Larsch | 6049399 | 2005-04-07 23:19:17 +0000 | [diff] [blame] | 457 | #endif /* OPENSSL_NO_RSA */ |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 458 | if (!X509_check_private_key(x,c->pkeys[i].privatekey)) |
| 459 | { |
Nils Larsch | 6049399 | 2005-04-07 23:19:17 +0000 | [diff] [blame] | 460 | /* don't fail for a cert/key mismatch, just free |
| 461 | * current private key (when switching to a different |
| 462 | * cert & key, first this function should be used, |
| 463 | * then ssl_set_pkey */ |
| 464 | EVP_PKEY_free(c->pkeys[i].privatekey); |
| 465 | c->pkeys[i].privatekey=NULL; |
| 466 | /* clear error queue */ |
| 467 | ERR_clear_error(); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 468 | } |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 469 | } |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 470 | |
Dr. Stephen Henson | a8236c8 | 1999-02-15 21:05:21 +0000 | [diff] [blame] | 471 | EVP_PKEY_free(pkey); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 472 | |
| 473 | if (c->pkeys[i].x509 != NULL) |
| 474 | X509_free(c->pkeys[i].x509); |
| 475 | CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509); |
| 476 | c->pkeys[i].x509=x; |
| 477 | c->key= &(c->pkeys[i]); |
| 478 | |
| 479 | c->valid=0; |
| 480 | return(1); |
| 481 | } |
| 482 | |
Richard Levitte | bc36ee6 | 2001-02-20 08:13:47 +0000 | [diff] [blame] | 483 | #ifndef OPENSSL_NO_STDIO |
Bodo Möller | 303c002 | 1999-05-09 10:12:10 +0000 | [diff] [blame] | 484 | int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 485 | { |
| 486 | int j; |
| 487 | BIO *in; |
| 488 | int ret=0; |
| 489 | X509 *x=NULL; |
| 490 | |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 491 | in=BIO_new(BIO_s_file_internal()); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 492 | if (in == NULL) |
| 493 | { |
| 494 | SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,ERR_R_BUF_LIB); |
| 495 | goto end; |
| 496 | } |
| 497 | |
| 498 | if (BIO_read_filename(in,file) <= 0) |
| 499 | { |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 500 | SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,ERR_R_SYS_LIB); |
| 501 | goto end; |
| 502 | } |
| 503 | if (type == SSL_FILETYPE_ASN1) |
| 504 | { |
| 505 | j=ERR_R_ASN1_LIB; |
| 506 | x=d2i_X509_bio(in,NULL); |
| 507 | } |
| 508 | else if (type == SSL_FILETYPE_PEM) |
| 509 | { |
| 510 | j=ERR_R_PEM_LIB; |
Bodo Möller | 74678cc | 1999-07-21 20:57:16 +0000 | [diff] [blame] | 511 | x=PEM_read_bio_X509(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 512 | } |
| 513 | else |
| 514 | { |
| 515 | SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,SSL_R_BAD_SSL_FILETYPE); |
| 516 | goto end; |
| 517 | } |
| 518 | |
| 519 | if (x == NULL) |
| 520 | { |
| 521 | SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,j); |
| 522 | goto end; |
| 523 | } |
| 524 | |
| 525 | ret=SSL_CTX_use_certificate(ctx,x); |
| 526 | end: |
| 527 | if (x != NULL) X509_free(x); |
| 528 | if (in != NULL) BIO_free(in); |
| 529 | return(ret); |
| 530 | } |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 531 | #endif |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 532 | |
Richard Levitte | 875a644 | 2004-03-15 23:15:26 +0000 | [diff] [blame] | 533 | int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 534 | { |
| 535 | X509 *x; |
| 536 | int ret; |
| 537 | |
| 538 | x=d2i_X509(NULL,&d,(long)len); |
| 539 | if (x == NULL) |
| 540 | { |
| 541 | SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1,ERR_R_ASN1_LIB); |
| 542 | return(0); |
| 543 | } |
| 544 | |
| 545 | ret=SSL_CTX_use_certificate(ctx,x); |
| 546 | X509_free(x); |
| 547 | return(ret); |
| 548 | } |
| 549 | |
Richard Levitte | bc36ee6 | 2001-02-20 08:13:47 +0000 | [diff] [blame] | 550 | #ifndef OPENSSL_NO_RSA |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 551 | int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 552 | { |
| 553 | int ret; |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 554 | EVP_PKEY *pkey; |
| 555 | |
| 556 | if (rsa == NULL) |
| 557 | { |
| 558 | SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER); |
| 559 | return(0); |
| 560 | } |
Bodo Möller | ca8e5b9 | 1999-05-09 20:12:44 +0000 | [diff] [blame] | 561 | if (!ssl_cert_inst(&ctx->cert)) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 562 | { |
Ralf S. Engelschall | 15d21c2 | 1999-02-25 14:40:29 +0000 | [diff] [blame] | 563 | SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY,ERR_R_MALLOC_FAILURE); |
| 564 | return(0); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 565 | } |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 566 | if ((pkey=EVP_PKEY_new()) == NULL) |
| 567 | { |
| 568 | SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY,ERR_R_EVP_LIB); |
| 569 | return(0); |
| 570 | } |
| 571 | |
Bodo Möller | 6ac4e8b | 2001-09-03 13:40:07 +0000 | [diff] [blame] | 572 | RSA_up_ref(rsa); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 573 | EVP_PKEY_assign_RSA(pkey,rsa); |
| 574 | |
Bodo Möller | ca8e5b9 | 1999-05-09 20:12:44 +0000 | [diff] [blame] | 575 | ret=ssl_set_pkey(ctx->cert, pkey); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 576 | EVP_PKEY_free(pkey); |
| 577 | return(ret); |
| 578 | } |
| 579 | |
Richard Levitte | bc36ee6 | 2001-02-20 08:13:47 +0000 | [diff] [blame] | 580 | #ifndef OPENSSL_NO_STDIO |
Bodo Möller | 303c002 | 1999-05-09 10:12:10 +0000 | [diff] [blame] | 581 | int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 582 | { |
| 583 | int j,ret=0; |
| 584 | BIO *in; |
| 585 | RSA *rsa=NULL; |
| 586 | |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 587 | in=BIO_new(BIO_s_file_internal()); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 588 | if (in == NULL) |
| 589 | { |
| 590 | SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE,ERR_R_BUF_LIB); |
| 591 | goto end; |
| 592 | } |
| 593 | |
| 594 | if (BIO_read_filename(in,file) <= 0) |
| 595 | { |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 596 | SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE,ERR_R_SYS_LIB); |
| 597 | goto end; |
| 598 | } |
| 599 | if (type == SSL_FILETYPE_ASN1) |
| 600 | { |
| 601 | j=ERR_R_ASN1_LIB; |
| 602 | rsa=d2i_RSAPrivateKey_bio(in,NULL); |
| 603 | } |
| 604 | else if (type == SSL_FILETYPE_PEM) |
| 605 | { |
| 606 | j=ERR_R_PEM_LIB; |
| 607 | rsa=PEM_read_bio_RSAPrivateKey(in,NULL, |
Bodo Möller | 74678cc | 1999-07-21 20:57:16 +0000 | [diff] [blame] | 608 | ctx->default_passwd_callback,ctx->default_passwd_callback_userdata); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 609 | } |
| 610 | else |
| 611 | { |
| 612 | SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE,SSL_R_BAD_SSL_FILETYPE); |
| 613 | goto end; |
| 614 | } |
| 615 | if (rsa == NULL) |
| 616 | { |
| 617 | SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE,j); |
| 618 | goto end; |
| 619 | } |
| 620 | ret=SSL_CTX_use_RSAPrivateKey(ctx,rsa); |
| 621 | RSA_free(rsa); |
| 622 | end: |
| 623 | if (in != NULL) BIO_free(in); |
| 624 | return(ret); |
| 625 | } |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 626 | #endif |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 627 | |
Richard Levitte | 875a644 | 2004-03-15 23:15:26 +0000 | [diff] [blame] | 628 | int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 629 | { |
| 630 | int ret; |
Richard Levitte | 5e4ca42 | 2000-11-06 23:16:04 +0000 | [diff] [blame] | 631 | const unsigned char *p; |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 632 | RSA *rsa; |
| 633 | |
| 634 | p=d; |
| 635 | if ((rsa=d2i_RSAPrivateKey(NULL,&p,(long)len)) == NULL) |
| 636 | { |
| 637 | SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1,ERR_R_ASN1_LIB); |
| 638 | return(0); |
| 639 | } |
| 640 | |
| 641 | ret=SSL_CTX_use_RSAPrivateKey(ctx,rsa); |
| 642 | RSA_free(rsa); |
| 643 | return(ret); |
| 644 | } |
Richard Levitte | bc36ee6 | 2001-02-20 08:13:47 +0000 | [diff] [blame] | 645 | #endif /* !OPENSSL_NO_RSA */ |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 646 | |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 647 | int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 648 | { |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 649 | if (pkey == NULL) |
| 650 | { |
| 651 | SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER); |
| 652 | return(0); |
| 653 | } |
Bodo Möller | ca8e5b9 | 1999-05-09 20:12:44 +0000 | [diff] [blame] | 654 | if (!ssl_cert_inst(&ctx->cert)) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 655 | { |
Ralf S. Engelschall | 15d21c2 | 1999-02-25 14:40:29 +0000 | [diff] [blame] | 656 | SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY,ERR_R_MALLOC_FAILURE); |
| 657 | return(0); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 658 | } |
Bodo Möller | ca8e5b9 | 1999-05-09 20:12:44 +0000 | [diff] [blame] | 659 | return(ssl_set_pkey(ctx->cert,pkey)); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 660 | } |
| 661 | |
Richard Levitte | bc36ee6 | 2001-02-20 08:13:47 +0000 | [diff] [blame] | 662 | #ifndef OPENSSL_NO_STDIO |
Bodo Möller | 303c002 | 1999-05-09 10:12:10 +0000 | [diff] [blame] | 663 | int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 664 | { |
| 665 | int j,ret=0; |
| 666 | BIO *in; |
| 667 | EVP_PKEY *pkey=NULL; |
| 668 | |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 669 | in=BIO_new(BIO_s_file_internal()); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 670 | if (in == NULL) |
| 671 | { |
| 672 | SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE,ERR_R_BUF_LIB); |
| 673 | goto end; |
| 674 | } |
| 675 | |
| 676 | if (BIO_read_filename(in,file) <= 0) |
| 677 | { |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 678 | SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE,ERR_R_SYS_LIB); |
| 679 | goto end; |
| 680 | } |
| 681 | if (type == SSL_FILETYPE_PEM) |
| 682 | { |
| 683 | j=ERR_R_PEM_LIB; |
| 684 | pkey=PEM_read_bio_PrivateKey(in,NULL, |
Bodo Möller | 74678cc | 1999-07-21 20:57:16 +0000 | [diff] [blame] | 685 | ctx->default_passwd_callback,ctx->default_passwd_callback_userdata); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 686 | } |
Nils Larsch | dc0ed30 | 2005-04-08 22:52:42 +0000 | [diff] [blame] | 687 | else if (type == SSL_FILETYPE_ASN1) |
| 688 | { |
| 689 | j = ERR_R_ASN1_LIB; |
| 690 | pkey = d2i_PrivateKey_bio(in,NULL); |
| 691 | } |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 692 | else |
| 693 | { |
| 694 | SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE,SSL_R_BAD_SSL_FILETYPE); |
| 695 | goto end; |
| 696 | } |
| 697 | if (pkey == NULL) |
| 698 | { |
| 699 | SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE,j); |
| 700 | goto end; |
| 701 | } |
| 702 | ret=SSL_CTX_use_PrivateKey(ctx,pkey); |
| 703 | EVP_PKEY_free(pkey); |
| 704 | end: |
| 705 | if (in != NULL) BIO_free(in); |
| 706 | return(ret); |
| 707 | } |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 708 | #endif |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 709 | |
Richard Levitte | 875a644 | 2004-03-15 23:15:26 +0000 | [diff] [blame] | 710 | int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d, |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 711 | long len) |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 712 | { |
| 713 | int ret; |
Richard Levitte | 875a644 | 2004-03-15 23:15:26 +0000 | [diff] [blame] | 714 | const unsigned char *p; |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 715 | EVP_PKEY *pkey; |
| 716 | |
| 717 | p=d; |
| 718 | if ((pkey=d2i_PrivateKey(type,NULL,&p,(long)len)) == NULL) |
| 719 | { |
| 720 | SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1,ERR_R_ASN1_LIB); |
| 721 | return(0); |
| 722 | } |
| 723 | |
| 724 | ret=SSL_CTX_use_PrivateKey(ctx,pkey); |
| 725 | EVP_PKEY_free(pkey); |
| 726 | return(ret); |
| 727 | } |
| 728 | |
| 729 | |
Richard Levitte | bc36ee6 | 2001-02-20 08:13:47 +0000 | [diff] [blame] | 730 | #ifndef OPENSSL_NO_STDIO |
Bodo Möller | b3ca645 | 1999-05-01 17:43:52 +0000 | [diff] [blame] | 731 | /* Read a file that contains our certificate in "PEM" format, |
| 732 | * possibly followed by a sequence of CA certificates that should be |
| 733 | * sent to the peer in the Certificate message. |
| 734 | */ |
| 735 | int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) |
| 736 | { |
| 737 | BIO *in; |
| 738 | int ret=0; |
| 739 | X509 *x=NULL; |
| 740 | |
Lutz Jänicke | 17a4a4d | 2008-05-26 06:21:13 +0000 | [diff] [blame] | 741 | ERR_clear_error(); /* clear error stack for SSL_CTX_use_certificate() */ |
Lutz Jänicke | c2c2e7a | 2008-05-23 10:37:52 +0000 | [diff] [blame] | 742 | |
Ben Laurie | a9e1c50 | 2012-05-30 10:10:58 +0000 | [diff] [blame] | 743 | in = BIO_new(BIO_s_file_internal()); |
Bodo Möller | b3ca645 | 1999-05-01 17:43:52 +0000 | [diff] [blame] | 744 | if (in == NULL) |
| 745 | { |
| 746 | SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_BUF_LIB); |
| 747 | goto end; |
| 748 | } |
| 749 | |
| 750 | if (BIO_read_filename(in,file) <= 0) |
| 751 | { |
| 752 | SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_SYS_LIB); |
| 753 | goto end; |
| 754 | } |
| 755 | |
Ben Laurie | a9e1c50 | 2012-05-30 10:10:58 +0000 | [diff] [blame] | 756 | x=PEM_read_bio_X509_AUX(in,NULL,ctx->default_passwd_callback, |
| 757 | ctx->default_passwd_callback_userdata); |
Bodo Möller | b3ca645 | 1999-05-01 17:43:52 +0000 | [diff] [blame] | 758 | if (x == NULL) |
| 759 | { |
| 760 | SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_PEM_LIB); |
| 761 | goto end; |
| 762 | } |
| 763 | |
Ben Laurie | a9e1c50 | 2012-05-30 10:10:58 +0000 | [diff] [blame] | 764 | ret = SSL_CTX_use_certificate(ctx, x); |
| 765 | |
Bodo Möller | b3ca645 | 1999-05-01 17:43:52 +0000 | [diff] [blame] | 766 | if (ERR_peek_error() != 0) |
| 767 | ret = 0; /* Key/certificate mismatch doesn't imply ret==0 ... */ |
| 768 | if (ret) |
| 769 | { |
| 770 | /* If we could set up our certificate, now proceed to |
| 771 | * the CA certificates. |
| 772 | */ |
| 773 | X509 *ca; |
| 774 | int r; |
| 775 | unsigned long err; |
Bodo Möller | b3ca645 | 1999-05-01 17:43:52 +0000 | [diff] [blame] | 776 | |
Dr. Stephen Henson | a4339ea | 2014-01-03 22:38:03 +0000 | [diff] [blame] | 777 | SSL_CTX_clear_chain_certs(ctx); |
| 778 | |
Ben Laurie | a9e1c50 | 2012-05-30 10:10:58 +0000 | [diff] [blame] | 779 | while ((ca = PEM_read_bio_X509(in, NULL, |
| 780 | ctx->default_passwd_callback, |
| 781 | ctx->default_passwd_callback_userdata)) |
Bodo Möller | b3ca645 | 1999-05-01 17:43:52 +0000 | [diff] [blame] | 782 | != NULL) |
| 783 | { |
Dr. Stephen Henson | a4339ea | 2014-01-03 22:38:03 +0000 | [diff] [blame] | 784 | r = SSL_CTX_add0_chain_cert(ctx, ca); |
Bodo Möller | b3ca645 | 1999-05-01 17:43:52 +0000 | [diff] [blame] | 785 | if (!r) |
| 786 | { |
| 787 | X509_free(ca); |
| 788 | ret = 0; |
| 789 | goto end; |
| 790 | } |
Ralf S. Engelschall | b1816a0 | 1999-08-05 13:31:42 +0000 | [diff] [blame] | 791 | /* Note that we must not free r if it was successfully |
Bodo Möller | b3ca645 | 1999-05-01 17:43:52 +0000 | [diff] [blame] | 792 | * added to the chain (while we must free the main |
| 793 | * certificate, since its reference count is increased |
| 794 | * by SSL_CTX_use_certificate). */ |
| 795 | } |
| 796 | /* When the while loop ends, it's usually just EOF. */ |
Bodo Möller | 9437fef | 2002-02-28 14:07:37 +0000 | [diff] [blame] | 797 | err = ERR_peek_last_error(); |
Bodo Möller | b3ca645 | 1999-05-01 17:43:52 +0000 | [diff] [blame] | 798 | if (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE) |
Nils Larsch | 48c832b | 2005-04-01 17:50:09 +0000 | [diff] [blame] | 799 | ERR_clear_error(); |
Bodo Möller | b3ca645 | 1999-05-01 17:43:52 +0000 | [diff] [blame] | 800 | else |
| 801 | ret = 0; /* some real error */ |
| 802 | } |
| 803 | |
| 804 | end: |
| 805 | if (x != NULL) X509_free(x); |
| 806 | if (in != NULL) BIO_free(in); |
| 807 | return(ret); |
| 808 | } |
| 809 | #endif |
Ben Laurie | a9e1c50 | 2012-05-30 10:10:58 +0000 | [diff] [blame] | 810 | |
| 811 | #ifndef OPENSSL_NO_TLSEXT |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 812 | static int serverinfo_find_extension(const unsigned char *serverinfo, |
| 813 | size_t serverinfo_length, |
Dr. Stephen Henson | de2a9e3 | 2014-08-14 13:25:50 +0100 | [diff] [blame] | 814 | unsigned int extension_type, |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 815 | const unsigned char **extension_data, |
Dr. Stephen Henson | de2a9e3 | 2014-08-14 13:25:50 +0100 | [diff] [blame] | 816 | size_t *extension_length) |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 817 | { |
| 818 | *extension_data = NULL; |
| 819 | *extension_length = 0; |
| 820 | if (serverinfo == NULL || serverinfo_length == 0) |
| 821 | return 0; |
| 822 | for (;;) |
| 823 | { |
Dr. Stephen Henson | de2a9e3 | 2014-08-14 13:25:50 +0100 | [diff] [blame] | 824 | unsigned int type = 0; |
| 825 | size_t len = 0; |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 826 | |
| 827 | /* end of serverinfo */ |
| 828 | if (serverinfo_length == 0) |
Trevor | 9cd50f7 | 2013-06-13 22:36:45 -0700 | [diff] [blame] | 829 | return -1; /* Extension not found */ |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 830 | |
| 831 | /* read 2-byte type field */ |
| 832 | if (serverinfo_length < 2) |
Trevor | 9cd50f7 | 2013-06-13 22:36:45 -0700 | [diff] [blame] | 833 | return 0; /* Error */ |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 834 | type = (serverinfo[0] << 8) + serverinfo[1]; |
| 835 | serverinfo += 2; |
| 836 | serverinfo_length -= 2; |
| 837 | |
| 838 | /* read 2-byte len field */ |
| 839 | if (serverinfo_length < 2) |
Trevor | 9cd50f7 | 2013-06-13 22:36:45 -0700 | [diff] [blame] | 840 | return 0; /* Error */ |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 841 | len = (serverinfo[0] << 8) + serverinfo[1]; |
| 842 | serverinfo += 2; |
| 843 | serverinfo_length -= 2; |
| 844 | |
| 845 | if (len > serverinfo_length) |
Trevor | 9cd50f7 | 2013-06-13 22:36:45 -0700 | [diff] [blame] | 846 | return 0; /* Error */ |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 847 | |
| 848 | if (type == extension_type) |
| 849 | { |
| 850 | *extension_data = serverinfo; |
| 851 | *extension_length = len; |
Trevor | 9cd50f7 | 2013-06-13 22:36:45 -0700 | [diff] [blame] | 852 | return 1; /* Success */ |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 853 | } |
| 854 | |
| 855 | serverinfo += len; |
| 856 | serverinfo_length -= len; |
| 857 | } |
Trevor | 9cd50f7 | 2013-06-13 22:36:45 -0700 | [diff] [blame] | 858 | return 0; /* Error */ |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 859 | } |
| 860 | |
Dr. Stephen Henson | de2a9e3 | 2014-08-14 13:25:50 +0100 | [diff] [blame] | 861 | static int serverinfo_srv_parse_cb(SSL *s, unsigned int ext_type, |
Ben Laurie | 0a60287 | 2014-02-04 23:16:46 +0000 | [diff] [blame] | 862 | const unsigned char *in, |
Dr. Stephen Henson | de2a9e3 | 2014-08-14 13:25:50 +0100 | [diff] [blame] | 863 | size_t inlen, int *al, |
Ben Laurie | 0a60287 | 2014-02-04 23:16:46 +0000 | [diff] [blame] | 864 | void *arg) |
Trevor | 9cd50f7 | 2013-06-13 22:36:45 -0700 | [diff] [blame] | 865 | { |
Ben Laurie | 0a60287 | 2014-02-04 23:16:46 +0000 | [diff] [blame] | 866 | |
Trevor | 9cd50f7 | 2013-06-13 22:36:45 -0700 | [diff] [blame] | 867 | if (inlen != 0) |
| 868 | { |
| 869 | *al = SSL_AD_DECODE_ERROR; |
| 870 | return 0; |
| 871 | } |
Ben Laurie | 0a60287 | 2014-02-04 23:16:46 +0000 | [diff] [blame] | 872 | |
Trevor | 9cd50f7 | 2013-06-13 22:36:45 -0700 | [diff] [blame] | 873 | return 1; |
| 874 | } |
| 875 | |
Dr. Stephen Henson | de2a9e3 | 2014-08-14 13:25:50 +0100 | [diff] [blame] | 876 | static int serverinfo_srv_add_cb(SSL *s, unsigned int ext_type, |
Dr. Stephen Henson | 0cfefe4 | 2014-08-19 14:02:50 +0100 | [diff] [blame] | 877 | const unsigned char **out, size_t *outlen, |
| 878 | int *al, void *arg) |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 879 | { |
| 880 | const unsigned char *serverinfo = NULL; |
| 881 | size_t serverinfo_length = 0; |
| 882 | |
Trevor | 9cd50f7 | 2013-06-13 22:36:45 -0700 | [diff] [blame] | 883 | /* Is there serverinfo data for the chosen server cert? */ |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 884 | if ((ssl_get_server_cert_serverinfo(s, &serverinfo, |
Ben Laurie | 0a60287 | 2014-02-04 23:16:46 +0000 | [diff] [blame] | 885 | &serverinfo_length)) != 0) |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 886 | { |
| 887 | /* Find the relevant extension from the serverinfo */ |
Trevor | 9cd50f7 | 2013-06-13 22:36:45 -0700 | [diff] [blame] | 888 | int retval = serverinfo_find_extension(serverinfo, serverinfo_length, |
Ben Laurie | 0a60287 | 2014-02-04 23:16:46 +0000 | [diff] [blame] | 889 | ext_type, out, outlen); |
Trevor | 9cd50f7 | 2013-06-13 22:36:45 -0700 | [diff] [blame] | 890 | if (retval == 0) |
| 891 | return 0; /* Error */ |
| 892 | if (retval == -1) |
| 893 | return -1; /* No extension found, don't send extension */ |
| 894 | return 1; /* Send extension */ |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 895 | } |
Trevor | 9cd50f7 | 2013-06-13 22:36:45 -0700 | [diff] [blame] | 896 | return -1; /* No serverinfo data found, don't send extension */ |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 897 | } |
| 898 | |
Trevor | 9cd50f7 | 2013-06-13 22:36:45 -0700 | [diff] [blame] | 899 | /* With a NULL context, this function just checks that the serverinfo data |
| 900 | parses correctly. With a non-NULL context, it registers callbacks for |
| 901 | the included extensions. */ |
| 902 | static int serverinfo_process_buffer(const unsigned char *serverinfo, |
| 903 | size_t serverinfo_length, SSL_CTX *ctx) |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 904 | { |
| 905 | if (serverinfo == NULL || serverinfo_length == 0) |
| 906 | return 0; |
| 907 | for (;;) |
| 908 | { |
Dr. Stephen Henson | de2a9e3 | 2014-08-14 13:25:50 +0100 | [diff] [blame] | 909 | unsigned int ext_type = 0; |
| 910 | size_t len = 0; |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 911 | |
| 912 | /* end of serverinfo */ |
| 913 | if (serverinfo_length == 0) |
| 914 | return 1; |
| 915 | |
| 916 | /* read 2-byte type field */ |
| 917 | if (serverinfo_length < 2) |
| 918 | return 0; |
| 919 | /* FIXME: check for types we understand explicitly? */ |
| 920 | |
| 921 | /* Register callbacks for extensions */ |
| 922 | ext_type = (serverinfo[0] << 8) + serverinfo[1]; |
Dr. Stephen Henson | 8cafe9e | 2014-08-19 13:54:38 +0100 | [diff] [blame] | 923 | if (ctx && !SSL_CTX_add_server_custom_ext(ctx, ext_type, |
Dr. Stephen Henson | 0cfefe4 | 2014-08-19 14:02:50 +0100 | [diff] [blame] | 924 | serverinfo_srv_add_cb, |
| 925 | NULL, NULL, |
| 926 | serverinfo_srv_parse_cb, |
| 927 | NULL)) |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 928 | return 0; |
| 929 | |
| 930 | serverinfo += 2; |
| 931 | serverinfo_length -= 2; |
| 932 | |
| 933 | /* read 2-byte len field */ |
| 934 | if (serverinfo_length < 2) |
| 935 | return 0; |
| 936 | len = (serverinfo[0] << 8) + serverinfo[1]; |
| 937 | serverinfo += 2; |
| 938 | serverinfo_length -= 2; |
| 939 | |
| 940 | if (len > serverinfo_length) |
| 941 | return 0; |
| 942 | |
| 943 | serverinfo += len; |
| 944 | serverinfo_length -= len; |
| 945 | } |
| 946 | } |
| 947 | |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 948 | int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, |
| 949 | size_t serverinfo_length) |
| 950 | { |
| 951 | if (ctx == NULL || serverinfo == NULL || serverinfo_length == 0) |
| 952 | { |
| 953 | SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO,ERR_R_PASSED_NULL_PARAMETER); |
| 954 | return 0; |
| 955 | } |
Trevor | 9cd50f7 | 2013-06-13 22:36:45 -0700 | [diff] [blame] | 956 | if (!serverinfo_process_buffer(serverinfo, serverinfo_length, NULL)) |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 957 | { |
| 958 | SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO,SSL_R_INVALID_SERVERINFO_DATA); |
Trevor Perrin | 0b2bde7 | 2013-07-27 23:10:14 -0700 | [diff] [blame] | 959 | return 0; |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 960 | } |
| 961 | if (!ssl_cert_inst(&ctx->cert)) |
| 962 | { |
| 963 | SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO,ERR_R_MALLOC_FAILURE); |
| 964 | return 0; |
| 965 | } |
| 966 | if (ctx->cert->key == NULL) |
| 967 | { |
| 968 | SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO,ERR_R_INTERNAL_ERROR); |
| 969 | return 0; |
| 970 | } |
| 971 | ctx->cert->key->serverinfo = OPENSSL_realloc(ctx->cert->key->serverinfo, |
Trevor | 5382adb | 2013-06-24 15:59:05 -0700 | [diff] [blame] | 972 | serverinfo_length); |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 973 | if (ctx->cert->key->serverinfo == NULL) |
| 974 | { |
| 975 | SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO,ERR_R_MALLOC_FAILURE); |
| 976 | return 0; |
| 977 | } |
| 978 | memcpy(ctx->cert->key->serverinfo, serverinfo, serverinfo_length); |
| 979 | ctx->cert->key->serverinfo_length = serverinfo_length; |
| 980 | |
| 981 | /* Now that the serverinfo is validated and stored, go ahead and |
| 982 | * register callbacks. */ |
Trevor | 9cd50f7 | 2013-06-13 22:36:45 -0700 | [diff] [blame] | 983 | if (!serverinfo_process_buffer(serverinfo, serverinfo_length, ctx)) |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 984 | { |
| 985 | SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO,SSL_R_INVALID_SERVERINFO_DATA); |
Trevor Perrin | 0b2bde7 | 2013-07-27 23:10:14 -0700 | [diff] [blame] | 986 | return 0; |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 987 | } |
| 988 | return 1; |
| 989 | } |
| 990 | |
Ben Laurie | 7a71af8 | 2012-06-07 13:20:47 +0000 | [diff] [blame] | 991 | #ifndef OPENSSL_NO_STDIO |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 992 | int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) |
| 993 | { |
| 994 | unsigned char *serverinfo = NULL; |
| 995 | size_t serverinfo_length = 0; |
| 996 | unsigned char* extension = 0; |
| 997 | long extension_length = 0; |
| 998 | char* name = NULL; |
| 999 | char* header = NULL; |
Trevor Perrin | c655f40 | 2013-09-13 19:32:55 -0700 | [diff] [blame] | 1000 | char namePrefix[] = "SERVERINFO FOR "; |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 1001 | int ret = 0; |
| 1002 | BIO *bin = NULL; |
| 1003 | size_t num_extensions = 0; |
| 1004 | |
| 1005 | if (ctx == NULL || file == NULL) |
| 1006 | { |
| 1007 | SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE,ERR_R_PASSED_NULL_PARAMETER); |
| 1008 | goto end; |
| 1009 | } |
| 1010 | |
| 1011 | bin = BIO_new(BIO_s_file_internal()); |
| 1012 | if (bin == NULL) |
| 1013 | { |
| 1014 | SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_BUF_LIB); |
| 1015 | goto end; |
| 1016 | } |
| 1017 | if (BIO_read_filename(bin, file) <= 0) |
| 1018 | { |
| 1019 | SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_SYS_LIB); |
| 1020 | goto end; |
| 1021 | } |
| 1022 | |
| 1023 | for (num_extensions=0;; num_extensions++) |
| 1024 | { |
| 1025 | if (PEM_read_bio(bin, &name, &header, &extension, &extension_length) == 0) |
| 1026 | { |
| 1027 | /* There must be at least one extension in this file */ |
| 1028 | if (num_extensions == 0) |
| 1029 | { |
Ben Laurie | 9725bda | 2013-09-24 23:13:22 +0100 | [diff] [blame] | 1030 | SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_NO_PEM_EXTENSIONS); |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 1031 | goto end; |
| 1032 | } |
| 1033 | else /* End of file, we're done */ |
| 1034 | break; |
| 1035 | } |
Trevor Perrin | c655f40 | 2013-09-13 19:32:55 -0700 | [diff] [blame] | 1036 | /* Check that PEM name starts with "BEGIN SERVERINFO FOR " */ |
| 1037 | if (strlen(name) < strlen(namePrefix)) |
| 1038 | { |
Ben Laurie | 9725bda | 2013-09-24 23:13:22 +0100 | [diff] [blame] | 1039 | SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_PEM_NAME_TOO_SHORT); |
Trevor Perrin | c655f40 | 2013-09-13 19:32:55 -0700 | [diff] [blame] | 1040 | goto end; |
| 1041 | } |
| 1042 | if (strncmp(name, namePrefix, strlen(namePrefix)) != 0) |
| 1043 | { |
Ben Laurie | 9725bda | 2013-09-24 23:13:22 +0100 | [diff] [blame] | 1044 | SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_PEM_NAME_BAD_PREFIX); |
Trevor Perrin | c655f40 | 2013-09-13 19:32:55 -0700 | [diff] [blame] | 1045 | goto end; |
| 1046 | } |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 1047 | /* Check that the decoded PEM data is plausible (valid length field) */ |
| 1048 | if (extension_length < 4 || (extension[2] << 8) + extension[3] != extension_length - 4) |
| 1049 | { |
Ben Laurie | 9725bda | 2013-09-24 23:13:22 +0100 | [diff] [blame] | 1050 | SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_BAD_DATA); |
Trevor Perrin | c655f40 | 2013-09-13 19:32:55 -0700 | [diff] [blame] | 1051 | goto end; |
Trevor | a398f82 | 2013-05-12 18:55:27 -0700 | [diff] [blame] | 1052 | } |
| 1053 | /* Append the decoded extension to the serverinfo buffer */ |
| 1054 | serverinfo = OPENSSL_realloc(serverinfo, serverinfo_length + extension_length); |
| 1055 | if (serverinfo == NULL) |
| 1056 | { |
| 1057 | SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_MALLOC_FAILURE); |
| 1058 | goto end; |
| 1059 | } |
| 1060 | memcpy(serverinfo + serverinfo_length, extension, extension_length); |
| 1061 | serverinfo_length += extension_length; |
| 1062 | |
| 1063 | OPENSSL_free(name); name = NULL; |
| 1064 | OPENSSL_free(header); header = NULL; |
| 1065 | OPENSSL_free(extension); extension = NULL; |
| 1066 | } |
| 1067 | |
| 1068 | ret = SSL_CTX_use_serverinfo(ctx, serverinfo, serverinfo_length); |
| 1069 | end: |
| 1070 | /* SSL_CTX_use_serverinfo makes a local copy of the serverinfo. */ |
| 1071 | OPENSSL_free(name); |
| 1072 | OPENSSL_free(header); |
| 1073 | OPENSSL_free(extension); |
| 1074 | OPENSSL_free(serverinfo); |
| 1075 | if (bin != NULL) |
| 1076 | BIO_free(bin); |
| 1077 | return ret; |
| 1078 | } |
Ben Laurie | 7a71af8 | 2012-06-07 13:20:47 +0000 | [diff] [blame] | 1079 | #endif /* OPENSSL_NO_STDIO */ |
Ben Laurie | a9e1c50 | 2012-05-30 10:10:58 +0000 | [diff] [blame] | 1080 | #endif /* OPENSSL_NO_TLSEXT */ |