Add SSL_use_certificate_chain_file function

Add SSL_use_certiicate_chain file functions: this is works the same
way as SSL_CTX_use_certificate_chain_file but for an SSL structure.

Update SSL_CONF code to use the new function.
Update docs.
Update ordinals.

Reviewed-by: Rich Salz <rsalz@openssl.org>
diff --git a/doc/ssl/SSL_CTX_use_certificate.pod b/doc/ssl/SSL_CTX_use_certificate.pod
index 80321b8..6514d01 100644
--- a/doc/ssl/SSL_CTX_use_certificate.pod
+++ b/doc/ssl/SSL_CTX_use_certificate.pod
@@ -16,6 +16,7 @@
  int SSL_use_certificate_file(SSL *ssl, const char *file, int type);
 
  int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file);
+ int SSL_use_certificate_chain_file(SSL *ssl, const char *file);
 
  int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
  int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, unsigned char *d,
@@ -70,8 +71,8 @@
 B<file> into B<ctx>. The certificates must be in PEM format and must
 be sorted starting with the subject's certificate (actual client or server
 certificate), followed by intermediate CA certificates if applicable, and
-ending at the highest level (root) CA.
-There is no corresponding function working on a single SSL object.
+ending at the highest level (root) CA. SSL_use_certificate_chain_file() is
+similar except it loads the cerificate chain into B<ssl>.
 
 SSL_CTX_use_PrivateKey() adds B<pkey> as private key to B<ctx>.
 SSL_CTX_use_RSAPrivateKey() adds the private key B<rsa> of type RSA
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index eb67cb0..43c6801 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -1446,6 +1446,7 @@
 __owur int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
 /* PEM type */
 __owur int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file);
+__owur int SSL_use_certificate_chain_file(SSL *ssl, const char *file);
 __owur STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file);
 __owur int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs,
                                         const char *file);
@@ -2069,7 +2070,7 @@
 # define SSL_F_SSL_CTX_SET_TRUST                          229
 # define SSL_F_SSL_CTX_USE_CERTIFICATE                    171
 # define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1               172
-# define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE         220
+# define SSL_F_USE_CERTIFICATE_CHAIN_FILE                 220
 # define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE               173
 # define SSL_F_SSL_CTX_USE_PRIVATEKEY                     174
 # define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1                175
diff --git a/ssl/ssl_conf.c b/ssl/ssl_conf.c
index 881c351..59516a5 100644
--- a/ssl/ssl_conf.c
+++ b/ssl/ssl_conf.c
@@ -344,7 +344,7 @@
         c = cctx->ctx->cert;
     }
     if (cctx->ssl) {
-        rv = SSL_use_certificate_file(cctx->ssl, value, SSL_FILETYPE_PEM);
+        rv = SSL_use_certificate_chain_file(cctx->ssl, value);
         c = cctx->ssl->cert;
     }
     if (rv > 0 && c && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) {
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index 5c40b49..3396a50 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -232,8 +232,7 @@
     {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE), "SSL_CTX_use_certificate"},
     {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1),
      "SSL_CTX_use_certificate_ASN1"},
-    {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE),
-     "SSL_CTX_use_certificate_chain_file"},
+    {ERR_FUNC(SSL_F_USE_CERTIFICATE_CHAIN_FILE), "use_certificate_chain_file"},
     {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE),
      "SSL_CTX_use_certificate_file"},
     {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY), "SSL_CTX_use_PrivateKey"},
diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c
index 305b185..31ce9bd 100644
--- a/ssl/ssl_rsa.c
+++ b/ssl/ssl_rsa.c
@@ -641,7 +641,7 @@
  * followed by a sequence of CA certificates that should be sent to the peer
  * in the Certificate message.
  */
-int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
+static int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file)
 {
     BIO *in;
     int ret = 0;
@@ -652,23 +652,26 @@
 
     in = BIO_new(BIO_s_file_internal());
     if (in == NULL) {
-        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB);
+        SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB);
         goto end;
     }
 
     if (BIO_read_filename(in, file) <= 0) {
-        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_SYS_LIB);
+        SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_SYS_LIB);
         goto end;
     }
 
     x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback,
                               ctx->default_passwd_callback_userdata);
     if (x == NULL) {
-        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
+        SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
         goto end;
     }
 
-    ret = SSL_CTX_use_certificate(ctx, x);
+    if (ctx)
+        ret = SSL_CTX_use_certificate(ctx, x);
+    else
+        ret = SSL_use_certificate(ssl, x);
 
     if (ERR_peek_error() != 0)
         ret = 0;                /* Key/certificate mismatch doesn't imply
@@ -682,7 +685,12 @@
         int r;
         unsigned long err;
 
-        if (!SSL_CTX_clear_chain_certs(ctx)) {
+        if (ctx)
+            r = SSL_CTX_clear_chain_certs(ctx);
+        else
+            r = SSL_clear_chain_certs(ssl);
+
+        if (r == 0) {
             ret = 0;
             goto end;
         }
@@ -691,17 +699,20 @@
                                        ctx->default_passwd_callback,
                                        ctx->default_passwd_callback_userdata))
                != NULL) {
-            r = SSL_CTX_add0_chain_cert(ctx, ca);
+            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).
+             */
             if (!r) {
                 X509_free(ca);
                 ret = 0;
                 goto end;
             }
-            /*
-             * Note that we must not free r 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).
-             */
         }
         /* When the while loop ends, it's usually just EOF. */
         err = ERR_peek_last_error();
@@ -717,6 +728,16 @@
     BIO_free(in);
     return (ret);
 }
+
+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);
+}
 #endif
 
 #ifndef OPENSSL_NO_TLSEXT
diff --git a/util/ssleay.num b/util/ssleay.num
index f5f85ab..ee82ef2 100755
--- a/util/ssleay.num
+++ b/util/ssleay.num
@@ -395,3 +395,4 @@
 SSL_set_rbio                            430	EXIST::FUNCTION:
 SSL_CIPHER_get_digest_nid               431	EXIST::FUNCTION:
 SSL_CIPHER_get_cipher_nid               432	EXIST::FUNCTION:
+SSL_use_certificate_chain_file          433	EXIST::FUNCTION:STDIO