Add SSL_use_certificate_chain_file function
authorDr. Stephen Henson <steve@openssl.org>
Thu, 7 May 2015 13:59:08 +0000 (14:59 +0100)
committerDr. Stephen Henson <steve@openssl.org>
Fri, 8 May 2015 17:43:44 +0000 (18:43 +0100)
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>
doc/ssl/SSL_CTX_use_certificate.pod
include/openssl/ssl.h
ssl/ssl_conf.c
ssl/ssl_err.c
ssl/ssl_rsa.c
util/ssleay.num

index 80321b8..6514d01 100644 (file)
@@ -16,6 +16,7 @@ SSL_CTX_use_certificate, SSL_CTX_use_certificate_ASN1, SSL_CTX_use_certificate_f
  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 @@ SSL_CTX_use_certificate_chain_file() loads a certificate chain from
 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
index eb67cb0..43c6801 100644 (file)
@@ -1446,6 +1446,7 @@ __owur int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
 __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 @@ void ERR_load_SSL_strings(void);
 # 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
index 881c351..59516a5 100644 (file)
@@ -344,7 +344,7 @@ static int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value)
         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) {
index 5c40b49..3396a50 100644 (file)
@@ -232,8 +232,7 @@ static ERR_STRING_DATA SSL_str_functs[] = {
     {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"},
index 305b185..31ce9bd 100644 (file)
@@ -641,7 +641,7 @@ int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx,
  * 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 @@ int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
 
     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 SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
         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 @@ int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
                                        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 @@ int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
     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
index f5f85ab..ee82ef2 100755 (executable)
@@ -395,3 +395,4 @@ SSL_SESSION_get_ticket_lifetime_hint    429 EXIST::FUNCTION:
 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