Add SSL_get[01]_peer_certificate()
authorTodd Short <tshort@akamai.com>
Thu, 11 Apr 2019 14:47:13 +0000 (10:47 -0400)
committerRichard Levitte <levitte@openssl.org>
Thu, 16 Jul 2020 07:08:21 +0000 (09:08 +0200)
Deprecate SSL_get_peer_certificte() and replace with
SSL_get1_peer_certificate().
Add SSL_get0_peer_certificate.

Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/8730)

14 files changed:
apps/lib/s_cb.c
apps/s_client.c
apps/s_server.c
doc/man3/SSL_get_peer_certificate.pod
include/openssl/ssl.h
ssl/ssl_lib.c
ssl/statem/statem_clnt.c
ssl/statem/statem_lib.c
test/handshake_helper.c
test/ossl_shim/ossl_shim.cc
test/sslapitest.c
test/ssltest_old.c
util/libssl.num
util/other.syms

index 5bddde5b0351d610aa7c93ca9d8ba54ac156b20c..de72bde9edb1e39a207fddd40eb0e2116059697e 100644 (file)
@@ -1227,7 +1227,7 @@ void print_ssl_summary(SSL *s)
     c = SSL_get_current_cipher(s);
     BIO_printf(bio_err, "Ciphersuite: %s\n", SSL_CIPHER_get_name(c));
     do_print_sigalgs(bio_err, s, 0);
-    peer = SSL_get_peer_certificate(s);
+    peer = SSL_get0_peer_certificate(s);
     if (peer != NULL) {
         int nid;
 
@@ -1243,7 +1243,6 @@ void print_ssl_summary(SSL *s)
     } else {
         BIO_puts(bio_err, "No peer certificate\n");
     }
-    X509_free(peer);
 #ifndef OPENSSL_NO_EC
     ssl_print_point_formats(bio_err, s);
     if (SSL_is_server(s))
index 5a5a40c9275155b5e66128ac9df2f594346fede0..91b21003fb218466e7c1973d8ea1ac93faf02097 100644 (file)
@@ -3241,7 +3241,7 @@ static void print_stuff(BIO *bio, SSL *s, int full)
         }
 
         BIO_printf(bio, "---\n");
-        peer = SSL_get_peer_certificate(s);
+        peer = SSL_get0_peer_certificate(s);
         if (peer != NULL) {
             BIO_printf(bio, "Server certificate\n");
 
@@ -3421,7 +3421,6 @@ static void print_stuff(BIO *bio, SSL *s, int full)
         OPENSSL_free(exportedkeymat);
     }
     BIO_printf(bio, "---\n");
-    X509_free(peer);
     /* flush, or debugging output gets mixed with http response */
     (void)BIO_flush(bio);
 }
index 9995953526d51c0fa4e04f33ba453df6cfa2fccd..15d479ce0e857e24d3c6c75ee698d01067f94c95 100644 (file)
@@ -2939,12 +2939,11 @@ static void print_connection_info(SSL *con)
 
     PEM_write_bio_SSL_SESSION(bio_s_out, SSL_get_session(con));
 
-    peer = SSL_get_peer_certificate(con);
+    peer = SSL_get0_peer_certificate(con);
     if (peer != NULL) {
         BIO_printf(bio_s_out, "Client certificate\n");
         PEM_write_bio_X509(bio_s_out, peer);
         dump_cert_text(bio_s_out, peer);
-        X509_free(peer);
         peer = NULL;
     }
 
@@ -3265,12 +3264,11 @@ static int www_body(int s, int stype, int prot, unsigned char *context)
             BIO_printf(io, "---\n");
             print_stats(io, SSL_get_SSL_CTX(con));
             BIO_printf(io, "---\n");
-            peer = SSL_get_peer_certificate(con);
+            peer = SSL_get0_peer_certificate(con);
             if (peer != NULL) {
                 BIO_printf(io, "Client certificate\n");
                 X509_print(io, peer);
                 PEM_write_bio_X509(io, peer);
-                X509_free(peer);
                 peer = NULL;
             } else {
                 BIO_puts(io, "no client certificate available\n");
index e21e3e4fd4fe0c4eeb571c604d7ea35a4fdd194a..b695edc689fa8e2e15573e5da60c632312db752d 100644 (file)
@@ -2,17 +2,21 @@
 
 =head1 NAME
 
-SSL_get_peer_certificate - get the X509 certificate of the peer
+SSL_get_peer_certificate,
+SSL_get0_peer_certificate,
+SSL_get1_peer_certificate - get the X509 certificate of the peer
 
 =head1 SYNOPSIS
 
  #include <openssl/ssl.h>
 
  X509 *SSL_get_peer_certificate(const SSL *ssl);
+ X509 *SSL_get0_peer_certificate(const SSL *ssl);
+ X509 *SSL_get1_peer_certificate(const SSL *ssl);
 
 =head1 DESCRIPTION
 
-SSL_get_peer_certificate() returns a pointer to the X509 certificate the
+These functions return a pointer to the X509 certificate the
 peer presented. If the peer did not present a certificate, NULL is returned.
 
 =head1 NOTES
@@ -27,9 +31,15 @@ That a certificate is returned does not indicate information about the
 verification state, use L<SSL_get_verify_result(3)>
 to check the verification state.
 
-The reference count of the X509 object is incremented by one, so that it
-will not be destroyed when the session containing the peer certificate is
-freed. The X509 object must be explicitly freed using X509_free().
+The reference count of the X509 object returned by SSL_get1_peer_certificate()
+is incremented by one, so that it will not be destroyed when the session
+containing the peer certificate is freed. The X509 object must be explicitly
+freed using X509_free().
+
+The reference count of the X509 object returned by SSL_get0_peer_certificate()
+is not incremented, and must not be freed.
+
+SSL_get_peer_certificate() is an alias of SSL_get1_peer_certificate().
 
 =head1 RETURN VALUES
 
@@ -52,9 +62,14 @@ The return value points to the certificate presented by the peer.
 L<ssl(7)>, L<SSL_get_verify_result(3)>,
 L<SSL_CTX_set_verify(3)>
 
+=head1 HISTORY
+
+SSL_get0_peer_certificate() and SSL_get1_peer_certificate() were added in 3.0.0.
+SSL_get_peer_certificate() was deprecated in 3.0.0.
+
 =head1 COPYRIGHT
 
-Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the Apache License 2.0 (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 8d96f0d85a82e98620829c586d78fd64d2863361..53664229c27d918e74f385e73385f497e0f19b97 100644 (file)
@@ -1706,7 +1706,12 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
                              long length);
 
 # ifdef OPENSSL_X509_H
-__owur X509 *SSL_get_peer_certificate(const SSL *s);
+__owur X509 *SSL_get0_peer_certificate(const SSL *s);
+__owur X509 *SSL_get1_peer_certificate(const SSL *s);
+/* Deprecated in 3.0.0 */
+#  ifndef OPENSSL_NO_DEPRECATED_3_0
+#   define SSL_get_peer_certificate SSL_get1_peer_certifiate
+#  endif
 # endif
 
 __owur STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s);
index c3174a7c91683f14c568b06d6b3d111e0a2c75eb..243c0ed7c9bf16ed07a09b00ec2729d4d865bccf 100644 (file)
@@ -1524,23 +1524,24 @@ int SSL_has_pending(const SSL *s)
     return RECORD_LAYER_read_pending(&s->rlayer);
 }
 
-X509 *SSL_get_peer_certificate(const SSL *s)
+X509 *SSL_get1_peer_certificate(const SSL *s)
 {
-    X509 *r;
+    X509 *r = SSL_get0_peer_certificate(s);
 
-    if ((s == NULL) || (s->session == NULL))
-        r = NULL;
-    else
-        r = s->session->peer;
-
-    if (r == NULL)
-        return r;
-
-    X509_up_ref(r);
+    if (r != NULL)
+        X509_up_ref(r);
 
     return r;
 }
 
+X509 *SSL_get0_peer_certificate(const SSL *s)
+{
+    if ((s == NULL) || (s->session == NULL))
+        return NULL;
+    else
+        return s->session->peer;
+}
+
 STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s)
 {
     STACK_OF(X509) *r;
index 7189940a62c49d5b2e18534268cb1657d7b6e436..9bee9cb3af31f6a11de3eb771bd66995a3a9b120 100644 (file)
@@ -2551,7 +2551,7 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt)
      * after the CertificateVerify message has been received. This is because
      * in TLSv1.3 the CertificateRequest arrives before the Certificate message
      * but in TLSv1.2 it is the other way around. We want to make sure that
-     * SSL_get_peer_certificate() returns something sensible in
+     * SSL_get1_peer_certificate() returns something sensible in
      * client_cert_cb.
      */
     if (SSL_IS_TLS13(s) && s->post_handshake_auth != SSL_PHA_REQUESTED)
index 36cdc1be58d4352399406038128bf0e0c30a8015..de8212747fc461a03affda0794012af92c6e5609 100644 (file)
@@ -537,7 +537,7 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
      * certificate after the CertVerify instead of when we get the
      * CertificateRequest. This is because in TLSv1.3 the CertificateRequest
      * comes *before* the Certificate message. In TLSv1.2 it comes after. We
-     * want to make sure that SSL_get_peer_certificate() will return the actual
+     * want to make sure that SSL_get1_peer_certificate() will return the actual
      * server certificate from the client_cert_cb callback.
      */
     if (!s->server && SSL_IS_TLS13(s) && s->s3.tmp.cert_req == 1)
index 2dfded5c11983bafe3fa4fd6466ad8faf29c6de9..bc6762d475c81c395734f3127ba2bdcb1d66833a 100644 (file)
@@ -1285,14 +1285,10 @@ static int pkey_type(EVP_PKEY *pkey)
 
 static int peer_pkey_type(SSL *s)
 {
-    X509 *x = SSL_get_peer_certificate(s);
+    X509 *x = SSL_get0_peer_certificate(s);
 
-    if (x != NULL) {
-        int nid = pkey_type(X509_get0_pubkey(x));
-
-        X509_free(x);
-        return nid;
-    }
+    if (x != NULL)
+        return pkey_type(X509_get0_pubkey(x));
     return NID_undef;
 }
 
index 0184778d4f88e0abbfa84edc7eac73b0b25dd3f8..d4d7cf1454ef9160d1bc788e1d10caa64db0e78e 100644 (file)
@@ -894,7 +894,7 @@ static bool CheckHandshakeProperties(SSL *ssl, bool is_resume) {
       return false;
     }
   } else if (!config->is_server || config->require_any_client_certificate) {
-    if (SSL_get_peer_certificate(ssl) == nullptr) {
+    if (SSL_get0_peer_certificate(ssl) == nullptr) {
       fprintf(stderr, "Received no peer certificate but expected one.\n");
       return false;
     }
index afc4ea8d40dd909d77df7d5740b927a9d7dd7937..1a91f96fb992e4af488016ca8af54902b6c96803 100644 (file)
@@ -7623,15 +7623,13 @@ static int test_cert_cb(int tst)
 
 static int client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
 {
-    X509 *xcert, *peer;
+    X509 *xcert;
     EVP_PKEY *privpkey;
     BIO *in = NULL;
 
-    /* Check that SSL_get_peer_certificate() returns something sensible */
-    peer = SSL_get_peer_certificate(ssl);
-    if (!TEST_ptr(peer))
+    /* Check that SSL_get0_peer_certificate() returns something sensible */
+    if (!TEST_ptr(SSL_get0_peer_certificate(ssl)))
         return 0;
-    X509_free(peer);
 
     in = BIO_new_file(cert, "r");
     if (!TEST_ptr(in))
index d45b2786d31bfc55790dfcd6095bdf73333a95d3..4f340fc2e0dca9c8c2173a3c6057a4fdd2dae085 100644 (file)
@@ -781,7 +781,7 @@ static void print_details(SSL *c_ssl, const char *prefix)
                prefix,
                SSL_get_version(c_ssl),
                SSL_CIPHER_get_version(ciph), SSL_CIPHER_get_name(ciph));
-    cert = SSL_get_peer_certificate(c_ssl);
+    cert = SSL_get0_peer_certificate(c_ssl);
     if (cert != NULL) {
         EVP_PKEY* pubkey = X509_get0_pubkey(cert);
 
@@ -789,7 +789,6 @@ static void print_details(SSL *c_ssl, const char *prefix)
             BIO_puts(bio_stdout, ", ");
             print_key_details(bio_stdout, pubkey);
         }
-        X509_free(cert);
     }
     if (SSL_get_peer_tmp_key(c_ssl, &pkey)) {
         BIO_puts(bio_stdout, ", temp key: ");
index d638088ddee8a68695438487fa94b83008886d05..637e088704e7ec2983da886ad29f69be3d1002fc 100644 (file)
@@ -79,7 +79,7 @@ SSL_SESSION_print                       79    3_0_0   EXIST::FUNCTION:
 SSL_get_client_ciphers                  80     3_0_0   EXIST::FUNCTION:
 SSL_get_srtp_profiles                   81     3_0_0   EXIST::FUNCTION:SRTP
 SSL_use_certificate_ASN1                82     3_0_0   EXIST::FUNCTION:
-SSL_get_peer_certificate                83     3_0_0   EXIST::FUNCTION:
+SSL_get_peer_certificate                83     3_0_0   NOEXIST::FUNCTION:
 DTLSv1_2_server_method                  84     3_0_0   EXIST::FUNCTION:DEPRECATEDIN_1_1_0,DTLS1_2_METHOD
 SSL_set_cert_cb                         85     3_0_0   EXIST::FUNCTION:
 SSL_CTX_set_cookie_verify_cb            86     3_0_0   EXIST::FUNCTION:
@@ -514,3 +514,5 @@ SSL_CTX_load_verify_store               ?   3_0_0   EXIST::FUNCTION:
 SSL_CTX_set_tlsext_ticket_key_evp_cb    ?      3_0_0   EXIST::FUNCTION:
 SSL_CTX_new_with_libctx                 ?      3_0_0   EXIST::FUNCTION:
 SSL_new_session_ticket                  ?      3_0_0   EXIST::FUNCTION:
+SSL_get0_peer_certificate               ?      3_0_0   EXIST::FUNCTION:
+SSL_get1_peer_certificate               ?      3_0_0   EXIST::FUNCTION:
index ab60424a8fef082b5b9e3f489977ae5b7835c2d1..351cffa93328580f0ac9f6efe47626ba07c7bf47 100644 (file)
@@ -505,6 +505,7 @@ SSL_get_max_cert_list                   define
 SSL_get_max_proto_version               define
 SSL_get_min_proto_version               define
 SSL_get_mode                            define
+SSL_get_peer_certificate                define deprecated 3.0.0
 SSL_get_peer_signature_nid              define
 SSL_get_peer_tmp_key                    define
 SSL_get_secure_renegotiation_support    define